So I am currently using one device as a transmitter with a specific major and minor value and its broadcasting with
self.peripheralData = [[[CSMBeaconRegion alloc] initAsTransmitter] peripheralDataWithMeasuredPower:nil];
[self.peripheralManager startAdvertising:self.peripheralData];
And I am having a receiver that starts ranging and displays the major and minor value of the transmitter.
Everything works well. But when i start walking away from the device, and go beyond 10 meters, I lose connection. When i walk back, i still do not have connection. I can only restart the connection when I am less than 1m from the transmitter.
How can i increase the range of transmitter to its MAX?
Should I set some value to peripheralDataWithMeasuredPower?
The power of the iBeacon signal is based on BLE, you can't change it. The peripheralDataWithMeasuredPower is just use to calibrate ranging on the beacon.
Regarding your beacon not connecting when you come back in range, this is internal to the iBeacon system. It should work but sometimes there is a delay after you come in range of a beacon before your device detects it.
Something is wrong here. When using an iPad or iPhone as a transmitter, you should be able to detect its iBeacon transmission beyond 10m, even if you can't reach the 50m nominal range. Are you testing in an area with many obstructions?
And even if it does drop off at 10m, you should not have to return to 1m to detect it again (is that a typo?). If you simply wait at 10m away, are you sure it won't detect it again?
While #Patrick-Tescher is correct that you cannot change the transmit power of an iOS device acting as an iBeacon, some hardware iBeacons like Radius Networks' RadBeacon do allow you to configure their transmitter power. But you typically change the transmitter power with a proprietary mechanism that is specific to the beacon, and not with iOS APIs.
Also, while your iOS device may have a short range, dedicated hardware iBeacons often have a range that exceeds the 50m nominal range of Bluetooth LE.
Full disclosure: I am an employee of Radius Networks.
Related
I am showing the user a local notification when they enter a beacon region, and when they exit a beacon region. The exit is the most important because I tell the user how long they dwelled in that location. I am using region monitoring because it allows me to keep track of the beacons even when the app is in the background or suspended. I am experiencing a bug where I am monitoring 3 beacons (this happens with 2 and 1, but less frequently). My phone will sleep, and I will continue to monitor for the beacons. Then, my app will wake due to didExitRegion for one of the beacons, even though all 3 beacons are sitting face up on the same desk as my phone. It is a different beacon each time, so I have ruled our signal strength. Then, once the app is awake, it rediscovers the beacon and immediately re enters (because it never left the signal in the first place). I am detecting the signals with an android device at the same time, and the beacons are broadcasting the whole time, so the iPhone should not be losing these signals, especially not for a long enough time to consider it an exit.
I tried to remedy this by using
[self.locationManager requestStateForRegion:region];
However, in these situations this will return state 2, which is CLRegionStateOutside.
How should I get around this? Has anyone had a similar experience. I should be able to dwell in a beacon region for 1 minute or 1 hour and only get an exit when the beacon is undetected for 30 seconds.
A few things to check:
Verify this happens with multiple iOS devices. It is possible that the iOS device has a hardware problem such that it has weaker Bluetooth LE reception, or picks up more radio noise. I have never seen this myself, but I have heard reports of others who insist they have seen it on some iOS devices.
Check the signal level received by the iOS device and the Android device by ranging the beacon using an app like Locate for iOS and Android. The signal levels should be similar on both devices. A strong signal will have an RSSI of about -60 or less negative. A weak signal will have an RSSI of about -100 or more negative. If you have a weak signal, it may cause intermittent detection losses because radio noise will sometimes prevent packets from being received properly. If you can configure your beacons to increase their transmitter power level, do so.
With the Locate app in the foreground, range the beacon to check the signal level and rotate it at different angles. Some beacons have antenna patterns that are much weaker on one side. You may find that the orientation gives a much weaker signal, and again, a weak signal can cause dropouts.
Check the specs or configuration settings of your beacon to see how often your beacons are transmitting. Beacons that are configured to transmit rarely to conserve battery (e.g. once every 5 seconds) are more likely to cause this situation because it only takes 6 missed packets in a row (rare but possible) to cause a region exit.
One other possibility is that there is an unusual amount of radio noise periodically in your vicinity in the Bluetooth frequency range. This is unlikely, but I have seen it before. I live across the street from a U.S. Marine installation with powerful antennas, and at home I often get much higher packet CRC error rates than I do in the office.
I would like to use iBeacon to detect the proximity to a hardware (emitting iBeacon signals) when the app runs in background.
Is there a way to get CLLocationManager to detect the location/proximity to an iBeacon whilst the app is running in background?
Does using iBeacon affect the iOS battery performance in a variable way depending on the transmission frequency of the iBeacon hardware? In other words, if we have an iBeacon that has a high transmission frequency will the iOS device drain more battery as it will be receiving more signal than when using an iBeacon with a lower transmission frequency?
Technically, it's possible to force ranging (estimating proximity) in the background on iOS. The problem is, that it has big impact on battery and potential user privacy implications, so it's unlikely that Apple would accept such an app into the App Store.
The proper (as in recommended by Apple) way for an app to interact with beacons in the background, is with region monitoring: simply detecting whether the user is in range of a beacon. If you want to force background ranging though, there's a short guide for that: https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-
Cheers.
There are two different ways to use iBeacons - checking for region changes, or checking proximity to beacons.
In the background, you can't poll a beacon for proximity directly, you must instead use startMonitoringForRegion: to monitor for the crossing of the region boundary. Once that boundary is detected, your app will wake up to process in the background and handle what you want it to handle.
The application:didFinishLaunchingWithOptions: dictionary contains a key that indicates your app was launched due to a location event.
The transmission frequency of the beacon only affects the battery life of the beacon.
I am developing an application which will have multiple ibeacons to detect and react according. The client has different stores in which he wants to deploy the beacons. I am now in a situation where the ibeacons are very close to each other. All the beacons share the same UUID but different major and minor values.
The situation is this:
A user enters the shop and it receive first notification through beacon monitoring. Now to get the other notification for the other beacon the user has to left the region and enter it again in order for the didEnterRegion to call otherwise the user will not get the alert for the other beacons. And that is not happening in my case. The beacons are close to each other that the user not really leaves the region once it enters it. And the notifications do not come through ranging once the device is locked or the application is killed.
Any suggestions on how to tackle this problem in a real case scenario. How to get the notification for all the beacons on a lock screen. I am using the estimote beacons for development.
This is a common problem. As you have seen, background detection is only triggered by region monitoring, and if your regions are set up to cover multiple beacons in the same physical area, you won't get background notifications as you move between them.
You can only get entry/exit updates in the background for a maximum of 20 BeaconRegions per app. So the common solution is to creatively use these 20 BeaconRegions for maximum results. If you have 20 or fewer different beacons within range of each other, the technique is straightforward -- you simply create one region for each beacon, and monitor on all of these.
If you need to work with > 20 beacons, then you have to come up with a numbering scheme that helps this along. For example, you can set all of the beacons' ProximityUUIDs to the same value, number your major values 1-20, and then set the minor values to a unique number for each beacon. You then would then monitor for the 20 regions, each with a different major number. You would also set up simultaneous ranging so you can also get the minor identifier of detected beacons. Like this:
CLBeaconRegion *region1 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"region1" major:1 ];
CLBeaconRegion *region2 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"region2" major:2 ];
...
CLBeaconRegion *region20 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"region20" major:20 ];
[locationManager startMonitoringBeaconsInRegion:region1];
[locationManager startRangingBeaconsInRegion:region1];
[locationManager startMonitoringBeaconsInRegion:region2];
[locationManager startRangingBeaconsInRegion:region2];
...
[locationManager startMonitoringBeaconsInRegion:region20];
[locationManager startRangingBeaconsInRegion:region20];
This technique works well if you can ensure that there is never a case where two beacons with the same minor number that would be within radio range of a mobile device simultaneously (e.g. beacons with the same minor must be > 100 meters apart). If you can't do this, then you have to start making compromises.
Multiple beacons monitoring is not possible. Since iOS has limits, maximum number of supported regions should be 20. We can achieve your use case by doing the followings.
Group all the beacons with single UUID. We can monitor one region instead monitoring multiple regions
Capture the nearby beacons through ranging(Monitoring will trigger only enter and exit. When the user stays within the region for longer time, then monitoring delegated won't be triggered.) Sort the beacons with proximity received through didRange method.
If no beacons found with "Immediate" Proximity, move to next proximity Near.
Display notification if we found any one beacon with proximity Immediate. If more than one beacons are found with immediate proximity, then sort using RSSI. Lowest RSSI will be the closest beacon and display the notification for the closest one.
If no beacons found with "Near" Proximity, move to next proximity Far.
Display notification if we found any one beacon with proximity Near. If more than one beacons are found with near proximity, then sort using RSSI. Lowest RSSI will be the nearest beacon and display the notification for the nearest one.
If no beacons found with "Far" Proximity, then you don't have any beacons nearby.
Display notification if we found any one beacon with proximity Far. If more than one beacons are found with Far proximity, then sort using RSSI. Lowest RSSI will be the nearest beacon and display the notification for the nearest one.
Unknown - You can ignore this
You can approach this problem and solve it way easier. Stop triggering the notification when the users exit the region. Use instead the proximity function which will give you more flexibility: use CLProximity. You can choose between immediate, close, far etc. So based on the minor of the beacons and its proximity you can trigger the notifications you want.
I'm trying to understand how you are supposed to detect proximity changes in the background.
The only window I get to range is when I enter a region, but this might be pretty far away.
I would like to present something when the user enters "near" or "immidiate", but if you get "didEnterRegion" at far, than stand around, then approach the beacon, you don't get any more ranging time, because you are still in the same region.
Is there a way to either extend the "ranging" time to let the user get near the beacon, or can you make "enterRegion" happen at a different proximity than "far"?
Background ranging time is limited to a few seconds as Charles says in his answer.
If you need to delay action until you are in the immediate region, then you must use iBeacons that allow you to reduce the transmit power so the transmission radius is smaller. The RadBeacon product from RadiusNetworks has this configurability for this exact purpose.
If you configure a RadBeacon for minimum transmit power, your phone will not detect it until it is a few feet away, sending you the entry event and starting your limited ranging window at that time.
Full disclosure: I am Chief Engineer for Radius Networks.
This walkthrough shows how to do what you're asking. I'm in the process of adapting and testing it for iOS 8, but the resulting app works well on iOS 7, pushing local notifications whenever the proximity changes.
In the best practices section in Apple's Getting Started with iBeacon guide it mentions that ranging API should not be used in the background.
• Ranging API are not expected to be used in the background. For best results, ranging should
be used when your app is frontmost and the user is interacting with your app.
Could be a shortcut to app rejection, so take caution.
Given this, you shouldn't really be expected to determine proximity when in the background. I'm also employing the low signal technique, but it becomes a little trickier to differentiate between beacons when you only use one monitored region for multiple beacons...
What's possible with iBeacons in background is pretty limited.
What you can do is monitor regions in the background (which gives you the didEnter / didExitRegion events).
You can also switch on ranging for the beacon and, for the 10 or so seconds after you get a beacon enter / exit event from region monitoring you will also get ranging info (i.e. the immediate / near / far data).
Perhaps you could trigger a local notification at that point to try to get the user to bring your app into foreground - then you'd be able to get the ranging data. If not then, based on my tests, you're only going to get the 10 seconds of ranging data.
To your question about adjusting the ranging time or adjusting the enterRegion proximity - no, these aren't possible in the current version of iOS.
I have been playing around with various test apps that detect when the device enters or leaves the iBeacon's region but my question is are there any apps that will detect when a beacon is turned on?
The reason I ask is that if I sit in the same room as my iPhone and remove the battery from the beacon then re-insert it the none of the apps that I have tried so far trigger a region entered response.
Please excuse my non tech question as until I can find out if this type of detection is possible I haven't yet fully immersed myself in the coding as it may not be suitable for my application.
Think about it from your phone's perspective: Powering down an iBeacon looks exactly the same as moving out of its transmitter range. Likewise powering up an iBeacon looks exactly the same as entering its transmitter range.
The way that the iOS CoreLocation monitoring callbacks work (didEnterRegion / didExitRegion) is exactly the same for the two cases above.
I suspect the reason you aren't seeing a didEnterRegion callback when you power on your iBeacon is because you didn't leave it unpowered long enough. It takes time for iOS CoreLocation to decide the phone exited a region, and it generally won't tell you that you entered a region if it thinks it never left it.
Two suggestions to make this easier for you.
When doing testing like this, always verify you get a didExitRegion indication before expecting a didEnterRegion event. (Add NSLog lines to your appDelegate to help you see this.)
Turn on ranging for iBeacons whenever you set up monitoring for iBeacons. This makes the time needed to detect region transitions much faster when you are in the foreground.
More information on the time it takes to detect region transitions can be found in this blog post.
I had similar experiences and assume the phone checks for new beacon only when you move around. That makes sense from an energy saving perspective and the main use case of beacons.
To detect a beacon when it's powered on is possible, if the CLLocationManager object is currently ranging for the beacon, and it's already in range.
The thing to understand here is the difference between region monitoring and beacon ranging.
Some apps only start with region monitoring, ranging only when a region is entered, and stop ranging when the region is exited.(taking the batteries out will cause the region to be exited) When you put the batteries back in, the beacon in this case is not detected because ranging has been stopped.
When your app launches start ranging with startRangingBeaconsInRegion: method and don't stop this anywhere in your code.