请求访问相册的权限

61

我有一个设置视图,用户可以选择打开或关闭“导出到照片库”功能。

当用户首次打开它(而不是第一次拍照时),我希望应用程序要求用户允许访问照片库。

我在许多应用程序中看到了这种行为,但找不到实现的方法。

7个回答

96

我不确定是否有内置的方法来实现此功能,但一种简单的方法是使用ALAssetsLibrary从照片库中提取一些无意义的信息,当您启用该功能时。然后,您可以简单地将您提取的任何信息设置为null,并提示用户允许访问他们的照片。

例如,下面的代码只是获取相机胶卷中的照片数量,但已足以触发权限提示。

#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);
    }
}];

编辑:刚刚发现这个,以下是如何检查你的应用程序访问相册的授权状态。

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];
}

2
好的。谢谢你提供 error.code。我已经直接在 failureBlock 中添加了一个警告。 - Titouan de Bailleul
似乎很傻,你不能请求获取授权。有时我觉得仅仅请求访问照片真的很丑陋,因为你正在展示选择器... - Chris
这已经被弃用了。我曾经遇到过类似的问题,通过这个链接找到了解决方法。https://dev59.com/YlkS5IYBdhLWcg3wu4vL - Pradeep Reddy Kypa
这里提供了iOS 10及以上版本的解决方案:https://dev59.com/7mYr5IYBdhLWcg3wka9M#38398067 - Just Shadow

91

iOS 8自带照片框架,使用方法如下:

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:

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

来自文档的重要提示:

该方法始终立即返回。如果用户之前已授权或拒绝照片库访问权限,则在调用时执行处理程序块;否则,它会显示一个警报,并仅在用户响应警报后执行块。


9
由于某些人“我没有阅读文档”的原因,代码在后台线程上运行。因此,如果需要进行UI更改,请使用类似以下的包装方式:dispatch_async(dispatch_get_main_queue(), ^{ -- 这里是与UI相关的代码 -- }); - Alexandre G
太棒了!别忘了将Photos框架添加到你的目标中,并在Swift类顶部添加import Photos :) - judepereira
4
请注意,在iOS 10及更高版本中,您还需要在Info.plist文件中为NSPhotoLibraryUsageDescription键添加一个字符串,否则调用requestAuthorization(或任何依赖于照片授权的API)将会崩溃。 - rickster

11

自从iOS 10以来,我们还需要在info.plist文件中提供照片库使用说明,我在这里进行了描述。然后,只需使用此代码使警报出现每次我们需要:

- (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];
                }
            }];
        }
    });
}

此外,有一些常见情况下警报不会出现。为了避免抄袭,我想让你看看这个答案


4

Swift:

import AssetsLibrary

var status:ALAuthorizationStatus = ALAssetsLibrary.authorizationStatus()

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

4
用户在 iOS 6 上第一次尝试写入相机胶卷时,系统会自动请求权限。不需要添加额外的代码(在此之前,授权状态为 ALAuthorizationStatusNotDetermined)。
如果用户第一次拒绝了请求,你不能再次请求(据我所知)。用户必须手动更改应用程序特定设置中的设置->隐私->照片部分。
还有另一种情况,即用户由于其他限制(如家长控制)而无法授予权限,在这种情况下,状态为ALAuthorizationStatusRestricted。

有内置的iOS弹出窗口可以让你选择图片,对于这个我看到了对话框。当你采用ALAssets方法时,我就看不到对话框了。 - Amir Memon

2
#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;
    }

如果设计的目标是iOS8.0以下的版本,仍然非常适合使用。谢谢! - serge-k

0

iOS 9.2.1,Xcode 7.2.1,启用ARC

'ALAuthorizationStatus'已弃用:自iOS 9.0起首次弃用 - 请改用Photos框架中的PHAuthorizationStatus

请参阅此帖子以获取更新的解决方案:

确定是否设置了对照片库的访问权限 - PHPhotoLibrary(iOS 8)

关键要点:

  • 由于今天的事实,您很可能正在为iOS7.0+进行设计,因此您需要处理ALAuthorizationStatusPHAuthorizationStatus

最简单的方法是...

if ([PHPhotoLibrary class])
{
   //Use the Photos framework
}
else
{
   //Use the Asset Library framework
}
  • 你需要决定要使用哪个媒体集合作为你的源,这取决于你的应用程序将在哪个设备上运行以及它使用的操作系统版本。

  • 如果授权被用户拒绝,您可能希望引导用户到设置页面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接