I have to create an application which will detect a non ios device over bluetooth which supports BTLE 4.0.
I have following doubts:
Is it possible to transfer images from iphone app to non ios device using BTLE 4.0
I have searched some tutorial which talks about Central and peripheral. What i understand is in this case iphone app will be peripheral and non ios device will be central? m i right
Will this code will be able to fulfil all my requirements
Yes, an image can be converted to data and data can be sent via bluetooth. To convert a UIImage to NSData you have to decide on what format you want it. You can use UIImageJPEGRepresentation
or
UIImagePNGRepresentation.
Either one will convert a UIImage into NSData.
No you are wrong. The iOS Device has a Central Manager (CBCentralManager) which find other devices (CBPeripheral). Those other devices have many services (CBService) and each service can have many characteristic (CBCharacteristic) which you connect to. Once the connection is created you can send (write) or receive (read) data.
The code looks pretty good. But the main point of SENDING data doesn't seem to be there. You can send to a Bluetooth peripheral from iOS using a WRITE command - which will automatically be split up in to small packets. The size is limited to 64K and can take around a second per kilobyte - so it is pretty slow. Use the function [peripheral writeValue:data forCharacteristic: characterstic type:CBCharacteristicWriteWithResponse]; (you have to keep a reference to the peripheral and the characterstic).
Related
Is it possible to send data from any computer the supports BLE (Windows or Mac) to an iOS app's CBCentralManager?
The data I want to send is purely text based. I'm searching for it but I am not being able to find if it is possible or a tutorial of how to do it.
Any help would be greatly appreciated.
Yes, normally you can do that. What you have to do is:
From the peripheral device (transmitter), advertise an CBService
(iOS) with a CBCharacteristic that support write value.
From the receiver, you create a CBCentralManager to search for the service created by the transmitter, then discover the right CBCharacteristic. Once the CBCharacteristic discovered, you can try to write value to that characteristic.
The processus look simple, but you have to do step by step on the receiver's side:
first, look for device
if device found, try to connect
then once connected to that device, try to discover the service
then once the service discovered, try to discover the characteristic
then once the characteristic is discovered, try to send
then you will receive the result of sending (ok or failed)
Take a look at my project in github, it's not complete but it show you how to exchange data between 2 BLE devices. The application is for iOS, but I'm pretty sure that you have the same code in Mac OS. I don't know how it works on PC.
I'm Working on iOS Application(Objective-C) for Bluetooth watch which using BLE(CoreBluetooth), and my watch is having GATT Bluetooth Profile, iOS application minimum support is from iOS7.
I wants to know How can we do data transfer between iOS device and external device using Core Bluetooth framework.
Actually I'm working on the Firmware upgrade section of my Bluetooth watch,
My iOS application will get Firmware code (binary data) from web service whenever any update received and then it will send data to Bluetooth watch.
I have searched and got one Apple Sample code:
BTLE_Transfer: https://developer.apple.com/Library/ios/samplecode/BTLE_Transfer/Introduction/Intro.html
I guess sample code was not useful in my case as its having Central and Peripheral both code and transferring data between two iOS device.
is there any other way apart from this sample code for BLE data transfer? or it's possible with this sample code only?(if yes how?)
UPDATED:
My device have 1 service which have 2 characteristic one for read and one for write.
According to my workflow using write charateristic:
Using WRITECHARACTERISTIC I'm sending data of firmware code in chunks
[MYDEVICEINSTANCE writeValue:NSDATACHUNK
forCharacteristic:WRITECHARACTERISTIC
type:CBCharacteristicWriteWithResponse];
and in delegate method "didWriteValueForCharacteristic" method I'm notifying read characteristic as below
[MYDEVICEINSTANCE setNotifyValue:TRUE
forCharacteristic:READCHARACTERISTIC];
which calls "didUpdateNotificationStateForCharacteristic" delegate method inside that I'm checking if READCHARACTERISTIC isNotifying or not then I call
[MYDEVICEINSTANCE readValueForCharacteristic:READCHARACTERISTIC];
which call delegate method "didUpdateValueForCharacteristic" and I'm reading response using READCHARACTERISTIC.value
My query:
I wants to confirm MTU maximum limit allowed by Apple for External device communication from iOS application, which I'm starting in step-1 by sending NSDATACHUNK to BLE Watch from iOS app using writeValue
I have tested that I can send NSDATACHUNK of MTU=255 size and BLE watch is receiving same successfully.
I have found in "Apple Sample code: BTLE_Transfer" they are using MTU=20 but, I guess that sample code is for iOS device to iOS device communication (Please, correct me if I'm wrong)
So, If I use MTU=250 in my iOS application for BLE communication is there any chance that apple will reject my Application?
Or is there any one that can say what is the maximum limit allowed by Apple for MTU?
Every suggestion are appreciated,
Thanks in advance
You can use whatever MTU size you want (up to 512).
The value that the connection will use is always the minimum between yours and theirs.
So, if for example they want to use MTU equal to, let's say, 50, then if your MTU is lower than 50, that one will be used; otherwise, whichever value you select above 50 is meaningless, as 50 gets picked.
After connect your device yo your app you should have to write a "characteristic" with:
[YOURDEVICEINSTANCE writeValue:NSDATAVALUE forCharacteristic:YOURCHARACTESITIC type:CBCharacteristicWriteWithResponse];
We spent a lot of time working with my custom BLE device and my conclusion was:
The connection is asymmetric. (you will spent 5ms to transmit from your BLE device to your app and 20ms from your app to your BLE device)
On an iOS device, the available mtu is 20. It means that you can send 20 bytes of data every time when you set it up as BLE peripheral. If you want to communicate for more than 20 bytes, you have to handle that yourself, referencing the APPLE Central Peripheral sample code
In your case, the problem is not the mtu of iOS device but your external BLE device, because your BLE device is the peripheral device. Since your BLE device is capable of transmitting a large amount of data - 255 bytes, it will be fine to have that mtu.
The maximum MTU is negotiated between the participating devices on a low level. CoreBluetooth makes this value available via CBPeripheral's maximumWriteValueLength(for: …).
That said, unless you exactly know the behavior of your BLE peripheral, I'm afraid you can't rely on this value. There are devices out there which claim to support the BLE 5.0 specification with QUEUED WRITES – which would lead to pretty high MTUs, such as 512. They do NOT implement it though, thus packages larger than their native MTU will get silently truncated and as of iOS 14, iOS will not detect this!
I am building an app that connects an iOS device to a smartwatch through bluetooth which returns blood pressure, heart rate, etc.
Once I establish a connection with the watch from an iOS device (using the CoreBluetooth Framework), I should be able to complete the handshake with the watch by sending 7 different byte arrays to the watch in succession for which the watch responds back by sending the corresponding byte data.
For example, the first byte array would contain a command to retrieve firmware version of the watch and the watch responds back with its version and so on. The problem is I'm not able to figure out how to send a byte array to the watch once the bluetooth connection is made and by the way, the watch is BLE 4.0 device.
I built the same app in android where once a bluetooth connection was made, a bluetooth socket was registered and I got input stream and output stream from this socket.
By using these, I was able to send and retrieve byte data to and from the watch.
Is there anyway to achieve the same in iOS?
Thanks for any help in advance!
I'm trying to learn more about by this sample provided by Apple.
This sample can send text from an iOS device to another one.
There is a method called:
-(BOOL)updateValue:(NSData *)value forCharacteristic:(CBMutableCharacteristic *)characteristic onSubscribedCentrals:(NSArray *)centrals;
When this sample send text by this method, it will return a BOOL to let you know succes or not.
It's easy and clear.
But I have doubt about :
Is this provide by BLE?
Or it's because of CoreBluetooth API?
In other words , If I receive data from other BLE device(not iOS device).
Could that device know that I've received data?
In BLE, when your central device (here iOS device, assumed to be master, and also the client) wants to send data to a peripheral device (assumed to be slave and the server), it has several options to do it:
(1) write to a characteristic value
(2) write command to a characteristic value
The difference is (1) has a response from the peripheral device. (2) doesn't have that. The advantage of (2) over (1) is that (2) can send multiple data blindly while (1) has to wait until there is a response to previous write before it could send next data.
Similarly, if your peripheral device (as server) wants to send some data to your iOS device, you could either indicate (with acknowledgement) or notify (without ack).
Hope this helps.
I'm developing an iOS app with an accompanying Bluetooth LE peripheral. The one step I don't seem to be able to solve is how to actually transmit the data from my app to the peripheral or vice versa.
What I've built so far is a test app that can connect to my sample Bluetooth peripheral, and read all of its services/characteristics/descriptors. It can toggle notifications for a given characteristic, and write to given characteristics. It is just this last step of "transmit n bytes to the peripheral, and receive m bytes from the peripheral" that I can't seem to figure out.
Looking at the External Accessory Framework (what I would use if Apple would actually give me MFi approval for this project), they give you input and output streams on a given session to communicate with the accessory, but no such object exists for CoreBluetooth.
Is this simply an oversight on Apple's part on the functionality of CoreBluetooth? Or do I simply need to develop my own Bluetooth service profile to handle the inflow/outflow of data to and from the peripheral?
LE is fundamentally designed to work with these GATT based profiles, which are suited for monitoring sensors, not for data streams. While LE does allow for additional L2CAP streams to be opened for custom protocols, Apple's CoreBluetooth doesn't provide access to do so.
You can build a custom profile with private services and characteristics and have it work kind of like SSP; that's the way I'm using my BLE module to get data from some sensors to my app. The module I bought (Microchip's RN-4020) already has a custom profile made specifically for this known as MLDP (Microchip Low-energy Data Profile).
The way I get the data in my iOS app is by subscribing to the private characteristic, thus being notified when the values are updated. So far it has been working great, and the data rate can go up to 20 kbps according to Microchip (I haven't tested its limits, since I don't need much speed). Here's a link to Microchip's product page: http://www.microchip.com/wwwproducts/Devices.aspx?product=RN4020
Good luck!
You can use the bluetooth.org 'Immediate Alert Service' uuid=1802 with characteristic uuid=2A06 with property=write_no_response to send one byte values to your peripheral device from your iPhone. The peripheral device must be programmed to act on the data that is sent. For example, you might use a button on an iPhone app to send a hex address that causes one or more port pins to turn on or off on the peripheral. While this is not using the Alert Service as it was intended, it does provide an easy way to test out data transfer to a peripheral device. The same process could be used to send sequential data bytes similar to a serial data stream. I have not yet tried sending more complex data streams. The write_no_response does not provide any feedback to the app as to whether the data was received by the peripheral.
The IOS TemperatureSensor.xproj is an example of code for reading temperature data from a peripheral. The OSX HealthThermometerClient.xproj has the code needed to decode the somewhat complex thermometer data structure. The IOS TI-BLE-Demo.xproj TIBLECBKeyfob.m has code for reading and writing characteristic values, such as, reading temperature or battery levels from a peripheral device.