I'm currently trying to develop a Background Bluetooth related app, and I'm having some trouble scanning in background.
I followed the entire Apple IOS Bluetooth Background tutorial, but I cant figure out why scanning doesn't work in background (my info.plist is correctly set up to manage BLE Background tasks, both central and peripheral).
What I've tested so far :
1 - When my two devices are in range and in foreground, scanning works well.
2 - When the peripheral is in background, and the central comes active in foreground, scanning also works, peripheral is well detected.
Here comes the troubles
3 - first I launch my peripheral device, and I put the app in the background. Then on the peripheral device, I power off the bluetooth, I launch the app, I put it in background, and I power on the bluetooth.
In my code, the -(void)centralManagerDidUpdateState:(CBCentralManager *)central calls the scan [centralmgr scanForPeripheralsWithServices:[NSArray arrayWithObject:servicesUUID] options:scanOptions];, function which works perfectly in the foreground. But nothing happened, the peripheral is never detected by the central.
4 - I launch the central, bluetooth activated, and I put it in background. Then I took my peripheral device, I went out of the bluetooth range (in the specific case I went to my supermarket to buy some beers to drown my sorrow), I launch it there -also bluetooth activated- I put it in background and I came back in the proximity of my peripheral. Once again nothing happened, the centrals did not detect the peripheral.
Furthermore, after the cases 3 and 4, if I just put the central on the foreground (the peripheral stays in background), detection restart, without doing anything else. As if the scan was successfully triggered in the case 4, but waiting the app to come active to actually start detecting other devices.
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
Hi for details you can see this answer
but the short answer is one of your Apps must be in Foreground to connect to each other
Either your central device or the peripheral
Reason: for central you an only scan with providing the service UUIDs of the peripheral
and in background a peripheral cannot adverise its UUIDs
so even they are there they just don't know of each others presence
Moreover some more notable things about background scanning are
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.
See Apple Docs
Related
There is any API OR third party for BLE communication in iOS app background state ..?I tried “Uses Bluetooth LE accessories” ,”Background Processing”,”Background fetch” with these capabilities BL Scanning is working but Advertisement data packet decrease .In app foreground state advertisement data packet increase ..how can I get maximum quantity of advertisement data packets.? I am using service UUID for Scanning.
As Rob Napier said, scanning in the background state as aggressively as in the foreground state is impossible by design because the system has lower resources and is attempting to save power. This is detailed in Apple's Core Bluetooth Programming Guide:-
For iOS apps, it is crucial to know whether your app is running in the
foreground or the background. An app must behave differently in the
background than in the foreground, because system resources are more
limited on iOS devices.
Although you can perform many Bluetooth-related tasks while your app
is in the background, keep in mind that scanning for peripherals while
your app is in the background operates differently than when your app
is in the foreground. In particular, when your app is scanning for
device while in the background:
The CBCentralManagerScanOptionAllowDuplicatesKey scan option key is ignored, and multiple discoveries of an advertising peripheral are
coalesced into a single discovery event.
If all apps that are scanning for peripherals are in the background, the interval at which your central device scans for advertising
packets increases. As a result, it may take longer to discover an
advertising peripheral.
These changes help minimize radio usage and improve the battery life
on your iOS device.
You can find more information here:-
CoreBluetooth background processing for iOS apps
iOS BLE scan in background
iOS - Scan and connect to a BLE peripheral in the background
I trying to connect peripheral using UUID in the background, It's working only when i interact with advertising beacon first time at foreground then my app went background its working background and lock mode also if First time my app is away from advertising beacon i put my app at background then will come near to advertising beacon it's not working. in console, they came last peripheral not found as that error will come, my question is :
is this possible to scan or connect Bluetooth using UUID for the first time without the app opening?
i already tried that solutions also :
iOS BLE device paired while app is in background or killed or suspend
iOS: didDiscoverPeripheral not called in Background mode
didDiscoverPeripheral: not working sometimes on background
Not able to search my BLE Device which is providing service ID in scan Response iOS
Source file : https://drive.google.com/file/d/1uVR_kA3NsQUpM-LLgrGgXCeZK6PBO-A7/view?usp=sharing
Found this question a bit interesting, so went about studying CoreBluetooth.
As per the Core bluetooth programming guide
Although you can perform many Bluetooth-related tasks while your app is in the background, keep in mind that scanning for peripherals while your app is in the background operates differently than when your app is in the foreground. In particular, when your app is scanning for device while in the background:
The CBCentralManagerScanOptionAllowDuplicatesKey scan option key is ignored, and multiple discoveries of an advertising peripheral are coalesced into a single discovery event.
If all apps that are scanning for peripherals are in the background, the interval at which your central device scans for advertising packets increases. As a result, it may take longer to discover an advertising peripheral.
Now in your provided sample the background modes are correctly provided.
iOS looks for advertising packets only in background [Passive] mode and not the response packets
Searching further bought me to this link
ios- Scan and connect to BLE peripheral in background
You can check and see if this too is the case with you
I was searching for my Bluetooth problem a few days but I did not find any useful solution. I would like reading advertising data more precisely manufacturing data from peripheral devices via ios application when it is in the background. In my case, the peripheral devices are Nordic nrf51822 chips and a central device is ios phone. I have successfully implemented the Bluetooth background mode and it works well on the ios device. The Event handler DiscoveredPeripheral is called when the new peripheral device is discovered. But the problem is that it is called only first-time the peripheral device becomes visible. If I turn off and on the peripheral device the DiscoverdPeripheral event is not called anymore. I know that this is ios restriction, but I do not know how can I handle this ios limitation. In the end, I would like that app in the background starts scanning for peripheral devices with specific UUID periodically, for example, every 10minutes. At this point, I would like to ask if this scenario is possible to implement in ios if so I appreciate for any help.
The Event handler DiscoveredPeripheral is called when the new peripheral device is discovered.
This isn't correct. It will only be called once per call to scanForPeripherals. When the device connects, you should stop scanning. When the device disconnects, which you should see as centralManager(_:didDisconnectPeripheral:error:), you can begin scanning again.
Even better, if you only want to reconnect to the same device, don't scan at all. Just call connect for that peripheral UUID. It will continue running while you're in the background and wake you up when the connect succeeds.
To push this further, implement Bluetooth State Restoration, which will allow you to automatically reconnect even after reboots.
I'm trying to search if it is possible for iPhone to scan BLE device and read its advertisementData while it is in sleep mode.
For example, continuous scanning as long as it takes and then if a device changes its advertisementData the phone will wake up and fire a local notification. Meaning, the app is running in background mode for x period of time.
Is it possible? Because in android it is.
There are restrictions on peripheral scanning when your app is running in the background:
You must specify the service UUIDs you are interested in; you cannot use nil
The duplicate scan option key is not supported. This is probably what is preventing you from achieving your desired result
As the duplicates key is ignored in the background, if a peripheral has previously been discovered by your app then its discovery will not re-trigger the didDiscoverPeripheral delegate method until your app is re-started.
For long-term discovery you should also opt-in to state-restoration but that isn't needed for a simple test-case running under Xcode.
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