I want you to understand to my English skill is not good.
I'm developing an app using CoreBluetooth.
I checked I can do Bluetooth work in the background after running the app once (scanning, connect, get services).
However, I'm wondering if CoreBluetooth communication is possible in the background mode work without running the app at all.
For example, Once measurements are initiated on the peripherals, the central app will detect them and operate in background mode.
Is it possible?
I'm sorry that there is no code. Now I'm there is no method to start that.
I guess what you are looking for is CoreBluetooth State Preservation and Restoration. According to the documentation:
Because state preservation and restoration is built in to Core Bluetooth, your app can opt in to this feature to ask the system to preserve the state of your app’s central and peripheral managers and to continue performing certain Bluetooth-related tasks on their behalf, even when your app is no longer running.
When you opt in to state restoration, your app will be relaunched into the background on certain BLE related events. In particular, it keeps track of the following:
The services the central manager was scanning for (and any scan options specified when the scan started)
The peripherals the central manager was trying to connect to or had already connected to
The characteristics the central manager was subscribed to
Please be aware that there are limitations to what you can do while your app is using state restoration and background execution (you might be aware of that already).
Hope that helps
P.S.: We have found that state restoration only works while your iOS device is not attached to your development machine via USB cable (might be different with Xcode 9 now).
Related
in my app, I am connecting my app to BLE device. and I am fetching BLE data from BLE device at every 1 second. it working fine when I do this in the foreground.but I want to do same in the background even when the app will be in the background I need to fetch data continuously from BLE device. right now its stoped automatically after 2 minutes.
Please let me know if it's feasible or not?
Thanks in advance
You need to enable Background Mode in your project settings under capabilities tab. Under background modes you will find a few modes that satisfy various purposes of running an app in background. From these you have to enable the ones that you think are suitable according to the task that your app will perform in background. I think, you should enable external accessory communication and background fetch.
Also you need to implement a background task when your app enters background. This is done in app delegate's didEnterBackground method.
Apple documentation
Apps that work with Bluetooth peripherals can ask to be woken up if the peripheral delivers an update when the app is suspended. This support is important for Bluetooth-LE accessories that deliver data at regular intervals, such as a Bluetooth heart rate belt. You enable support for using bluetooth accessories from the Background modes section of the Capabilities tab in your Xcode project. (You can also enable this support by including the UIBackgroundModes key with the bluetooth-central value in your app’s Info.plist file.) When you enable this mode, the Core Bluetooth framework keeps open any active sessions for the corresponding peripheral. In addition, new data arriving from the peripheral causes the system to wake up the app so that it can process the data. The system also wakes up the app to process accessory connection and disconnection notifications.
In iOS 6, an app can also operate in peripheral mode with Bluetooth accessories. To act as a Bluetooth accessory, you must enable support for that mode from the Background modes section of the Capabilities tab in your Xcode project. (You can also enable this support by including the UIBackgroundModes key with the bluetooth-peripheral value in your app’s Info.plist file.) Enabling this mode lets the Core Bluetooth framework wake the app up briefly in the background so that it can handle accessory-related requests. Apps woken up for these events should process them and return as quickly as possible so that the app can be suspended again.
Any app that supports the background processing of Bluetooth data must be session-based and follow a few basic guidelines:
Apps must provide an interface that allows the user to start and stop the delivery of Bluetooth events. That interface should then open or close the session as appropriate.
Upon being woken up, the app has around 10 seconds to process the data. Ideally, it should process the data as fast as possible and allow itself to be suspended again. However, if more time is needed, the app can use the beginBackgroundTaskWithExpirationHandler: method to request additional time; it should do so only when absolutely necessary, though.
I'm afraid I already know the answer of my own question, but I decided to ask anyway before losing my hopes.
I have the following use case: an app writes some bytes in a "shared" resource (let's say on a file) and another app reads the data and sends them to an external device via BLE while in background. Unfortunately, I know that concepts like shared resource and background are bounded in iOS. What I tried so far is:
Using App Group to share data between two apps
This is working fine even in background, but both the apps need to be produced by the same developer team (i.e. Team ID must be the same). This is a problem because one app is not produced by my developer team.
Copying data in the pasteboard
This is not working when app is in background. Data will always be nil and will update only when the app becomes active again.
...and of course there are...
Background limitations
Even though I go for the App Group solution, the only way I can manage to read data and send to the BLE device in background is by starting a background task. This obviously is a caveat: the task has an expiration time (from tests I performed it keeps going for about 3 minutes before being suspended by the OS). I don't need to run a long-time task, but I cannot assure it can be performed completely by 3 minutes or so.
Here's the question: Is there some other solution for this use case or should I finally give up?
If you are using CoreBluetooth to send files to your Bluetooth device, you can try adding bluetooth-central as UIBackgroundMode key in Info.plist of your app.
Apple has mentioned this in its programming guide:
Communicating with a Bluetooth Accessory Apps that work with Bluetooth
peripherals can ask to be woken up if the peripheral delivers an
update when the app is suspended. This support is important for
Bluetooth-LE accessories that deliver data at regular intervals, such
as a Bluetooth heart rate belt. You enable support for using bluetooth
accessories from the Background modes section of the Capabilities tab
in your Xcode project. (You can also enable this support by including
the UIBackgroundModes key with the bluetooth-central value in your
app’s Info.plist file.) When you enable this mode, the Core Bluetooth
framework keeps open any active sessions for the corresponding
peripheral. In addition, new data arriving from the peripheral causes
the system to wake up the app so that it can process the data. The
system also wakes up the app to process accessory connection and
disconnection notifications.
In iOS 6, an app can also operate in peripheral mode with Bluetooth
accessories. To act as a Bluetooth accessory, you must enable support
for that mode from the Background modes section of the Capabilities
tab in your Xcode project. (You can also enable this support by
including the UIBackgroundModes key with the bluetooth-peripheral
value in your app’s Info.plist file.) Enabling this mode lets the Core
Bluetooth framework wake the app up briefly in the background so that
it can handle accessory-related requests. Apps woken up for these
events should process them and return as quickly as possible so that
the app can be suspended again.
I am planning to develop an iOS application using CoreBluetooth framework which monitors a pedometer peripheral continuously and counts the footsteps.
I know that if backgroud execution mode is set to BLE Central, the application will continue to receive BLE events even in the background.
Apple documentation states that in case the app gets terminated due to low memory, the system can keep track of BLE events for a particular Central Manager if state preservation and restoration is adopted.
Assume I have an iOS application that operates in Central mode. The app is subscribed to receive notification from a Pedometer when ever the footstep characteristic changes.
I have adopted the following in my app.
BLE Central background mode
BLE State preservation/restoration for Central Manager
I start my app, Scan, Pair and Connect to the pedometer and the app starts receiving footsteps.
My Questions:
Now if the iPhone reboots, Will I continue to receive BLE events so that my app will be launched in the background without the user having to manually launch the application again and connect to the pedometer?
If the app is terminated by the user explicitly using the multitasking gesture, Will the app be able to receive BLE events without the user having to manually launch the application again and connect to the pedometer?
Is there a way to launch my application on iOS boot up?
Now if the iPhone reboots, Will I continue to receive BLE events so that my app will be launched in the background without the user having to manually launch the application again and connect to the pedometer?
Your app won't receive BLE events because all apps are started in the terminated state after a reboot (despite remaining in the app switcher). The user will have to manually launch your app at least once after reboot in order for it to use BLE.
If the app is terminated by the user explicitly using the multitasking gesture, Will the app be able to receive BLE events without the user having to manually launch the application again and connect to the pedometer?
Same as above, the app has entered the terminated state, so it won't be able to communicate using BLE until it is explicitly launched again.
Is there a way to launch my application on iOS boot up?
iOS doesn't provide any way to launch your application on boot.
The one exception to all of this that I can find is iBeacons. If your app registers to receive updates for a specific iBeacon, iOS will launch your app when it finds it (even after a reboot or if the user explicitly kills it from the switcher). When you get the iBeacon callback you can start all your BLE logic and it will then run in the background per usual. Of course this means you need to advertise as an iBeacon on your pedometer, which may or may not be feasible.
Bear in mind the detection of the iBeacon is pretty finicky, especially after a reboot. You have little guarantee as to how fast or even if you will be delivered the iBeacon callback to start your app. But it's something.
Source
Is there any way to "wake-up" (relaunch) an iOS application (a background task actually, not to show the application) whenver a bluetooth device is connected?
For example, the iOS OS kills the application due to memory lack. Then a couple of hours later the user connects his bluetooth device. Can the iOS notify my application that the bluetooth device is connected and run a background task?
In Android I see that I can create a BroadcastReceiver that is registered for when a bluetooth device is connected. I need something equivalent to that for iOS.
If you have a pending connect for your BLE peripheral and you have specified BLE central background mode then yes, your app will be relaunched. You also need to implement state preservation and restoration as described in the Core Bluetooth programming guide in the event that your app is actually killed (not just in the background).
Note that in iOS a user cannot connect to a BLE peripheral directly - your app is responsible for identifying the target BLE peripheral and issuing the connect command. This is described in the programming guide.
Question is as title describes.
I have two apps, one CBPeripheralDelegate and one CBCentralManagerDelegate. The peripheral advertises when it is in the foreground (I think, I have no other BTLE devices to test it), but if I run the Central app in the foreground on the phone and the peripheral in the background, neither seems to see the other.
I have enabled UIBackgroundModes:bluetooth-peripheral in the peripherals info.plist as per the documentation for CoreBluetooth background execution.
I've found a few people trying to advertise in the background on here, but none to an app on the same device.
Let's say for the sake of my question that my code works perfectly... Can the bluetooth signal be 'looped' back into the same iPhone?
In short, no it cannot.
Although two different apps may be advertising and searching for their own services, at the end of the day they are still accessing the same chipset. Apple just masks away all the gritty details to streamline bluetooth dev.
Browse around the following link, if you want to break into some of the more underlying details involving Bluetooth Core System Architecture