I've been searching around to find a straight answer to a problem I'm facing and the information is a little scattered. I'm not sure whether it's possible or not based on the answers.
Basically I'm using iBeacons as a component to my app. The scenario is this, you have a high street with numerous shops. Each shop has 1 beacon in their window facing to the street. A generic shopping app is on the user's phone.
When a user walks up the high street I want a user to receive a notification when passing a shop. This notification would say something like "Check out MyShops latest offers and discounts" with a prompt to open the app. This is all as the app is in the background.
All the beacons have a consistent UDID which tie to my app. And each shop would have it's own major identifier.
I want the notification to be specific to a shop (with a specific beacon major and minor) but I cannot find a way of determining which beacon was entered while in the background.
Also some shops may be close and have broadcast overlap, will the background process for entering a region trigger for each beacon you get in range of if they have the same UDID?
You can do what you want with a common app that launches the other store-specific apps once it is brought to the foreground by a user tapping the local notification.
A few points:
You must combine CoreLocation monitoring and ranging APIs to do this. Monitoring will wake up the app into the background on beacon detection (but only for 10 secs) and ranging will give you updates every second with an NSArray containing all visible beacons with the full beacon identifiers and a distance estimate for each.
In the ranging callback, you can compare the estimated distance to all visible beacons to determine which is closest (CLBeacon.accuracy). The closest one is what should send the local notification for the shop.
Do not confuse the beacon ProximityUUID with the iOS device's unique UDID. The two have nothing to do with one another.
Related
I'm building an iOS App, in which I would wish to handle more than 20 iBeacons. Basically all beacons added to the web portal have to be handled by the App. Since there is an iOS restriction to number of region to be monitored as 20, I'm unable to give different local notifications for beacons in same region (having same UUID).
Is there any way to handle this?
A few points:
The 20 region limit applies to the number of CLRegion objects that can be registered by a single app. It does not mean you can only detect 20 beacons. Since each CLRegion object can leave the major and/or minor nil (making the fields a wildcard), each one can match billions of beacons.
Beacon apps typically use local notifications, not push notifications.
The way you set up many different notifications to come from many different beacons is like this:
Define a single wildcard region that matches all of your beacons. (Or a few regions if needed for background triggering).
Start monitoring and ranging for each of these regions.
In the didRangeBeacond:inRegion callback keep a flag for each individual beacon to see if you have sent a notification for it before. If not, set the flag to true and trigger a local notification specific to that beacon's identifiers.
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.
I have created a app for detecting the beacons. things are going on good. the problem that I have is:
When there are more beacons overlapping on one another. how am I suppose to handle the situation considering the case
1. When we want to receive the offer only once from a particular beacon on entering to the beacon/we are in the place where we have more than one beacon overlapping each other.
Thanks,
When you have overlapping iBeacons, it is important to design the iBeacon identifiers (UUID, major, minor) and the CLBeaconRegions you use to monitor them so that you get the results you want.
Do you want to trigger "the offer" whenever any of the overlapping iBeacons are detected? If so, then monitor for a CLBeaconRegion that matches them all, probably by setting just the UUID (and maybe the major if all beacons share that value.) In this case, you will only get one Region entry notification when any of them are detected. You won't get one for each overlapping iBeacon.
If you only want to trigger "the offer" when a single one of the overlapping iBeacons is detected, then monitor for a CLBeaconRegion that only matches that one iBeacon, typically by specifying the UUID, major, and minor in that CLBeaconRegion. Of course, you also need to ensure that each iBeacon is configured with a different minor. Remember, too, that you can monitor for multiple CLBeaconRegions simultaneously, if needed, and get a specific callback for each one.
While it a separate issue from overlapping iBeacons, if you really want users to "receive the offer only once", you also need to add a filter to your detection callback. A glitch in iOS sometimes gives you a very quick exited region callback followed by an almost instantaneous entered region callback. In order to prevent users from getting the offer a second time, store off the timestamp of the last time the offer was pushed to the user, and only push it again if enough time has passed (say 1 hour or one day.) See this answer for details.
My workflow at the moment is to detect in the didRangeBeacons method the Beacon which is the closest to my actual position. This is done by comparing for each beacon the rssi property.
After identifying the closest Beacon I process the desired action for this beacon.
To avoid that this action is triggered repeatedly (beacause the didRangeBeacons method is triggered a couple of times per seconds) I implemented an isLocked Flag (BOOL) in my actual beaconHandler, which does the processing.
So I only react to the Beacon which is the closest to me. And I only react once. I also keep track of my last beacon which I identified as closest. This enables me to react immediatly, If you are getting in Range of another beacon. So e.g. when you walk along a store, every beacon is triggered immediatly, but not repeatedly.
From what I have understood, minor and major ids in beacons are used for segmentation (for instance, major for physical stores and minor for different locations within a given store).
Then, as a beacon does not deliver rich payload, I guess those ids will be exploited to deserve the adequate information to the user - and probably through webservices.
Finally, UUID are said to be for the whole fleet. From what I understand, an app (e.g for retail store) is likely to register for only one or a few UUID (generally one, more for complex architectures or overload of services).
At the application level, you can (1) range for beacons when the app is foreground (with catching capabilities for minor/major ids), and (2) detect region exit/entry (monitoringForRegion:) while in background + deliver UILocalNotification to wake up the app (going back to (1)).
Now lets deal with the end user. I think we can assume that the average one will not go through a whole retail store with the app in foreground in his hand, and is more likely to have it running in background.
Consequently, case (2) will be the most common one.
But as all emitters will share the same UUID and as the geolocation manager running in background is monitoring for region linked to UUID, didEnter and didExit regions delegate methods risk no to be triggered intelligently depending on the range/configuration of emitters. Finally, not all the indoor location-based advertising you wanted to broadcast to your customers will be received and catched.
In fact, I fear that only the one when the customer will arrive at the store location will be systematically suggested (in a background mode context).
Am I missing something?
You are mostly right. The one thing you are missing is that you can monitor on 20 different regions simultaneously, and these regions can optionally include the major and/or the minor. So you could trigger many times in a (big) store by intelligently designing your iBeacon identifiers and region monitors.
Two caveats: in-region monitoring callbacks fire when the beacon first comes into range (about 50m). They are also not simultaneous. They can take up to 15 min on an iPhone 4S with the app in the background, although it is faster on an iPhone 5.
To phrase what David said a little differently:
You can define a beacon region using a UUID, a UUID and a major value, or a UUID + a major and a minor value.
If you define a region using just the UUID, any beacon with that UUID will trigger a didEnterRegion message, and the OS will treat all beacons with that UUID as part of the same region.
However, if you create a region with UUID+Major, or UUID+Major+Minor, only beacons matching those values will trigger a region notification. You can have 2 beacons with the same UUID and major value right next to each other and different minor values. If you've registered 2 different regions with specific UUID+Major+Minor value, you'll get independent enter/exit/ranging messages about each region. A third beacon with the same UUID and major value but a different minor value will not trigger enter/exit notifications.
This question is about when the Application is in background
I got a Application which works with 2 iBeacons (same UUID, same Major, different minor ).
The first iBeacon (minor 1) is for example for the Door. When the App is in the Background i get a Notification that i enter the region. This works fine. And now, for example, i walk in the Store and at some Point is the second iBeacon (minor 2).
If i'm in the immediate Zone of the second iBeacon, the Application should fire a notification. ("Hey you're at the cashpoint").
But i read that's not possible when the Applikation is in the Background. It only works when i hit the shoulder button or home button.
http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html
So the Question: Can anybody give me a hint how to implement this use case.
Several things:
When you create a beacon region, you can either match on just the UUID, the UUID and major value, or the UUID, major AND minor value.
If you specify just the UUID, your beacon enter/exit notices will not include major/minor value information.
Likewise, if you create a region with a UUID and major but not minor value, your beacon enter/exit messages will include the UUID of the beacon and the major, but not the minor, value.
The simplest thing to do is to create a separate region for reach unique beacon you're tracking. Then you'll get separate enter/exit notices for each beacon.
If you want multiple beacons to be part of the same region, but report different major or major/minor values, you have to turn on beacon ranging and wait for a ranging call. In the ranging call you'll get an array of beacon objects (not beacon region objects, CLBeacon objects) for all beacons that match the current region. The beacon objects will include the actual UUID, major, and minor for that beacon.
If you are in the background and have both beacon monitoring and ranging turned on, you'll get an didEnterRegion message (or maybe a changed state message) followed by several seconds of ranging information, and then your app will go back to sleep.
When your app is in the background, your only real option is to display a local notification and hope the user wakes your app again. If the user swipes that notice, the system prompts the user for unlock credentials if needed, and then takes the user back to your app.