How to refresh permission after getting access to it - ios

I need to access users Photos, for this I ask for permission. There are possible outcomes :
Permission granted : In this condition application resumes it normal functioning.
Permission Denied : In this case application shows an alert wherein user has option to goToSettings or to just ignore it. If user selects goToSettings and provides access to photos and comes back to application then it still says that permission is not granted. Permissions are only refreshed when I restart my application.
My Question: How to refresh the application's permission settings without restarting my application. Similar problem to my question is posted here.
Edit:
My application is a navigation controller based application and I check for access in my controller's viewDidLoad. I just tried if request permissions are refreshed if I pop and push the controller again. No luck, the results where same - it still said permission denied.
Edit 2 : Code to check for permissions
func requestAccess() -> Void {
PHPhotoLibrary.requestAuthorization {
status in
switch(status) {
case .notDetermined, .denied :
// perform relavent action
break
case .authorized , .restricted :
// perform relavent action
break
}
}
}

iOS kills your app when you changed privacy settings. And after next tap on app's icon your app is started from scratch. application:didFinishLaunching is called and so on. So you don't need to update permissions.

In your AppDelegate you could have logic in applicationDidBecomeActive to re-query the permission store for your updated permissions.
In your viewDidLoad for the view you check permissions on you could observe the notification like so;
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(yourClass.applicationDidBecomeActive(_:)),
name: UIApplicationDidBecomeActiveNotification,
object: nil)

The code below is Objective-C.
I think you can do this when user tapping a button or something:
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusNotDetermined) {
// ask for authorization
[PHPhotoLibrary requestAuthorization...
} else if (status == PHAuthorizationStatusAuthorized) {
// continue accessing photos
} else {
// access denied, go to settings if you want
}

Related

MPMediaPickerControllerDelegate Permission Check Swift

I have the following code in my project to select audio files through 'MPMediaPickerControllerDelegate'. When run the below code, for the first time the user is prompted to grant permission. If the user declines the loading the picker would silently fail.
Is there a way to prompt user to grant permission if they return after declining at first?
I was wondering if it's a bug. Is there any way we can detect the permission of the MPMediaPickerControllerDelegate so that we can decide to show the audio or not.
Below is my code:
let myMediaPickerVC = MPMediaPickerController(mediaTypes: MPMediaType.anyAudio)
myMediaPickerVC.allowsPickingMultipleItems = false
myMediaPickerVC.delegate = self
present(myMediaPickerVC, animated: true, completion: nil)
You have to first check the authorization permission, then run your code if authorizationStatus permission is authorized. If it is not notDetermined then ask for permission. If it denied then show Alert asking user to go to Settings and enable this permission.
MPMediaLibrary.requestAuthorization({(newPermissionStatus: MPMediaLibraryAuthorizationStatus) in
// This code will be called after the user allows or denies your app permission.
switch (permissionStatus) {
case MPMediaLibraryAuthorizationStatus.authorized:
print("permission status is authorized")
case MPMediaLibraryAuthorizationStatus.notDetermined:
print("permission status is not determined")
MPMediaLibrary.requestAuthorization(MPMediaLibraryAuthorizationStatus -> permissionStatus)
case MPMediaLibraryAuthorizationStatus.denied:
print("permission status is denied")
case MPMediaLibraryAuthorizationStatus.restricted:
print("permission status is restricted")
}
})

PhotoLibrary access .notDetermined, when denying then enabling

If I deny at first, then go to settings and allow in settings, in both cases the status is notDetermined, instead of denied then authorized.
Why is that happening?
It doesn't save the image when i click "Don't allow", but status becomes .notDetermined not .denied .
It saves, after i go to settings->Photos, uncheck "Never" and check "Add Photos Only". But the status stays .notDetermined, does not become .authorized
func save(){
guard let image = imageView.image else {return}
UIImageWriteToSavedPhotosAlbum(image, self, nil, nil)
let status = PHPhotoLibrary.authorizationStatus()
switch status {
case .authorized:
print("authorized")
return
case .notDetermined:
print("not determined")
case .denied, .restricted:
print("denied or restricted")
//please go to settings and allow access
promptToSettings()
}
}
I am asking permission to save an image to photo library.
When the first time the user tries to save, he gets asked: "App would like to add to Photos" "Don't Allow" "Ok"
If the user denied then tried to save again,i want to check and if the status is .denied, prompt the user to go to settings and allow.
But the code goes to .notDetermined block when the user does not give access the first time. It stays .notDetermined even after in settings the user allows access.
I downloaded your code and ran it. I was able to experience whatever you said. It always returned Not Determined status.
I did a little bit analysis on your code further. Please find my observation below.
In your current code, "PHPhotoLibrary.requestAuthorization" method is not called before reading the authorization status using "PHPhotoLibrary.authorizationStatus" method.
Though "UIImageWriteToSavedPhotosAlbum" in Save method triggers a Photos app permission pop up, it does not help here completely.
So, I called "askForAccessAgain" method in ViewDidLoad method in order to get the permission using "PHPhotoLibrary.requestAuthorization" method first.
After that, whenever i saved the photos using Save method, it returned the correct status, let it be either "Authorized" or "Denied".
If I choose "Never" and "Allow Photos Only", it returned "Denied or Restricted" status. When "Read and Write" is chosen, "authorized" is returned.
So, it looks like, We need to call "PHPhotoLibrary.requestAuthorization" method to get the permission first instead of relying on other Photo access methods ( like UIImageWriteToSavedPhotosAlbum) for getting the permission. Only then, correct status is returned by "PHPhotoLibrary.authorizationStatus".
One more addition info:
App Permissions are retained even after deleting the app and reinstalling it. Just take a look on this as well. It might help you in troubleshooting similar issues in future.
iPad remembering camera permissions after delete—how to clear?
Please let me know if this has resolved your issues.

Does AVCaptureDevice.requestAccessForMediaType only work for undetermined authorization status?

I am checking if an app has permission to use the camera with:
let authStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
If the authorization status is denied (perhaps the user accidentally did not allow permission the first time when asked), is it possible to show the permission request again?
If authorization has been denied, I am attempting to request permission with:
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo,
completionHandler: { (granted:Bool) -> Void in
if granted {
dispatch_async(dispatch_get_main_queue()) {
self.shootPhoto(UIButton())
}
}
})
But no request for permission is dialog is presented. Does requestAccessForMediaType only work if the authorization status is undetermined?
No this is not possible. In this situation, you will need to explain to the user how to go into Settings and change the permissions.

