6

I am using a UIImagePicker to present the users photos so that the user can choose an image to be used in my app.

My problem is that on the first time a user opens the image picker they are presented with a prompt saying: '"my App" Would like to Access your Photos' with two options, Don't allow and OK.

My requirement is that when the user clicks Don't Allow, the Image picker gets dismissed.

Is there a way to detect that the user has chosen Don't allow?

Currently it leaves the user in an ugly blank modal view. If the user opens the image picker again they are show the nice apple provided message that says "this app does not have access to your photos etc etc"

here is how I use the image picker:

self.imagePickerController = [[UIImagePickerController alloc] init];
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:self.imagePickerController animated:YES];
Robert Wagstaff
  • 2,664
  • 1
  • 27
  • 40
  • I suppose I could run a background thread that continually checks [ALAssetsLibrary authorizationStatus] every 0.25 second and then fires a notification when it changes from ALAuthorizationStatusNotDetermined to something else. This kind of hackery won't fly on my current project tho. Does anyone have a better way to detect that the authorization status has changed? – Robert Wagstaff Feb 07 '13 at 03:58
  • How to detect user has clicked Don't Allow access to ***Camera*** button? – Itachi Sep 30 '14 at 05:51

3 Answers3

13

Got it!

if ([ALAssetsLibrary authorizationStatus] == ALAuthorizationStatusNotDetermined) {
    ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        if (*stop) {
            // INSERT CODE TO PERFORM WHEN USER TAPS OK eg. :
            return;
        }
        *stop = TRUE;
    } failureBlock:^(NSError *error) {
        // INSERT CODE TO PERFORM WHEN USER TAPS DONT ALLOW, eg. :
        self.imagePickerController dismissViewControllerAnimated:YES completion:nil];
    }];
}
Robert Wagstaff
  • 2,664
  • 1
  • 27
  • 40
  • Almost. Your `if` condition should also check for `ALAuthorizationStatusAuthorized`. This way you perform the group enumeration when the user has already granted permission. You should also have an `else` part to inform the user that they can't access the photos. – rmaddy Feb 07 '13 at 15:23
  • disagree sorry. In my case I always want to show an ImagePicker, even if they are not authorised or not yet determined to be authorised. I call the above code after I have displayed my image picker, my requirement is to just close the image picker. The next time the image picker is displayed it tells the user they have disallow the photo privacy settings. – Robert Wagstaff Feb 10 '13 at 03:49
  • 1
    No problem. Your requirements are different than I thought. Obviously you know what you need better than I do. :) – rmaddy Feb 10 '13 at 04:10
2

Use ALAssetsLibrary authorizationStatus. There is a specific return value that indicates your app has been denied.

Doing a search here on that method will reveal some sample code for properly handling the various authorization states.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • thanks, this is a great start to answering the question, but I need to know when they have tapped the Don't Allow button so I can respond, not just know the current authorization status – Robert Wagstaff Feb 07 '13 at 02:51
  • 4
    It doesn't work quite like that. If you determine that the `authorizationStatus` is either `ALAuthorizationStatusAuthorized` or `ALAuthorizationStatusNotDetermined`, then you proceed to try to access an asset. If the status is not determined then the user sees the alert. If the user chooses "Deny" then the error block is called. If the user chooses "Allow" (or the status was already "authorized", then the completion block is called. So you always check the status. And you always implement the failure blocks for the various asset enumeration and access methods. – rmaddy Feb 07 '13 at 03:06
0

I had a similar problem. You can look at my code below if it can help anyone in future who may have similar problem.I have an IBAction which helps me load the images. I struggled with this method for 4-5 hours.

(IBAction)loadImages:(id)sender {
    ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];

    if (status == AVAuthorizationStatusAuthorized || status == AVAuthorizationStatusNotDetermined) {

        ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];
        [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
            if (*stop) {
                self.imagePicker = [[UIImagePickerController alloc] init];
                self.imagePicker.delegate = self;
                self.imagePicker.allowsEditing = NO;
                self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                imagePicker.mediaTypes =[UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
                [self presentViewController:imagePicker animated:YES completion:^{
                    //TODO
                }];
                return;
            }
            *stop = TRUE;
        } failureBlock:^(NSError *error) {
            [imagePicker dismissViewControllerAnimated:YES completion:nil];
        }];
    }

    if (status == AVAuthorizationStatusDenied || status == AVAuthorizationStatusRestricted) {
        UIAlertView *cameraAlert = [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"Camera Access Required", nil) message:NSLocalizedString(@"Please allow us to access your camera roll in your device Settings.", nil) delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil, nil];
        [cameraAlert show];
    }
}
Vadim Martynov
  • 8,602
  • 5
  • 31
  • 43
Milan Shah
  • 205
  • 1
  • 3
  • 15