UIBackgroundModes external-accessory - ios

I have added "App communicates with an accessory” under the Key “Required background modes” in my apps info-plist so that when the app is killed in any way iOS will prompt the user to restart the background syncing for any connected BLE devices.
I have read lots of documentation and seen lots of comments however nothing concert I have only had one other person tell me if I use this our app it will not be accepted into the app store.

The external-accessory background mode is for MFi accessories, not BLE accessories. There are separate Core Bluetooth background mode entitlements for BLE (bluetooth-central and bluetooth-peripheral).
If you declare the MFi accessory background mode but your app does not connect to external MFi accessories then you can expect your app to be rejected.
This is covered by clause 2.16 of the App Store Review Guidelines
2.16 Multitasking Apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc.

Related

iOS background app to read Bluetooth advertisement

Is it possible to build an iOS App that can run in the background, with minimal battery consumption, and collect BLE advertisements payloads of specific devices? Does iOS prevent such apps to work in the background even when the user has given consent?
Yes it is possible to build such an app that can continuously scan in the background. Check Apple's Documentation on the subject:-
CoreBluetooth background processing for iOS apps
Also check the following links with more details on the subject:-
BLE device keep connect with iPhone when app terminates
Leveraging background Bluetooth for a great user experience
iOS background Bluetooth: BLE scanning when phone is locked
However, there are limitations to the speed of the scan and the data retrieved from the scan. See the links below for more info:-
Scan peripheral in background
iOS: scan and connect to a BLE peripheral in the background
Overcoming the iOS background Bluetooth limitations

continuous run app in background. iOS Swift

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.

Apple Store App Rejection - Support for external-accessory in the UIBackgroundModes

I recently had an app rejected by the store for the following reason:
Our app declares support for external-accessory in the
UIBackgroundModes key in your Info.plist file but does not declare any
external accessory protocols supported by your app. The external
accessory background mode is intended for apps that communicate with
hardware accessories through the External Accessory framework.
I have read through some answers of previous people who asked this question but I am unsure on my case. My app communicates with a HM10 Bluetooth Low Energy module by sending and receiving bytes.
In my info.plist I stated that the app uses CoreBluetooth and communicates with an accessory. Which part do I need to change to fix apples concern?
Also, do I need to become part of the MFI program to use this HM10 Bluetooth module? Thanks.
Here is is my info.plist, thanks!
Also - the background modes:
Don't add "External accessory communication", only select the 2 BG modes for Bluetooth.
No need to join MFi program.
Then you'll be fine.

How to share data between apps while in background?

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.

CoreBluetooth advertising in background on iOS 10

First: I have an iPad Air 2, and an iPhone 7. For further reading we estimate that the app is active and open on iPad and in background mode on iPhone. The app is exactly the same, even with same Bluetooth Service UUIDs and same DataLocalNameKey.
I want to write an app that can advertise a bluetooth service in background and is able to discover this service (optimal in background too). As I already read I can't use apples beacon technology cause there it's only possible to get scanning/notified by beacons in near in background (I tested this, works fine) but not to advertise. So I started to use CoreBluetooth as described in the mentioned SO answer cause there it's possible to advertise in background.
My app calls didDiscoverPeripheral method in CBCentralManagerDelegate on the iPhone (app in background), so it detected the iPad. The isAdvertising property of CBPeripheralManager on iPhone is true. But didDiscoverPeripheral is not called on iPad. I'm a little bit confused. One option is my iPad is not able to detect the iPhone anymore for some reasons or my iPhone is lying and it's not advertising.
So i thought I'm just a little bit of dumb and googled for "CoreBluetooth debug apps". I found Vicinity and AltBeacon. And with both apps the behavior is the same! If you background (press home/sleep button) the advertising app, the browsing app is not able to discover it anymore. If you open the backgrounded the app it will instant discover it. Both apps mention that its possible with them to broadcast in background.
Am I doing something wrong; is this behavior expected? Did I misunderstood the framework? Can you confirm this behavior?
To confirm this, the fastest way is to install Vicinity on two devices (you have to add the NSBluetoothPeripheralUsageDescription key to Info.plist) set one device to broadcast and press the home button.
This isn't anything specific to iOS 10 -- it's always been this way on iOS. On iOS, apps simply cannot send out standard Bluetooth LE advertisements when they are in the background. They have to be in the foreground to do this.
That said, there is limited support in iOS for apps advertising GATT Services in the background. This uses a proprietary technique that only works with other iOS devices that are looking for those services. (Because it uses a non-standard proprietary scheme, the same technique won't work for beacon advertisements, for example.)
Here's how Apple describes it:
...you should be aware that advertising while your app is in the background operates differently than when your app is in the foreground. In particular, when your app is advertising while in the background:
The CBAdvertisementDataLocalNameKey advertisement key is ignored, and the local name of peripheral is not advertised.
All service UUIDs contained in the value of the CBAdvertisementDataServiceUUIDsKey advertisement key are placed in a special “overflow” area; they can be discovered only by an iOS device that is explicitly scanning for them.
If all apps that are advertising are in the background, the frequency at which your peripheral device sends advertising packets may decrease.
Read more here: https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html
it was a bug in ios 10.0.(1) and partially fixed in ios 10.1
src: https://forums.developer.apple.com/thread/51309

Resources