Location Access Request in iOS 11
It is not optional anymore.
Since iOS 11 has been released, if your application requests the location to be always on (locationManager.requestAlwaysAuthorization()
), the users will automatically be given all three options.
Unlike in previous iOS versions, all options have to be displayed to the user. That leads to: you have to add a key for both options.
Adapted from Apple's Article - Requesting Always Authorization:
You are required to include the
NSLocationWhenInUseUsageDescription
andNSLocationAlwaysAndWhenInUseUsageDescription
keys in your app's
Info.plist file. (If your app supports iOS 10 and earlier, the
NSLocationAlwaysUsageDescription
key is also required.) If those keys
are not present, authorization requests fail immediately.
Reference: What's New in Location Technologies Video Session.
Location permission issue iOS 11 and iOS 10
I figured out the issue by creating a quick stand alone app that only asked for permissions, I was given an error log that stated the keys I was using were wrong.
I had NSLocationAlwaysAndWhenInUsageDescription
instead of NSLocationAlwaysAndWhenInUseUsageDescription
which is odd because from the docs it states that NSLocationAlwaysAndWhenInUsageDescription
should be used. Switching to include the correct key fixed issue and now permissions works as expected for iOS 11 and 10.
Thanks for all the help.
Location access - App is not asking for user permission to access location - iOS 11
I have gone through the Apple documentation and found the solution for this question.
Apple has changed few guidelines to get user location.
Here is the Video Link: Apple- What's New in Location Technologies
Full code for location access in Swift & Objective-C both
Solution:
Now we need to add three Authentication Key into Plist:
- NSLocationAlwaysAndWhenInUseUsageDescription
- NSLocationWhenInUseUsageDescription
- NSLocationAlwaysUsageDescription
Plist will look like :
And Authentication message screen will look like:
Full code for location access
Location Services not working in iOS 11
It would appear that apple have added yet another privacy feature. The user is now able to override our requestAlwaysAuthorization
and downgrade it to requestWhenInUseAuthorization
- Which means as a developer we now have to supply both descriptions in the Info.plist
I found that they have added a new key NSLocationAlwaysAndWhenInUseUsageDescription
/*
* Either the NSLocationAlwaysAndWhenInUseUsageDescription key or both the
* NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription
* keys must be specified in your Info.plist; otherwise, this method will do
* nothing, as your app will be assumed not to support Always authorization.
*/
However, upon using this new key - the location service still didn't work, upon further searching I found this gem mixed in with all the extra debugging information:
This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain both NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription keys with string values explaining to the user how the app uses this data
Which directly contradicts the the comment that I found in the updated CLLocationManager.h
file. So I've created a radar.
Good news, if you follow the advice of the debugging console, IE. add both the new key NSLocationAlwaysAndWhenInUseUsageDescription
and one of the old keys NSLocationWhenInUseUsageDescription
, locations services will start to work again.
How to force 'always' location access in iOS app
A few observations about this flow where we request “when in use” first, and when that's granted, only then request “always” (as discussed in WWDC 2020 What's New in Location):
Make sure you run this on a device, not the simulator. You may not see the subsequent “upgrade ‘when-in-use’ to ‘always’” permission alert when using a simulator.
This feature was introduced in iOS 13.4. Make sure you are not attempting this on an earlier iOS 13 version. On those earlier versions, you won’t see the second alert to upgrade to “always”.
Make sure you don’t have a lingering
requestAlwaysAuthorization
elsewhere in your code-base that might have put the app in a “provisional always” state. Once in provisional state, you are locked into the provisional flow of 13.0.
I know it isn’t what you’re looking for, but for the sake of future readers, the alternative to the above is the simpler “provisional always” flow introduced in iOS 13.0 (outlined in WWDC 2019's What's New in Core Location). You just call requestAlwaysAuthorization
(never calling requestWhenInUseAuthorization
). Apple's intent here was to let the user better reason about what’s going on, showing the “when in use” alert while the app is in use and automatically showing the “always” upgrade alert when location services are used while the app isn't running.
iOS: make Location appear in the app settings without requesting for location authorization (Tile app example)
To reveal "Location" in the app settings without asking for permission first (Always
requires two-step opt-in), you need to call locationManager.requestLocation()
.
func scheduleLocationUpdates() {
if CLLocationManager.locationServicesEnabled() && CLLocationManager.authorizationStatus() == .authorizedAlways {
locationManager.startUpdatingLocation()
// hide full screen instruction (if shown)
} else {
if (UIDevice.current.systemVersion as NSString).floatValue >= 13.0 {
locationManager.requestLocation() // reveal "Location" in app settings (works on iOS 13 only)
// show full screen instruction how to provide "Always authorization"
} else {
if CLLocationManager.authorizationStatus() == .notDetermined {
locationManager.requestAlwaysAuthorization()
} else {
// show full screen instruction how to provide "Always authorization"
}
}
}
}
Function scheduleLocationUpdates()
should called in viewWillAppear
and after UIApplication.willEnterForegroundNotification
event (e.g. when the user comes back from Settings).
On iOS 12 "Location" will not appear in the app settings without asking for the permission first. But you can ask for Always
permission directly (without two steps), so this is not necessary.
Always Allow location does not appear after using requestAlwaysAuthorization()
iOS 13 Location Permissions
NSLocationAlwaysUsageDescription - deprecated.
This key is required if your iOS app uses APIs that access the user’s location at all times and deploys to targets earlier than iOS 11.
The Always Allow option, which grants an app “background” location
access, has been removed from the initial location permissions prompt.
Instead, users can select Keep Only While Using (aka “foreground”
permission) or select a new option,Allow Once. So how does an app then
get upgraded to “background” location permission? If the user
continues to use the app, iOS 13 will now automatically and
periodically prompt to upgrade location permissions from While Using
to Always Allow.
Related Topics
Errors Encountered While Discovering Extensions: Error Domain=Pluginkit Code=13 "Query Cancelled"
Tableview.Cellforrowatindexpath(Indexpath) Return Nil
How to Cast from Cftyperef to Axuielement in Swift
Where Do I Register a Valuetransformer in Swift
Nsmanagedobjectcontext's Propagatesdeletesatendofevent Set to False Causes Error on Save
Nscollectionview Selection Handling in Swift
How to Emit Items, One by One, from Collection with a Delay in Rxswift
Swift 3 Google Map Add Markers on Touch
Swiftui Text View Does Not Show Non-Displayable Characters
Cannot Assign to Value: 'self' Is Immutable
How to Get The Count of a Type Conforming to 'sequence'
Implement Protocol with Different Associated Type
Swiftycam Capture Session Is Not Running
Horizontal Scrolling in Spritekit (Vs. a Viewcontroller)
How to Detect Hash Changes in Wkwebview
Dynamic Dispatching Protocol Extension Doesn't Work Multiple Targets