I am trying to build an app that is able to detect another iPhone with the same app within a certain proximity. I don't want to use location. Is this possible?
Assuming you're looking for devices pretty close to each other, generally on the order of a single room, maybe a bit further if you're lucky (sometimes quite a lot less if you're not), what you're looking for is Bluetooth LE (Low Energy).
Choose a service UUID (type uuidgen from the commandline; it'll make you one)
Using CBPeripheralManager, advertise your service ID (see startAdvertising)
Using CBCentralManager, search for the same service ID (see scanForPeripherals)
Register yourself as a background Bluetooth app, both as bluetooth-central and bluetooth-periphral (see Core Bluetooth Background Execution Modes for details)
With this setup, your app will advertise your service, and your app will automatically be launched anytime the phone sees something advertising the service.
See the Core Bluetooth Programming Guide for details. Bluetooth development is a bit finicky and there are lots of little corner cases you often need to deal with, but the basics are pretty straightforward, especially for this kind of use case.
If you just want to find people who are actively (in the foreground) using your app and communicate with them, take a look at GameKit. It's built on top of Core Bluetooth, but does a ton of the work for you. It's especially designed for getting people together to play games, but it can do a lot more than that.
One note: Do not confuse Bluetooth with Bluetooth LE. They are radically different and basically unrelated protocols. Bluetooth is used for things likes streaming music, and you have basically no access to it at all in iOS. BLE is used for exchanging small bits of data with low-power peripherals like heart rate monitors and the like. Core Bluetooth only deals with BLE.
You could also use iBeacons for this (An abstraction on top of BLE). iBeacons are a little easier to use than BLE, and like Core Bluetooth you can set up beacon region monitoring so your app will get launched if a beacon (or group of beacons) you are listening for comes into range. (But beacon monitoring uses the location manager)
Related
I work on iOS application which is using BLE for communication with our custom made BLE unit.
We want to send specific commands via BLE to the unit automatically.
When user is near unit and specific criteria are met, the app should connect to the unit, "login" the user, send command via BLE and disconnect right away.
These specific criteria are based on manufacturer data from advertisement (i.e. the unit is in "available to login" state when manufacturer data has last byte 0x01, when it's "NOT available to login", last byte is 0x00).
In foreground, this mechanism works flawlessly.
We want to do this even when app is in background or terminated (swipe up in dashboard on iPhone).
The mechanism we have implemented:
the unit has capability of acting as iBeacon
when unit is NOT available for login, the iBeacon is OFF
when it IS available for login, the iBeacon will turn ON and wakes up application, upon that the BLE scan will start in background mode
background mode setting is bluetooth-central
Problem here is that no matter what I tried, the advertisement:
sometimes it's not discovered at all (looks like it's timing issue?)
when it's discovered, it does NOT contain manufacturer data
Did anyone come across something similar?
Any help is appreciated and have a nice day!
An app simply cannot read raw BLE manufacturer advertisement data when in the background on iOS -- the operating system prohibits it.
Two exceptions to this rule:
iBeacon, which itself is implemented as a specific type of manufacturer advertisement. An app can detect iBeacons in the background on iOS, although only four bytes of readable data (encoded in the major and minor fields) are fully usable. If you can modify your device to send information this way, it will do what you want. However you must use CoreLocation APIs to detect iBeacon, as CoreBluetooth does not allow reading manufacturer data from iBeacon advertisements. If you do use CoreLocation, you cannot use the detections to establish a Bluetooth connection with CoreBluetooth as the two APIs are sandboxed.
Overflow Area advertisements. Backgrounded iOS apps can read these special types of manufacturer advertisements when in the background but only if the screen is turned on. (It is often possible to force the screen on at specific times by sending a local notification.) See my blog post here for more info: http://www.davidgyoungtech.com/2020/05/07/hacking-the-overflow-area
An alternative to detecting manufacturer advertisements is to use BLE Service advertisements with attached data. For this to work, you'd need to define a 16 bit or 128 bit GATT Service UUID and send out an advert with attached data bytes. Eddystone beacon formats work this way, and allow detection in the background on iOS. This is probably the best approach if you can alter the BLE hardware.
I have got a chip that has a iBeacon service as well as a standard BLE service.
I would like to use the iBeacon service to trigger the app that I am developing when entering a BLE signal range.
Once active I'd like the app to scan for peripherals using CoreBluetooth and then connect to the chip.
Is this against Apple terms and conditions?
Apple has no known restrictions on this setup. In fact, this is how the RadBeacon configuration app works.
Using this technique, detecting a beacon in the background will only give your app 5 seconds of background running time, which generally is not enough time to reliably complete Bluetooth pairing and data exchange. Your best bet would be to present a local notification to the user on beacon detection, and then if the user brings the app to the foreground, do the pairing.
An alternative would be to extend background running time using a technique like described in my blog post here. That post shows how to range for beacons in the background, but the same technique will work for bluetooth communication tasks.
I was hoping someone could spell out the relationship between iBeacon recognition, CoreLocation and CoreBluetooth, specifically in the context of what iOS considers "geo-fencing".
First off, I understand Apple's documentation on Using Regions to Monitor Boundary Crossings and have seen other discussions around the topic, like iOS - CoreLocation and geofencing while app is closed (especially pertinent to our app since this is a background operation). However, I'm having a hard time finding Apple's explicit definition of geofencing and exactly which frameworks get categorized as such.
Consider:
Beacons are based on BLE and yet they use the CoreLocation framework and not the CoreBluetooth framework. In fact, you do not need to add Bluetooth capabilities to the project settings in order to get them to work.
Detecting beacon regions uses the same object and method calls: to register a region, you call the ‘startMonitoringForRegion’ method of ‘CLLocationManager’ object.
It appears that once we added beacon recognition to our app, users have begun seeing "geo-fencing enabled" messages in their settings.
I thought geo-fencing was purely used in GPS- and Wifi-based location services? Not BLE services? The whole point of BLE beacons is to reduce the drain on the battery that geo-fencing produces.
On a higher level, is there any way to prove demonstrably that using beacon technology produces a much lower battery drain than other location-based geo-fencing? Using "geo-fencing" as an umbrella term for both (if that is indeed what is happening), muddies the waters significantly when making a business case for beacons.
I want to build and app which can detect other iPhones with my app within 65 feet range. As I understand I have the following choices:
Use Bluetooth to check periodically whether there is device with my app in the range. Send list of found devices to the server. The problem here is battery consumption. Is it true that Bluetooth will be disabled after some period of time automatically?
Can I use BLE technology for this purpose? If so, do you know what devices support BLE?
What is the best option on your opinion? Did I miss some other option?
Thanks
UPDATE
I plan to run search every 20 seconds or even more often.
There is no simple answer to this problem.
Bluetooth has 2 flavors: "Regular" bluetooth, used for hands-free devices, headphones, and the like, and BLE (Bluetooth Low Energy)
Regular bluetooth devices must be paired. (I'm less familiar with regular bluetooth than BLE, so take my explanation of this bit with a grain of salt.) In order to be paired they have to be put into "discoverable" mode, which broadcasts their ID. That is a battery-draining and only done briefly. It's not an "always on" solution.
BLE has a range of up to 60 meters, so it should meet your need in that regard.
BLE devices can "advertise" as a "peripheral" for extended periods. Other Bluetooth devices can act as a "central" and ask to be notified when certain peripheral devices are detected. I'm not sure if you can make an iOS device advertise (broadcast) as a BLE peripheral while it's in the background and/or if the device is locked, but it will certainly advertise while it's running. I'm pretty sure you can register to be notified when you detect a certain BLE peripheral from the background, but not positive.
iBeacons are a specific use of BLE with some extra limitations and some extra abilities. An iBeacon is a dirt-simple transmitter that sends a UUID plus a major and minor value and a signal strength calibration value periodically (usually once a second.) You can't add any other data to an iBeacon transmission. iOS can only act as an iBeacon transmitter when the app is in the foreground. If your app moves to the background, it stops transmitting. Period.
However, you can listen for iBeacon signals even from the background. AND, if you've registered as a listener for an iBeacon and the system terminates your app due to low memory, the system still listens for those beacons on your behalf. If iOS detects a beacon you're listening for, you get re-launched if needed, and notified in the background. You can then post a local notification to get the user's attention.
iBeacons are probably your best bet, but you will need your users to be actively running your app in the foreground in order to transmit a signal. That will drain your user's battery fairly quickly.
One possible solution would to have have every single device send their locations to your server every predetermined time period (more frequent the better but more resource intensive). Then, query the data from the server and get the location of all the devices near you.
Keep in mind, that this probably won't be very useful for real-time data collection. For example, if you want to send data every 30 seconds or so, this isn't a good option.
Use this option if you want to get data every 15-20 minutes or so.
how is it possible to send data to an iPhone which acts as an iBeacon?
I am looking for an process as the following:
Search nearby iBeacons
Connect to some iBeacon
Exchange data between the devices
Does anybody know how to put the different bluetooth functions together to make
this possible?
thx in advance
Standard iBeacons are transmit-only devices that can be seen by mobile devices, but don't actually "connect" to them or exchange data.
But you can still do what you are asking if you have an app on all devices as well as a web service to do the data transfer. This would allow devices A and B to detect each other when they are nearby and exchange data. Here's how:
Your app on devices A and B alternates between acting as an iBeacon (advertising its presence with an application-specific identifier and a phone-specific identifier) and ranging for iBeacon signals including the application-specific identifier.
During its ranging cycle, your app on device A will detect an iBeacon transmission from device B, which includes both your application identifier and the device identifier of B.
App A then makes a "write" call to the web service with a source of "A" and a destination of "B", along with any data you want to transfer, like "Device A says hello to device B."
The app would also periodically make a "read" call to the web service. In this example, device B would read any information destined for B, and the web service would return a record that device A had send it a message with the data "Device A says hello to device B."
Because the same process is also running on both phones, this communication can happen both ways.
iBeacon is a proximity technology and isn't designed for data interchange. However, since the Bluetooth stack is going to be active on your iPhone acting as the beacon (so it can advertise its proximity UUID), you can use Core Bluetooth to connect to the beacon and exchange data between the devices.
Does it specifically need to use iBeacon technology? The reason I ask is that from reading your description of the process, you could achieve the same thing using iOS 7's Multipeer Connectivity. It's able to abstract out all the technical complexities of connecting 2 iOS devices together regardless of the interface, be it WiFi or Bluetooth. I've managed to build something similar using MCNearbyServiceBrowser, MCNearbyServiceAdvertiser, and MCSession classes.