by whom presenting iOS's privacy dialog - ios

if my app is requesting GPS location, there's a dialog shown to user asking permission.
and my app also check the authorization, if the user not allow use location service, I will also prompt a dialog to notify user to do the settings.
now the question is, when I first launch the app, the user haven't allow yet, but the check code also executed, so it will show a dialog beneath the system privacy dialog. now it has two scenarios:
user click Don't allow, the system dialog dismissed, and my dialog appear, say app don't have permission to locate, that's right.
but if user click Allow, my will also shown because it's right there, beneath the system's dialog.
I now can only put the two part code different place, but is there a better or more reasonable way to solve this? which is, if user clicked allow, I will know.
some thoughts:
1. if I can know there's a system's privacy dialog been presenting (not a better way, because I just want to know location privacy
2. how to know the location privacy dialog's presenter, so I will use it to check if it has presenting a dialog
3. how to know what action did user do after the privacy dialog is shown can user clicked to dismiss.

Implement didChangeAuthorizationStatus delegate method from location manager and check authorization there
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .NotDetermined:
// show alert here
break
case .AuthorizedWhenInUse:
break
case .AuthorizedAlways:
break
case .Restricted:
// show alert here
break
case .Denied:
// show alert here
break
default:
break
}
}

Related

iOS 14 Camera and Photo Permission Flow

Hey folks I’m having trouble wrapping my head around the correct way to handle camera and photo permissions in iOS 14 and what the appropriate flow is. It feels like I’ve overlooked something simple though not sure what exactly.
For context, the user is not prompted with a request for camera or photos permission until they’ve tapped the respective button for the first time. The app includes a custom photo picker that displays available photos to select based on previous photo associations (i.e. a photo can only belong to one product at a time and wouldn’t show as “available” in the custom picker unless it wasn’t associated with a product).
If the user taps the camera button, accepts the permission request, takes a photo and taps “Use Photo”, the UIImagePickerController is dismissed and an alert is presented that asks the user to Select Photos..., Allow Access to All Photos, or Don't Allow. If the user chooses to allow access to all photos there is no problem, the photo is saved using PhotoKit APIs and the UI updated to showcase the thumbnail of the photo just taken. Everything works as expected.
If the user chooses to select certain photos, a PHPickerViewController is presented and does not include the photo just taken with the camera since it has yet to be saved. This makes sense though leaves me to wonder how do I save the image and allow the user who chooses limited photo access to select that newly taken photo? Perhaps this isn’t possible.
There are additional hiccups I’m seeing with the flow such that if the user then taps “Done” to dismiss the PHPickerViewController without making any selections after electing limited access, the app is able to save the image taken from the camera using PhotoKit APIs and the UI updated to showcase the thumbnail (this seems incorrect though I may be misunderstanding something simple).
In the same run of the app, if the user taps the photos button, they are presented with the custom picker and logging shows a fetch count of 0 photos available to the user. This makes sense since there were no selections made. However, on the next app run, if the user taps the photo button, they are presented with the alert to Select More Photos... or Keep Current Selection. If they elect to add to the photo selection, they are presented with a PHPickerViewController that shows the photo previously taken with the camera as a user selection and a fetch count of 1 for available photos. Additionally, with limited access mode, attempts to generate thumbnails have produced errors in the Xcode console indicating that an operation is not permitted or a failure to decode an asset. I've seen the following in the console: [Thumbnails] Could not open PLPositionalImageTable...
It feels like I’m missing something basic in this process of taking, saving, and using photos (even a limited selection of them) for iOS 14. Does anyone have experience with this or a resource beyond recent WWDC videos that may shed light on what I’m missing? Appreciate the help in advance.
Also fwiw I would love to rely on PHPickerViewController rather than the custom picker however unless I’m missing something, PHPickerViewController doesn’t allow us to provide a subset of photos to display and only that subset even if the subset is limited by the user selection in limited access mode. If I’m misguided I’d appreciate direction there as well. Thanks all!
The issue is not clear how you are using a custom image picker. and how you are capturing the image. If you capturing the image using a native image picker as it looks like. Picker delegate will give image without saving in photos. But it looks like you are trying to save the image first in photos and trying to access it from there. alternatively, You can use the image once you consume the provided image.
Photos permissions are prompted when the user is trying to access photos the first time. and photo selection is asked when the user trying to access the photo the first time after the app launch.
If you have case when user is selected "Limited selection" access. You can check for current photos library selection and alert user based on selection.
switch PHPhotoLibrary.authorizationStatus() {
case .notDetermined:
PHPhotoLibrary.requestAuthorization { [weak self] status in
switch status {
case .authorized:
self?.initPhotoLibrary()
case .limited:
// Alert user to select all photos
default:
self?.handleDeniedAlbumsAuthorization()
}
}
case .authorized:
self.initPhotoLibrary()
case .limited:
// Alert user to select all photos
case .restricted: fallthrough
case .denied:
handleDeniedAlbumsAuthorization()
}
There are additional hiccups
This is based on custom image picker logic, this should not be the case for native image picker.
Check apple documentation for PHPicker:
https://developer.apple.com/documentation/photokit/delivering_a_great_privacy_experience_in_your_photos_app
if AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) == AVAuthorizationStatus.authorized {
// if de user accept before
}
else
{
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (response :Bool) -> Void in
if response == true {
// User accept the permission
}
else {
// User declined the permission
}
});
}

Determine which button was tapped on system alert

I am presenting SKStoreReviewController.requestReview() and I want to have a boolean in UserDefaults which I would make true in case the user taps on Cancel.
Is there a way to determine if cancel was tapped considering this is a OS alert?
There isn’t a way to access which button was selected. I’m curious why you would you need this functionality? The OS will decide if the user should be shown the alert depending on a few factors including when the user last left a review or canceled.
Apple Developer Site:
https://developer.apple.com/documentation/storekit/skstorereviewcontroller/2851536-requestreview
Although you should call this method when it makes sense in the user
experience flow of your app, the actual display of a rating/review
request view is governed by App Store policy. Because this method may
or may not present an alert, it's not appropriate to call it in
response to a button tap or other user action.

IOS : How to handle "Cancel" button on Alert pop up, when Location services turned off

I am using location services in my application. When I run the application with location services OFF, It gives me a pop up saying "Turn on Location services to allow to determine your location" with two buttons "Settings" and "Cancel".
If I tap on Settings, it takes me to Settings app. But If I tap on "Cancel" nothing happens.
I want to detect the touch event on "Cancel" button. Is there any way to do that.
You don't have direct access to that event, sadly.

CLLocationManager requestAlwaysAuthorization not showing alert second time

Calling [CLLocationManager requestAlwaysAuthorization] doesnt show the alert after the user selected "Dont Allow" option for the first time. Is there anyway to force the app to show the alert again when needed?
Apple won't display your alert if the user has already pressed Don't Allow.
On the other hand, you can check the authorization status and show a pop telling the user to go to settings and changing it manually.
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusNotDetermined) {
// Show request
}
Regards

Switch on GPS automatically without user interaction

Is it possible to switch on the GPS programmatically, without user interaction?
No it is not possible to turn on GPS without user interaction.
The first time you attempt to switch it on, there will be an Alert. After user has enabled it , then you can switch on/off at will.
see CLLocationManager
https://developer.apple.com/library/mac/#documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html

Resources