DidEnterRegion only called if requestAlwaysAuthorization is called. Beacons - ios

didEnterRegion and didExitRegion are only called after I request and allow Always Authorization for CoreLocation
Even if I request WhenInUseAuthorization didExit and didEnter won't be called
How am I supposed to trigger ranging of beacons if I can't get this to be called?
Any solutions?
UPDATE
Apple rejected my app for calling requestAlwaysAuthorization()
Here is my question submitted to the review team this morning:
In order to monitor beacon regions (a very core functionality of beacons used in many apps including some Apple apps) you need to have the user allow the app to access location even when not using the app. I am using .requestAlwaysAuthorization to enable beacons to monitor in the background. Why won't this be allowed?
Apples response this afternoon on iTunes Connect:
Thank you for your feedback. However, background location is not necessary for iBeacon functionality. Therefore, it is necessary to remove the background location feature before resubmission.
So if beacons are supposed to automatically monitor regions in the background, but I can't ask permission for background monitoring and beacons won't monitor in the background unless I get permission, how then am I supposed to monitor regions in the background??

Do you mean when the app is in the background? If so, then it is true that didEnterRegion and didExitRegion don't get called with only a WhenInUseAuthorization. They will only get called when you app is in the foreground and you enter/exit a region

background location is not necessary for iBeacon functionality. Therefore, it is necessary to remove the background location feature before resubmission.
It seems that your app was rejected because of the Background Modes (specifically, the "location updates" mode), no the "always" authorization. You don't need any Background Modes enabled for beacon monitoring to work in the background, the "always" authorization is enough.
Simply disable the Background Modes capability in your project settings and you should be good!

Unfortunately, you must request Always Allow location access to use region monitoring with beacons.
From the docs:
Important
Apps must have always authorization to use region monitoring, and they must be configured with the Location updates background mode to be launched.
https://developer.apple.com/documentation/corelocation/determining_the_proximity_to_an_ibeacon

Related

iOS: Location Update in Application Suspended State

Is it possible to update location when application is in suspended/terminate state.
i want to update location every 500 meters when app is in suspended/terminate state.
thanks in advance.
When terminated the only real way to get updates is to use Region Monitoring but you will only get major updates so I doubt it will work for 500 meters.
From the documentation:
If your app is terminated either by a user or by the system, the
system doesn't automatically restart your app when new location
updates arrive. A user must explicitly relaunch your app before the
delivery of location updates resumes. The only way to have your app
relaunched automatically is to use region monitoring or
significant-change location service. However, when a user disables the
Background App Refresh setting either globally or specifically for
your app, the system doesn't relaunch your app for any location
events, including significant change or region monitoring events.
Further, while Background App Refresh is off your app won't receive
significant change or region monitoring events even when it's in the
foreground.
There are good reasons for this. Firstly people don't want apps that 'snoop' on them all the time and even if there is a good reason imagine having 10 apps doing this constantly. It's going to start causing you performance and battery life issues.
EDIT
There appears to be some confusion by a lot of people over this issue so I will attempt to clear things up a bit.
Your app is NOT supposed to be continually tracking location while terminated (or suspended really). You are just not allowed to do this both for privacy reasons and so that you don't drain the battery excessively.
While your app is in the foreground you can use location services via startUpdatingLocation to monitor the device location. Assuming the app has been granted permission this will use all available hardware (GPS, WiFi, Cellular).
Now from the documentation itself:
If you start this service and your app is suspended, the system stops
the delivery of events until your app starts running again (either in
the foreground or background). If your app is terminated, the delivery
of new location events stops altogether. Therefore, if your app needs
to receive location events while in the background, it must include
the UIBackgroundModes key (with the location value) in its Info.plist
file.
So once suspended and terminated your options are really to monitor regions and to monitor for significant location changes. Neither of these are particularly accurate or frequent. One reason for this is that they only use low power methods to get the position (WiFi and Cellular) they don't use the GPS.
So no accurate and/or frequent location tracking while an app is suspended or terminated. This just has to be accepted and you need to design your apps accordingly.
let locationManager = CLLocationManager()
locationManager.startMonitoringSignificantLocationChanges()
After returning a current location fix, the receiver generates update events only when a significant change in the user’s location is detected. It does not rely on the value in the distanceFilter property to generate events
If you start this service and your app is subsequently terminated, the system automatically relaunches the app into the background if a new event arrives. In such a case, the options dictionary passed to the application(:willFinishLaunchingWithOptions:) and application(:didFinishLaunchingWithOptions:) methods of your app delegate contains the key location to indicate that your app was launched because of a location event. Upon relaunch, you must still configure a location manager object and call this method to continue receiving location events. When you restart location services, the current event is delivered to your delegate immediately. In addition, the location property of your location manager object is populated with the most recent location object even before you start location services.
Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification. It should not expect notifications more frequently than once every five minutes. If the device is able to retrieve data from the network, the location manager is much more likely to deliver notifications in a timely manner.
Hope It helps