Checking permissions in Swift 2.0

No matter where I add code to check permissions for things like camera/mic/photos, the popup confirmation always kills my app or sends me back a few view controllers.
An example is as follows.
I have few view controllers in (part way through a registration process) when I have a page that deals with the permissions. Users tap a button to deal with the camera permission which uses the following code.
if AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) != AVAuthorizationStatus.Authorized {
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted :Bool) -> Void in
if granted == true {
// do something
} else {
// determine whether not determined, denied etc and do something else
}
});
}
However as soon as the iOS confirmation pops up, it throws the app back 2 view controllers. In other cases (e.g. on a viewDidLoad) permission requests kill the app as soon as the choice is made.
Any ideas what am I missing in my setup or how to prevent this behaviour?
Thanks.
I think you misunderstood my comment, what I did meant was
if AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) != AVAuthorizationStatus.Authorized { // here you are checking if it's not authorized i..e it's denied, NotDetermined or Restricted
....
}
else if if AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) == AVAuthorizationStatus.Authorized
// do the something in case it's autorized
I'm listing keys here -
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to the photo library.</string>
<key>NSCameraUsageDescription</key>
<string>This app requires access to the camera.</string>

Handling Built In iOS Permission Dialogs

When loading my view controller for the first time, the user is prompted with a built in iOS permissions message: "Allow "appName" to access your location while you use the app?"
is there a way I can pause the app until the user either selects Don't Allow or Allow?
After the user selects Allow Or Dont Allow, I can handle it by checking the value like so:
//INSIDE OF ViewDidAppear
if(authstate != CLAuthorizationStatus.Denied)
{
// do something
}
else if (authstate == CLAuthorizationStatus.AuthorizedWhenInUse)
{
// do something
}
Right now the code steps through the if statement even though the iOS permissions dialog is still showing on the screen. Therefore, I want to pause it until the user selects Allow or Dont Allow. Then after the user selects either Allow or Dont Allow, continue onto the if statement
no. the permission request happens asynchronously. you have to implement the CLLocationManagerDelegates method
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
// check the status
}
that gets called after the user answered the permission dialogue.

Resources