I am working on an iOS Bluetooth LE application. First I pair the IOS (central) to my bluetooth chip (peripheral)
1) Discover peripherals.
2) Connect to peripheral.
3) Getting services and characteristics.
4) Able to read data and write data from the characteristics.
5) Save the peripheral
6) Disconnect from the peripheral
When I run the app the second time, it connects to the peripheral automatically and writes and reads data from the characteristic and disconnects from it. The App works in the background for 10 minutes.
I would like to run this app in the background. That is I want to call the methods which connect, write and read values in the background every 6 hours. Is this possible? My App works in the background for only 10 minutes. Any suggestion will be of great help.
First you will need to be sure that you added:
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
<string>bluetooth-peripheral</string>
</array>
to your Info.plist which will allow your app to run in the background.
However this will work as follows: it will allow your app to "wake up" to any bluetooth event and run methods that you like to fire when your app is getting any bluetooth activity.
So for example:
you can scan for bluetooth devices in the background and once found something that fits your criterias you can run code, as didDiscoverPeripheral fires (connect / read / write etc..).
you can be connected to a device and subscribed for notification from a specific characteristic. Once the characteristic changes value your app in the background should get a notification and didUpdateValueForCharacteristic callback will be called so again you can call methods from this point, still running in the background.
maybe you can think of other use-cases. I've mentioned these scenarios to give you an idea how you can definitely work in the background with BTLE.
These scenarios should not be limited to the 10 minutes timeframe.
However I have noticed that if you run something else in background mode (e.g: a loop) and the 10 minutes passes your app might be killed from the background so even the above mentioned callbacks will not work.
So to answer your 6 hours question: it would be possible if your BTLE device could initiate some BLE action every 6 hours to wake your app up. OTherwise I'm not sure you can start your activity from the app (ios) side.
Related
I'm currently trying to develop a Bluetooth IOS application that can work in background.
I methodically followed the tuts on the IOS developper website, and it works pretty fine; I'm getting stuck whenever I want to update a subscribed characteristic in background.
When my Peripheral device enters in background, I want the characteristic to periodically update, so that it send a notification to the Central device, taking advantage of the characteristic subscription mode.
Note : for now the characteristic is only a timestamp, updated every 5 seconds, in order to test if it works well
First I implemented a NSTimer, but as expected it is killed when the Peripheral app enters in background. Then I tried to establish a Background Fetch mode, but it is only possible to set a minimum refresh interval (and not warming up my application on fixed period).
Does somebody have an idea on how to proceed/overcome the problem?
Thank you!
Ps: I appologize for my English, I'm a bit rusty
I have a query regarding Scanning of the BLE devices in an iOS app.
Use case of our app is to share the location of a set of BLE devices assigned to each user continuously to a particular server for every 15 minutes time interval, irrespective of the state of the app (except terminated state may be).
About our BLE device, it transmits the advertisement data once for every 4 second interval.
We tried using the "uses Bluetooth LE accessory" background mode and continuously we were able to scan the BLE devices using the scanForPeripharal method in CBCentralManager with the UUIDs of the BLE devices.
We were able to get the list of scanned devices even in the background.
But when we lock the device and the screen becomes inactive/turned off, we are unable to get the list of scanned devices.
In another solution, we tried using the background fetch but it is very inconsistent(practically it never gets called in the given time interval).
We need a solution using which we should be able to do the following,
For every 15 minutes time interval.
scan the BLE peripherals around our vicinity.
Get the current location of the user.
Share it with a MQTT server.
A couple of options:
If you have a custom BLE device anyway, you could modify it to send a stream of iBeacon advertisements periodically, say a burst of 10 packets every 15 minutes. An app looking for the iBeacon using CoreLocation would wake up in the background every 15 minutes and you could then read your other advertisements with CoreBluetooth.
You could make your app request location background modes, and request fine location updates. This may allow you to get BLE device discoveries after receiving callbacks for location update events. The disadvantage is that you would need to satisfy the AppStore reviewers that your app is a consumer navigation app to get it in the AppStore.
Here is my scenario ..
I have a device that advertises dynamic data per BLE protocol. There are multiple such devices operating for a user
Questions -
1) Can IOS scan such constantly changing advertising data or does it expect advertising packets to be pretty static?
2) Can we create a service that scans for such packets periodically - maybe 30s every 5 minutes?
3) Can such a service be automatically restarted during bootup without user intervention?
You cannot create a service on a normal (non-jailbroken) phone. Isn't even possible to distribute something like that (read the app review guidelines). Sure, you can scan for BLE data on whatever interval you want, but your app needs to be active, or it needs to be doing something approved by Apple for making connections to BLE devices in the background. Just be aware that like any other background app, iOS might suspend or terminate your app at any time, and there's nothing you can do about it.
What you have described is covered by the standard BLE background mode - it is covered in the Core Bluetooth programming guide.
You can set up a scan for specific service UUIDs and this will continue in the background. Your app will be launched into the background when a device is discovered.
The exact scheduling of the notification can't be controlled - but in my experience you are notified pretty much as soon as a new peripheral is discovered. Once you have discovered a device you can even initiate a connection as soon as it disconnects (ie goes out of range) - iOS will automatically reconnect to the device when it comes back into range
In order for the scan or pending connection to survive across reboots you must configure state restoration. This is also covered in the Core Bluetooth Programming Guide.
I have worked on an app which read heart rate from server kinds of bluetooth low energy HRM(Heart Rate Monitor)by bluetooth notification.
And I have added the "App communicates using CoreBluetooth" into the app's "Background Modes".
It works fine when the app is in foreground, but when the app is in background, one of the Heart Rate Monitors is always to be disconnect with the app in sever minutes.
So I debugged the app and find that, this kind of HRM is always push notification irregularly.The interval between notifications is from 1 second to 20+ second.
I know that when the app is in background, iOS will stop the bluetooth connection if it is too long between bluetooth notifications.
So my question is: Is it possible to keep the connection when the app is in background?
Is reconnection the only way to solve my problem?
Detecting the disconnection and reconnecting to the peripheral will make your app more robust as it will handle the case where the peripheral goes out of range and then returns in addition to the case you are seeing.
When the peripheral is disconnected your centralManager:didDisconnectPeripheral method will be called on your delegate. In this method you can call connectPeripheral:options again to re-establish the connection. iOS will either do this immediately if the device is still in range or automatically later, once the device comes back into range.
Once your centralManager:didConnectPeripheral method is called you can re-establish the characteristic monitoring.
Edit Clarify that you can call connectPeripheral immediately
When using the BLE with CoreBluetooth (no iBeacon), is there a way to wake an app that is not running when the device receives a Bluetooth signal?
I'm simulating a beacon with the RedBearlab's BLE Shield (http://redbearlab.com/bleshield/).
Thanks,
DAN
* UPDATE 03/05/14 *
It looks like Apple has introduced a major update with iOS 7.1: now iOS will open your app for you if it detects a UUID that matches your app. The app only needs to be installed, it doesn't have to be running (logic in AppDelegate needed to answer the wake-up call).
If the app was running in the background and then closed (I mean here terminated - and you do not see it anymore in the list of background apps when you double click the home button) due to memory pressure from other apps, then the iOS will take care of waking it up again when a delegate is called (assuming you have background modes listed in .plist).
If the app was running in the background and then closed by the user (again I mean here terminated. So the user double clicked to get the list of apps running in the background and then clicked on your app in the background list until it wiggled and then pressed the 'x' next to the app to kill it) then this is a clear indication that the user does not want the app running in the background and the app will not be re-launched. The user has to relaunch the app for its delegates to start functioning again in the background (new in iOS7).
Update:
I am not sure if this is in the documentation but it is in CoreBluetooth WWDC 2013 Video. I recommend you watch it. They spent a good portion of the video on how CoreBluetooth behaves in the background.
From what I understand, if your app has not previously connected with the BLE Peripheral, then no.
If your app has previously connected with the BLE Peripheral, then use:
-connectPeripheral:options
Connection requests don't time out. The best place to call this method is when your app loses connectivity with the BLE peripheral. You will get notified when you lose connection to the peripheral in the CBCentralManagerDelegate Protocol:
-centralManager: didDisconnectPeripheral: error
So the next time your App comes in range of the BLE Peripheral, it will trigger this method. Also note that you will need to set up State Preservation and Restoration when you initialize a CBCentralManager.
https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html
the system wakes up your app when any of the CBCentralManagerDelegate or CBPeripheralDelegate delegate methods are
invoked, allowing your app to handle important central role events,
such as when a connection is established or torn down, when a
peripheral sends updated characteristic values, and when a central
manager’s state changes.
To perform certain peripheral role tasks while in the background, you
must include the UIBackgroundModes key with the bluetooth-peripheral
value in your app’s Info.plist file. When this key-value pair is
included in the app’s Info.plist file, the system wakes up your app to
process read, write, and subscription events.
You could try to declare voip in info.plist. For the time being, my application was automatically relaunched after a time, even user terminated it.