How to get multiple ibeacons using CoreLocation, objective-C - ios

I'm using the following code to assign a beacon uuid:
NSUUID *uuid=[[NSUUID alloc]initWithUUIDString:#"1234545-12F-...-...-DGS457DHSJFHSD"];
But I need to detect several beacons with different uuid's.
How do I do it? Is there is any method to detect any possible beacon(with uuid unknown by the app) near the device?
I would like a method(if any) in Objective-C.
Thanks in advance

On iOS it is not possible to detect all iBeacons. You must tell CoreLocation the ProximityUUIDs you want to detect up front. You may register up to 20 different ProximityUUIDs to detect at any given time by registering different CLBeaconRegion instances, each with a different ProximityUUID.
Android, Linux and OSX do not have this restriction.
See here for details.

Related

New ibeacons not detected in my app

I am developing a beacon detection application and at the moment works very well for kontakt brand beacons.
The client has sent me some new beacons that i have never seen and I have searched with google but i can't find what brand they can be.
The following information related to this beacon they gave me:
uuid: fda50693-a4e2-4fb1-afcf-c6eb07647825
pass: 000000
name: ion_beacon00021
major: 16789
minor: 24532
I have transformed my code to monitor both uuid without making it work
for (index, beaconID) in beaconsIds.enumerated() {
let beaconUUID = UUID(uuidString: beaconID)!
let identifier = "BLERegionBeacon \(index)"
let beaconRegion = CLBeaconRegion(proximityUUID: beaconUUID, identifier: identifier)
self.locationManager?.startMonitoring(for: beaconRegion)
self.locationManager?.startRangingBeacons(in: beaconRegion)
}
func configureLocationManager() {
self.locationManager = CLLocationManager()
self.locationManager!.delegate = self
self.locationManager!.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager!.distanceFilter = kCLDistanceFilterNone;
self.locationManager!.activityType = CLActivityType.automotiveNavigation;
for region in self.locationManager!.monitoredRegions {
self.locationManager?.stopMonitoring(for: region)
}
if CLLocationManager.authorizationStatus() != CLAuthorizationStatus.authorizedAlways {
self.locationManager?.requestAlwaysAuthorization()
}
self.locationManager!.startUpdatingLocation()
}
When not finding how to make this new ibeacon work I have resorted to third party applications (like MyBeacon, Detector, Beacon Demonstrator, Locate) to get validate if the information I have of this beacon is correct, but in no application I have been able to make it detect this ibeacon.
I bought a new battery to make sure it was not as simple as that, but neither. :'(
I had the idea to use any application that detects bluetooth devices and I found BLE Scanner. With this application i was lucky and could realize that at least the name that i have of the beacon is correct, but not found any related to major or minor or pass. I also thought that the long id seen there could be correct and that the I had was not... But I discarded it because when I connected the brand kontakt also gave me a different uuid.
ISCONNECTABLE Jumps between YES and NO.
When i use BLE Scanner to detect beacons Kontakt show me addional info called SERVICEDATA and ISCONNECTABLE still in YES.
- Is there anything else that needs to be done to detect these beacons?
- Anyone have any idea what may be going on?
Thank you very much
EDIT
Following the help of davidgyoung, I could realize that the Locate application if it works but only in its version for android. And in fact correctly returns the information I had been given from that beacon at first.
I found that these beacons with configurable using an application called BeaconFlyer and there I realized the reason for being that password that had sent me. I was able to change the uuid although strangely I just put numbers and no letters. I changed it by 32 zeros following the same pattern of 8-4-4-4-12. I still get no results in IOS but works on android, even after changing the uuid.
It is possible that some brands need to be certified to be detected by iOS devices and that the android do not have these restrictions.
EDIT 2
Considering all these details, it seems that the problem is IOS and not android, so it occurred to me that maybe if I created a simple android project just to test the functionality of the beacons, I should be able to detect it.
The test was done by registering this UUID f7826da6-4fa2-4e98-8024-bc5b71e0893e which is the one that has always works for me and with which I detect without any problem the beacons markkontakt.
To my surprise I detect it without problem even without registering the UUID that I have for this brand. It is very strange considering that only register 1 UUID that was the mark kontakt
If you are detecting another beacon with the same code, then the simplest explanation is that the ProxmityUUID you were given is wrong.
You won't be able to determine the correct ProximityUUID from BLE Scanner on iOS, as iOS blocks access to iBeacon advertisements unless you know the ProximityUUID up front. If you can get your hands on an Android device you can use the Locate app to see any beacon regardless of its identifiers. https://play.google.com/store/apps/details?id=com.radiusnetworks.locate&hl=en You can use this to find out what it is actually sending. There are similar apps for MacOS as well if you have access to a Mac.
It is quite clear that your client sent you "beacons" and not necessarily "iBeacons". As davidyoung pointed out, what constitutes an iBeacon is specified (quite strictly) by Apple. Download the specs from there and have a look, if you are so inclined.
I have used several BLE scanners to check what uuid, major, and minor numbers various brand iBeacons I worked with have, among them the mentioned BLE scanner. I think the specification does not prevent somehow putting additional services into an iBeacon, which results in different brand iBeacons potentially showing slightly different info in different scanners.
However, what you show in the screenshot and the fact that the isconnectable field switches values make me think that these beacons are not correctly working.
There will be no way to make them work on iOS that way then. You can write your own Bluetooth protocol code to do stuff with them, but that then won't rely on Apple's iBeacon mechanics. This will mean the nice stuff like region monitoring even while the app is suspended and so on won't work. It's also probably more battery draining and in general more work.
I am as said not a Bluetooth expert, but learned this much: UUIDs are all over the specs. The UUID you (and Apple) refer to is a part of the data packet the iBeacon is supposed to send, but I have also seen BLE services in general being identified by UUIDs in (non-Apple) reference documents. This can get confusing when you scan such a beacon and see UUIDs (or at least strings that look like ones) in several places. So even if the beacons you have follow the spec (or can be configured to do so somehow) my guess is that someone screwed up. For example, they could have edited (maybe even with a hardwired connection and tool) the wrong UUID, not setting the one you need to use, but accidentally overwriting the part that specifies the device as an iBeacon (byte 5 and 6 of the data packet come to mind), making it impossible for you to use them.
As an advice I would suggest the following: If your client is interested in actual iBeacon functionality, tell them they should buy correct beacons. the kontakt ones are actually quite good. I've tested cheap china knockoffs and would advise against those, as they quickly become unreliable. It might be tempting to save a few bucks at first, but if you need to constantly replace beacons in the long run that becomes more expensive in the end.
One other theory about what might be happening:
A beacon advertisement packet implementing iBeacon must have Apple's manufacturer code 004c in order to be detected by iOS. Android has no such restriction. If this beacon is sending a different manufacturer code it would explain why only Android can detect it.
How do you find out if this is true? You need to see the raw bytes of the advertisement somehow.
The beacon brand is Iotton and it's looks like the one we sell:
https://www.beaconzone.co.uk/ibeacon/ton9108
It's unlikely the Kontakt app is showing the Iotton beacon because the local name is incorrect. It's more likely your Kontakt beacon - turn it off for now. With this or any beacon, the best app for getting the UUID and seeing if the beacon is working is Nordic nRF Connect.
Are you sure you have set the delegate on CLLocationManager? The code doesn't show it, so unless this is somewhere above or below, you'll need to add:
self.locationManager?.delegate = self
Then make sure your class implements CLLocationManagerDelegate the didRange(beacons: region:) method to get callbacks.
If you think you already have this set up, showing that code might reveal something else that is missing preventing it from working.

How can i make iBeacons private

I created an App which is using some iBeacons functionalities. The goal is to add some beacons in some clients stores so the App shows notifications specific for this stores.Now i am using an UUID that is the same for all my beacons and I am managing to identify the store using minor and major values.
How can I make the beacons not accessible by other Apps ? Is there a way to add passwords to beacons or something like this ?
Ok after looking in Estimotes websites i found out that there is a way to lock your beacons.
http://blog.estimote.com/post/103051450215/delivering-on-the-promise-of-beacons-a-modular
To wrap it up: There is a thing called secureUUID. This uuid is changing every couple of minutes. To be able to track this uuid you have to use Estimote cloud service so you can synchronise your app region tracking with beacon.
No this is not possible,iBeacons use very small package size on Bluetooth just sending the UUID and major/minor identifiers.
This has a draw back that you might fake a iBeacon if you know their UUID.

App callback for any iBeacon proximity UUID

I have played around with Airlocate and two iPhones. Also between a Linux /hcitool beacon transmitter and Airlocate ranging. I see that the set of proximity UUIDs to be tracked are hardcoded in the Airlocate source code.
Is it possible for an iOS app to get a more generic call back , when it is in the vicinity of any iBeacon (any proximity UUID) and let that app decide how to go about behaving the way it wants.
I understand that this should definitely be possible from the OS perspective, as I see a 9 byte iBeacon prefix in the start of the PDU, which is independent of the proximity UUID.
Another query - I view hardcoding the proximity UUID in the APP as some sort of pairing . How is general bluetooth pairing different from this.
My aim in asking these questions is to understand the feasibility of using beacons to beam (broadcast) data, so that all recipients in the vicinity can receive it. If I choose to go with a specific 16 byte proximity UUID, then I am left with only 5 bytes (Major/minor/power) to beam data. Otherwise I get 21 bytes
By "more generic call back", it seems like you are trying to listen to iBeacons that are not deployed by you. The answer to this is NO, you can't do that.
According to this post:http://beekn.net/2013/10/ibeacons-can-my-ios-app-find-beacons-that-arent-mine/ , in order to listen to an iBeacon, you must know its proximityUUID first.
Unfortunately Apple decides to limited your ability to do that. CoreBluetooth framework can detect iBeacon nearby but since it only returns the device UUID, not the proximityUUID, you cannot add callback to them.
And Android can read the proximityUUID of any iBeacon without any problem.

Estimote Repeat Notifications

I am developing an iOS 8 app with multiple Estimote iBeacons. According to (https://community.estimote.com/hc/communities/public/questions/200966066-How-detect-multiple-beacons-iOS?locale=en-us), I implemented one BeaconManager, and registered it with two BeaconRegions. However, only the second beacon region works.
Instead, I used two BeaconManagers and register one BeaconRegion for each of them. Now it works. However, a new problem occurs: in some cases when I enter or exit the region, I receive multiple notifications for one beacon, instead of only one. This link (http://beekn.net/2013/11/ibeacon-tutorial-dealing-with-errors/) says it's a bug from Apple, but I am not sure about the case.
Anyone can help?
Thanks,
Ryan
Beacon regions are shared system resources, which means that all the BeaconManagers and LocationManagers are notified about state changes of all the regions registered in the app.
Example: if you monitor beacon region A with manager A, and beacon region B with manager B, manager A will still get notifications about region B. Same for manager B and region A.
Because of that, it rarely makes sense to have more than one instance of a BeaconManager in your app.
Monitoring multiple regions should work just fine with a single BeaconManager, there must be something specific to your code that leads to one of the regions not working. If you could add a code snippet to your question, that'd probably help tracking the issue down.
As per my opinion, these should be only one beacon manager to manage all beacon.
And if you have beacon from same vendor (In your case it is Estimote iBeacons) then I don't think that you need to create more than one region here.
Because all beacons of same vendors have same proximity UUID. What is different is its Major value and Minor value.
So you can differentiate all beacons with its Major and Minor values also there is a ranging which can make a further granularity for seperation.

Detect Roximity iBeacon without Roximity SDK?

We are looking at ordering some iBeacons from Roximity but I am not clear if we have to use the Roximity SDK with these beacons or if I can use the core location functionality?
The reason I am asking is that I do not want to get tied to their SDK and then have to always buy beacons from them.
I was able to get the UUID of the Roxmity beacon, but I do not know what the beacons "identifier" is, so in the case of this code:
[[CLBeaconRegion alloc] initWithProximityUUID:_uuid identifier:#"COM.TEST.APP"];
I do not know what to put in place of COM.TEST.APP
I received some Roximity beacons yesterday, and used them successfully without the Roximity SDK. The UUID that our beacons had was:
8DEEFBB9-F738-4297-8040-96668BB44281
We found the UUID by scanning with a Mac app we wrote that finds any beacons in the local area. Simply create a CLBeaconRegion with that UUID and start ranging, and they should show up. Make sure you've removed the plastic isolator tab from the battery.
As #davidgyoung mentions below, the identifier parameter won't affect whether you can detect the beacons or not.
The identifier you mention in this line of code does not affect the ability to detect an iBeacon, Roximity or otherwise:
[[CLBeaconRegion alloc] initWithProximityUUID:_uuid identifier:#"COM.TEST.APP"];
The "COM.TEST.APP" identifier is just a reference string for you as an application programmer. By using this same string when constructing a second region, you are telling iOS that these are the exact same region. This is useful for canceling monitoring or ranging. It is also useful for replacing one region with another using the CoreLocation APIS.
As long as you keep it consistent for these purposes, that string can be whatever you want.
As for the bigger question if you can use their beacons independently of their SDK, try detecting their beacon with my free Locate for iBeacon app in the AppStore. You have to add the Roximity UUID to the configuration list, but once you do so, if the app is able to locate it, that means it is compatible with standard CoreLocation iBeacon APIs.

Resources