How monitor iPhone 's background process?

i wanna activate my app through the ibeacon device advertising, then my app monitor the advertise and will be active in background, but i don't know how long will it can be active. how monitor the background process? when the app's status is Active , until it's status is killed?
enter image description here
Apple provides support for iBeacons that will let you monitor beacons even if your app is in the background, or not running at all. Take a look at CLBeaconRegion and the Core Location manager. You set up one or more beacon regions and ask the system to begin monitoring them.
(You'll have to ask the user for permission to monitor beacon regions before it will work. Otherwise your API calls will fail.)

Swift Region Monitoring Local Notification trigger

I'm doing an app to trigger a local notification when a region is entered.
However, sometimes when the phone is locked, the notifications didn't pop up even I've been in the region area for a while. The notification popup will show only when the power/home button is pressed(phone still in locked mode).
In general, all seems to be working except that sometimes the notification will show only when power/home button is pressed to awake the phone although it is still locked.
Hope someone can enlighten me please! =)
According to the developer documentation. In core-location framework, two services can give you the current location information.
The standard location service is a configurable, general-purpose solution for getting location data and tracking location changes for the specified level of accuracy.
The significant-change location service delivers updates only when there has been a significant change in the device’s location, such as 500 meters or more.
You need to use standard location services to keep monitoring location in background
If your iOS app must keep monitoring location even while it’s in the background, use the standard location service and specify the location value of the UIBackgroundModes key to continue running in the background and receiving location updates. (In this situation, you should also make sure the location manager’s pausesLocationUpdatesAutomatically property is set to YES to help conserve power.)

Time spend around a beacon

What should be the correct approach to identify time spend around a beacon[not within a region] in background. I am able to do this when app is in foreground using didRangeBeacons and some business logic.I read on few forums that ranging does work when app has registered for location updates in background, but i am having no success. I have added the location updates key for UIBackgroundModes in plist.
I am using estimote beacons and their sdk.
I see two possible solutions here:
Listen for enter and exit region events, store the timestamps and then use them to calculate the time span on exit. If you define your region so that it encompasses only one beacon, monitoring the region will be equivalent to monitoring the beacon. The only thing to keep in mind is that iOS imposes a limit of 20 regions to be monitored at the same time - so this solution doesn't scale above 20 beacons.
Use ranging in the background. Apart from the UIBackgroundModes, you also need to start regular location services, i.e. startUpdatingLocation.
Beacon ranging delivers events normally while an app is running in the foreground. When your app is in the background, this service delivers events only when the location-updates background mode is enabled for the app and the standard location service is running.
(this is from CLLocationManager class reference, section "Using Location Services in the Background")
Note that ranging in the background will be draining the battery life more than usual, and Apple also requires justification for using the background modes. Unless there's some value for the user of your app coming from the background modes, they might choose to reject it. All in all, use the background ranging wisely! (:

CLLocationManager startMonitoringForRegion: not relaunching app after device restart

Ok, so I currently have an app where I register a geofence to be monitored using the CLLocationManager startMonitoringForRegion method. This works fine when the app is in the foreground and background.
I also have the appropriate plist values set:
UIBackgroundModes :{location}
UIRequiredDeviceCapabilities: {location-services}
What doesn't work
After a device restart, the app is not being relaunched. I can force this to happen if I set startMonitoringSignificantLocationChanges before entering background. But this method uses much more battery life and I don't need the location all the time, just whenever I break a geofence.
The docs for regions say:
In iOS, the regions you register with the location manager persist between launches of your application. If a region crossing occurs while your iOS app is not running, the system automatically wakes it up (or relaunches it) in the background so that it can process the event. When relaunched, all of the regions you configured previously are made available in the monitoredRegions property of any location manager objects you create.
Question
Is it possible (when using geofencing regions) to have the system restart my app AFTER a system reboot, WITHOUT using startMonitoringSignificantLocationChanges ?
Edit: I am targeting iOS6 & iOS7
Answering my own question here.
While you do need to use the startMonitoringSignificantLocationChanges to get the system to wake up the app after a device reboot. Nothing will wake up the app if the user has force closed it.
For my purposes, I did not need to set UIBackgroundModes to location. This setting is usually used for applications that only need fine-grained location updates (E.g. using startUpdatingLocation). Setting the background mode is not required when using startMonitoringSignificantLocationChanges.

Resources