Ask permission to access Camera Roll

Objective CIos

Objective C Problem Overview


I have a settings view where the user can choose switch on or off the feature 'Export to Camera Roll'

When the user switches it on for the first time (and not when he takes the first picture), I would like the app to ask him the permission to access the camera roll.

I've seen behavior in many app but can't find the way to do it.

Objective C Solutions


Solution 1 - Objective C

I'm not sure if there is some build in method for this, but an easy way would be to use ALAssetsLibrary to pull some meaningless bit of information from the photo library when you turn the feature on. Then you can simply nullify what ever info you pulled, and you will have prompted the user for access to their photos.

The following code for example does nothing more than get the number of photos in the camera roll, but will be enough to trigger the permission prompt.

#import <AssetsLibrary/AssetsLibrary.h>

ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];
[lib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    NSLog(@"%zd", [group numberOfAssets]);
} failureBlock:^(NSError *error) {
    if (error.code == ALAssetsLibraryAccessUserDeniedError) {
        NSLog(@"user denied access, code: %zd", error.code);
    } else {
        NSLog(@"Other error code: %zd", error.code);
    }
}];

EDIT: Just stumbled across this, below is how you can check the authorization status of your applications access to photo albums.

ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];

if (status != ALAuthorizationStatusAuthorized) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Attention" message:@"Please give this app permission to access your photo library in your settings app!" delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil, nil];
    [alert show];
}

Solution 2 - Objective C

Since iOS 8 with Photos framework use:

Swift 3.0:

PHPhotoLibrary.requestAuthorization { status in
    switch status {
    case .authorized:
        <#your code#>
    case .restricted:
        <#your code#>
    case .denied:
        <#your code#>
    default:
        // place for .notDetermined - in this callback status is already determined so should never get here
        break
    }
}

Objective-C:

[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
    switch (status) {
        case PHAuthorizationStatusAuthorized:
            <#your code#>
            break;
        case PHAuthorizationStatusRestricted:
            <#your code#>
            break;
        case PHAuthorizationStatusDenied:
            <#your code#>
            break;
        default:
            break;
    }
}];

Important note from documentation:

> This method always returns immediately. If the user has previously granted or denied photo library access permission, it executes the handler block when called; otherwise, it displays an alert and executes the block only after the user has responded to the alert.

Solution 3 - Objective C

Since iOS 10, we also need to provide the photo library usage description in the info.plist file, which I described there. And then just use this code to make alert appear every time we need:

- (void)requestAuthorizationWithRedirectionToSettings {
    dispatch_async(dispatch_get_main_queue(), ^{
        PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
        if (status == PHAuthorizationStatusAuthorized)
        {
            //We have permission. Do whatever is needed
        }
        else
        {
            //No permission. Trying to normally request it
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                if (status != PHAuthorizationStatusAuthorized)
                {
                    //User don't give us permission. Showing alert with redirection to settings
                    //Getting description string from info.plist file
                    NSString *accessDescription = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSPhotoLibraryUsageDescription"];
                    UIAlertController * alertController = [UIAlertController alertControllerWithTitle:accessDescription message:@"To give permissions tap on 'Change Settings' button" preferredStyle:UIAlertControllerStyleAlert];

                    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
                    [alertController addAction:cancelAction];

                    UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:@"Change Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
                    }];
                    [alertController addAction:settingsAction];

                    [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
                }
            }];
        }
    });
}

Also, there are some common cases when the alert doesn't appear. To avoid copying I would like you to take a look at this answer.

Solution 4 - Objective C

The first time the user tries to write to camera roll on ios 6 he/she is automatically asked for permission. You don't have to add extra code (before that the authorisationstatus is ALAuthorizationStatusNotDetermined ).

If the user denies the first time you cannot ask again (as far as I know). The user has to manually change that app specific setting in the settings->privacy-> photos section.

There is one other option and that is that it the user cannot give permission due other restrictions like parental control, in that case the status is ALAuthorizationStatusRestricted

Solution 5 - Objective C

Swift:

import AssetsLibrary
    
var status:ALAuthorizationStatus = ALAssetsLibrary.authorizationStatus()

if status != ALAuthorizationStatus.Authorized{
    println("User has not given authorization for the camera roll")
}

Solution 6 - Objective C

#import <AssetsLibrary/AssetsLibrary.h>

//////

ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
    switch (status) {
        case ALAuthorizationStatusRestricted:
        {
            //Tell user access to the photos are restricted
        }
            
            break;
        case ALAuthorizationStatusDenied:
        {
            // Tell user access has previously been denied
        }
            
            break;

        case ALAuthorizationStatusNotDetermined:
        case ALAuthorizationStatusAuthorized:
            
            // Try to show image picker
            myPicker = [[UIImagePickerController alloc] init];
            myPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            myPicker.delegate = self;
            [self presentViewController: myPicker animated:YES completion:NULL];
            break;

            
        default:
            break;
    }

Solution 7 - Objective C

iOS 9.2.1, Xcode 7.2.1, ARC enabled

> 'ALAuthorizationStatus' is deprecated: first deprecated in iOS 9.0 - > Use PHAuthorizationStatus in the Photos framework instead

Please see this post for an updated solution:

https://stackoverflow.com/q/26595343/4018041

Key notes:

  • Most likely you are designing for iOS7.0+ as of todays date, because of this fact you will need to handle both ALAuthorizationStatus and PHAuthorizationStatus.

The easiest is to do...

if ([PHPhotoLibrary class])
{
   //Use the Photos framework
}
else
{
   //Use the Asset Library framework
}
  • You will need to decide which media collection you want to use as your source, this is dictated by the device that your app. will run on and which version of OS it is using.

  • You might want to direct the user to settings if the authorization is denied by user.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTitouan de BailleulView Question on Stackoverflow
Solution 1 - Objective CMick MacCallumView Answer on Stackoverflow
Solution 2 - Objective CTomasz BąkView Answer on Stackoverflow
Solution 3 - Objective CJust ShadowView Answer on Stackoverflow
Solution 4 - Objective CTimoRozendalView Answer on Stackoverflow
Solution 5 - Objective CEsqarrouthView Answer on Stackoverflow
Solution 6 - Objective CDan AthertonView Answer on Stackoverflow
Solution 7 - Objective Cserge-kView Answer on Stackoverflow