avoid using location while app is in the background - ios

I am using the google google places api or an iOS app and was wondering how to avoid having to ask for allowing "always on" location (NSLocationAlwaysUsageDescription). I do not think my app needs to access the location while in the background (is there a reason to?)
My google places api call is in a callback in viewDidLoad. Should I put it elsewhere in order to only ask for less intrusive permissions?
Thanks

There are 2 methods on CLLocationManager that request the location access. In order to request location access while the app is running you need to call requestWhenInUseAuthorization.
For example:
let locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
I'm assuming you were following this guide where it show location access like this:
locationManager.requestAlwaysAuthorization()
That method does request the access to always use your device's location, even while the app is in the background.
Hope that helps!

Related

xcode11 - Requesting Authorization for Location Services in ios 13

I would like to requests the user’s permission to use location services while using the app, Allow Once or Don't allow.
enter image description here
I only have code in ViewController.swift because I build the app with Ruby on Rails.
Which property list key I should use and how?
You need to call locationManager for this:
locationManager.requestAlwaysAuthorization()
To request "always" location access as well as:
locationManager.requestWhenInUseAuthorization()

Why is CLLocationManager giving me the wrong authorization status?

I'm building a running-based app in Swift that requests the user's location. For the sake of this question, let's just assume the app runs only on iOS 13+. Shortly after launching the app, we prompt the user for location access via the CLLocationManager method: requestWhenInUseAuthorization().
However, this app actually needs access to the user's location all the time, so only being able to request "When In Use" location access (per iOS 13) restricts the UX (other apps like Zenly and Snapchat do this as well since getting constant location updates improves the experience for their users and/or their friends).
After prompting for the location permission, we then grab the latest location authorization status. If that value is not equal to authorizedAlways (and it won't be unless the user changes that value in his/her Settings app), we present a new screen basically telling the user, "Since this is a running app, we really need your location all the time, so please go to settings and change the permission to 'Always' since we can't do it for you."
The issue I'm running into here is that when listening for updates on the CLLocationManagerDelegate method: locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus), sometimes that method provides the incorrect location authorization status.
Specifically, after a user selects "When In Use" and runs the app a few times, the value returned from that delegate method frequently reads as "Always," even though the Settings app on the phone still reflects the original, unchanged value ("When In Use").
Has anyone run into this before and, if so, do you have any ideas on what might cause it or how to fix it? Happy to provide more info on my setup. Thanks.

Request location updates permissions iOS

I currently have my app setup to request location services always, using [locationManager requestAlwaysAuthorization]; and NSLocationAlwaysUsageDescription
This works fine, however I would like to give the option of using location services only while using the app like in the screenshot below.
I have tried adding NSLocationWhenInUseUsageDescription however this overides he always request and only gives the alert for while in use, any ideas on who to give both options in settings?
First ask the user using your own dialog with two options - always / when using the app. Then call appropriate permission request according to the user's choice.
Either:
[locationManager requestAlwaysAuthorization];
or:
[locationManager requestWhenInUseAuthorization];
having both in plist is valid so that's not a problem. Depends on when you actually request it in the code.
It will be slightly tricky to maintain though, so a good code structure is crucial.
The built in iOS alert will only allows for one level of permission and it will only ask the user once. The assumption is that most apps will only need one or the other. In any case, if you want to have both options show up in the Settings, you must ask for Always permission.
More importantly though:
The Always setting is really only to be used by apps that require background location updates. So unless your app requires it, you shouldn't be asking for it. Also, using background location mode will cause your app to be more heavily scrutinized during the app review process.

Location Services enabled from native Settings App

When my app is launched it requests to use location services.
If a user selects 'Don't Allow' I prompt again letting them know that Location Services are required for the best experience and they can enable in the settings app.
If a user does not allow and still creates an account, the main screen will not fully function without the location feature part.
From this point, if I manually enable in the Settings app I'm still not getting the main page to pick up the current location.
How do I detect that location services have been enabled from the Settings App?
Is there a method I need to enforce again from the AppDelegate?
You can tell if location has been enabled for your app using CLLocationManager.AuthorizationStatus, which returns a member of the CLAuthorizationStatus enum. If location is disabled completely, your app won't be authorized, so you know everything you need to know.
let authorization = CLLocationManager.authorizationStatus()
if authorization == .AuthorizedWhenInUse || authorization == .Authorized {
...
}
If you request authorization using CLLocationManager and the user denies it, you can't cause the window to come up again.
From a UX point of view, be careful about nags as well. Communicate clearly that your app benefits from using location, but try to avoid browbeating the user about it.
See also how to determine when settings change on ios to have your app retry location access right after a user (hopefully) enabled it.

Android like permissions in iOS

In android, you define permissions for gps, sms sending, location , .., in the manifest file.
Is there anything similar in the iOS, so the user would know what capabilities of the phone some app uses before installation?
Or is the user warned during app use when some function wants to use something (e.g. gps, sms...)?
In iOS you declare your application requirements in its manifest-like Info.plist. But this information is not used to ask user permission, only for ensuring device compatibility.
Only Notifications and Location Services require user permission, which is automatically asked to the user the very first time your application attempt to use the corresponding API.
My guess is that many other permissions are already granted via the Apple Store license agreement, that the user must have accepted, unlike Android (I guess you can install an app without using the market isnt? which changes a lot from a legal point of view)
There's no such things as permissions on iPhone.
The only thing that user is warned about is when application uses his current location - then user is prompted with system alert and must explicitly allow or deny application's access to location data.
What concerns sms and email, they can be created and sent only via standard controllers so user will be aware of that anyway
on iOS you don't have to declare all necessary permissions in some specific file. You just use them. For example location
info.plist
//Privacy - Location When In Use Usage Description
<key>NSLocationUsageDescription</key>
<string>title</string>
//Privacy - Location Always and When In Use Usage Description
<key>NSLocationWhenInUseUsageDescription</key>
<string>description</string>
import CoreLocation
let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
}
[IDFA]

Resources