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
Related
I have an iOS and macOS app that make heavy use of Core Bluetooth. The core functionality of the app involves having a central device (CBCentralManager) connect to a peripheral device (CBPeripheralManager), retrieve some data, then disconnect. Either device, whether macOS or iOS can act as either a central or peripheral depending on who needs the data.
At first I thought there was an issue with my code, but after testing the app with two iOS devices, one is able to connect and extract data from the peripheral device even when the peripheral device is locked and the app is in the background. Now according to the docs concerning background advertising on iOS under "The bluetooth-peripheral Background Execution Mode" this is kind of expected:
...they can be discovered only by an iOS device that is explicitly scanning for them.
Is there any way to have a macOS app discover peripherals even when they're backgrounded? I'm sure the code I've written is correct because it's the same across iOS and macOS.
Update 1
I believe that this might be possible just unsure how to approach the issue. Using Apple's Bluetooth Explorer on macOS, I am able to find the desired device AND I'm able to see and read data for my custom service.
This finding is validated from logs from my iOS device about the read requests which are from my peripheralManager(CBPeripheralManager, didReceiveRead: CBATTRequest).
I've a iOS 10 device in my work place and I got curious about it's bluetooth's weird behaviour. So.. I was playing around with my Android's Beacon simulator App and I noticed that every time I unlocked my IPhone and enabled the Bluetooth a new entry was immediately created in my android's near by beacon's list. Is there a reason for that?
UPDATE 1
- handoff disabled
- AirDrop disabled
- No open apps.
= still got a mysterious broadcast on my Beacon Simulator App.
UPDATE 2
Ok, I was digging into the subject and noticed that the iOS device is not being able to find near by devices in a standard bluetooth discovery.
In the other hand, near-by devices can detected the iPhone and when clicking on his entry in their result's list a popup for pairing shows up on Iphone's screen and as if it was magic the name of the device trying to pair shows up on the iphone's list that is always empty, in this case Huawei P9 but tested with a note 4.
I am the developer of Beacon Simulator. I just want to warn that the app is a Beacon simulator before all, not really a Beacon scanner. I added the scanning part because it was easier to do some tests, for the beacon copy feature and also for future developments.
What the scanner will show you is not necessarily a beacon, but any scannable Bluetooth Low Energy devices, connectable or not. Unfortunately, it is difficult to know if a device is connectable or not with the Android API, so the app lists everything.
Since the icon represents a standard Bluetooth logo, it means it is a signal not recognized by the app (here, it isn't an iBeacon nor AltBeacon nor Eddystone beacon). So either it is a non standard beacon, or simply a signal to advertise a possible connection to the device. When a connectable device broadcast its presence, the signal uses the same channel and protocol than the one used by beacons. A connectable device will advert itself as connectable, but as said, the Android API erase this difference, unfortunately.
So what you see is not necessarily a beacon, but maybe simply your iPhone broadcasting its presence as a connectable device. Maybe I should add some disclaimers in the app.
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
We would like to use some configuration of the iBeacon , where the user's iPhone will advertise its services, but when the app is closed.
So when a user come across a hardware beacon, it will recognise the user's iPhone(as a beacon) without opening the app, and even connect to it .
I could find here many opinions about that, but i wonder if there are any news with the iOS8 ,and if there is a clear answer for that from Apple ?
A couple of points:
Bluetooth beacons, iBeacons included, are transmit only. They don't see or "recognize" other beacons or phones. The statement "when a user come across a hardware beacon, it will recognise the user's iPhone(as a beacon)" is not possible with the technology regardless of whether the app on the phone is in the foreground or the background.
iBeacons are supported on iOS devices with version 7.x and 8.x of the operating system. On all these versions, however, beacon transmission from the iOS device is only supported when the app is in the foreground. See here for details.
I have read the docs about the BLE for iOS, and i could see that every device has its UUID instead of mac adress for the BLE.
My question ,in which there is no answer to on the docs, is- when you turn on the bluetooth on the device ( without opening any app) , so the device's bluetooth is on , what does it advertise then, and could I discover that device or get its UUID, while his bluetooth is on,but without any app that is open.
I am pretty sure that when the BLE is on, you can discover that device, or awake him, but I wonder what data can I get from him while its on without an app .
(same for Android.. )
iOS does not advertise any Bluetooth Low Energy services that are visible to another iOS device without an app running. Once an app advertises a service you will see additional services available - device information, time service, battery level.
If you are using different Bluetooth hardware to scan then you may see some advertisements without an app but the reported UUID of an iOS device changes every 15 minutes for privacy reasons - See this answer - Corebluetooth, How to get a unique UUID?