allowsBackgroundLocationUpdates in CLLocationManager in iOS9
This new property is explained in the WWDC session "What's New in Core Location".
The default value is NO
if you link against iOS 9.
If your app uses location in the background (without showing the blue status bar) you have to set allowsBackgroundLocationUpdates
to YES
in addition to setting the background mode capability in Info.plist. Otherwise location updates are only delivered in foreground. The advantage is that you can now have location managers with background location updates and other location managers with only foreground location updates in the same app. You can also reset the value to NO
to change the behavior.
The documentation is pretty clear about it:
By default, this is NO for applications linked against iOS 9.0 or
later, regardless of minimum deployment target.With UIBackgroundModes set to include "location" in Info.plist, you
must also set this property to YES at runtime whenever calling
-startUpdatingLocation with the intent to continue in the background.Setting this property to YES when UIBackgroundModes does not include
"location" is a fatal error.Resetting this property to NO is equivalent to omitting "location"
from the UIBackgroundModes value. Access to location is still
permitted whenever the application is running (ie not suspended), and
has sufficient authorization (ie it has WhenInUse authorization and is
in use, or it has Always authorization). However, the app will still
be subject to the usual task suspension rules.See -requestWhenInUseAuthorization and -requestAlwaysAuthorization for
more details on possible authorization values.
CLLocationManager delegate not receiving location updates after application is suspended despite background location updates enabled
I had the same problem and the only way to prevent the app from beeing suspended was to set
locationManager.pausesLocationUpdatesAutomatically = false
When pausesLocationUpdatesAutomatically
is set to true
the systems puts the app in suspended state and will not receive location changes anymore until the user manually brings the app to foreground again.
NSUserDefaultsDidChangeNotification Doesn't Fire After Sending stopUpdatingLocation to CLLocationManager
Nevermind I figured it out.
The observation of the NSNotificationCenter
on the NSUserDefaultsDidChangeNotification
DOES NOT wake up the application. What was happening was the CLLocationManagerDelegate
protocol applied to my controller would "wake up" the application to do what it needed to the with CLLocation
s that were received. Upon this waking up, the observation of change to some user defaults in the NSNotificationCenter
would fire off my selector userDefaultsDidChange
.
As long as the CLLocationManager
was updating and there to alert the application it would allow the controller to call the designated selector. When the CLLocationManager was no longer updating the location the application would not be woken up and therefore not know any user defaults had changed until the app returned to the foreground.
I will update this answer if I come up with a better solution for this odd observation scenario.
How do I get a background location update every n minutes in my iOS application?
I found a solution to implement this with the help of the Apple Developer Forums:
- Specify
location background mode
- Create an
NSTimer
in the background withUIApplication:beginBackgroundTaskWithExpirationHandler:
- When
n
is smaller thanUIApplication:backgroundTimeRemaining
it will work just fine. Whenn
is larger, thelocation manager
should be enabled (and disabled) again before there is no time remaining to avoid the background task being killed.
This works because location is one of the three allowed types of background execution.
Note: I lost some time by testing this in the simulator where it doesn't work. However, it works fine on my phone.
CLLocationManager initialization
Sounds like you've coded the location stuff correctly. What you are missing (but have seen) is that the update most certainly does not happen instantaneously. You need to "gate" the rest of your UI's presentation (i.e. your webview) on the location information becoming available. There are a lot of ways to do this. A common tactic is to present a full-screen "HUD" or veil with some indicator to the user that the app is initializing or locating them (with an activity indicator, too, is always a nice touch.) Behind that (out of sight to the user) you can be waiting for the location result and then kickoff the appropriate UI update, and then drop the veil.
Any of that make sense or give you some ideas? I've done this plenty of times. Synchronizing async activities (like location updates) with real-time UI updates that make sense can be challenging, but isn't impossible. :-)
Related Topics
How to Chain Filters in Metal for iOS
How to Add Frameworks into the Swift Project
Get Apple Watch Heartratevariabilitysdnn Realtime
Default Uifont Size and Weight But Also Support Preferredfontfortextstyle
Conversion from String to Date in Swift Returns Nil
Xcode 8.3 Swift Version Error (Swift_Version) in Objective C Project
How to Schedule Mail Using Gmail API
Translate Just 4 Lines of Code from Objective C to Swift (Pointers)
Retrieve All Child Value to a Label in Table View Cell
Cannot Subscript a Value of [Anyobject]? with an Index of Type Int
How to Add Pagination in UItableview.
Can't Build an App for Distribution After Joining Existing Enterprise Developer Program