确定是否设置了对照片库的访问 – PHPhotoLibrary

有了iOS 8中的新function,如果您在应用程序中使用相机,它将要求获得访问相机的权限,然后当您尝试重新拍摄照片时,它会要求获得访问照片库的权限。 下一次当我启动应用程序,我想检查相机和照片库是否有访问权限。

在这里输入图像说明

对于相机,我检查一下

if ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] == AVAuthorizationStatusDenied) { // do something } 

我正在寻找类似于这个照片库的东西。

选中+[PHPhotoLibrary authorizationStatus] – 如果未设置,则返回PHAuthorizationStatusNotDetermined 。 (然后您可以使用+requestAuthorization:在同一个类上请求访问。)

我知道这已经得到了回答,但只是扩大@Tim的答案,这里是你需要的代码(iOS 8及以上):

 PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; if (status == PHAuthorizationStatusAuthorized) { // Access has been granted. } else if (status == PHAuthorizationStatusDenied) { // Access has been denied. } else if (status == PHAuthorizationStatusNotDetermined) { // Access has not been determined. [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { if (status == PHAuthorizationStatusAuthorized) { // Access has been granted. } else { // Access has been denied. } }]; } else if (status == PHAuthorizationStatusRestricted) { // Restricted access - normally won't happen. } 

不要忘记#import <Photos/Photos.h>

如果您使用的是Swift 3.0或更高版本,则可以使用以下代码:

 // Get the current authorization state. let status = PHPhotoLibrary.authorizationStatus() if (status == PHAuthorizationStatus.authorized) { // Access has been granted. } else if (status == PHAuthorizationStatus.denied) { // Access has been denied. } else if (status == PHAuthorizationStatus.notDetermined) { // Access has not been determined. PHPhotoLibrary.requestAuthorization({ (newStatus) in if (newStatus == PHAuthorizationStatus.authorized) { } else { } }) } else if (status == PHAuthorizationStatus.restricted) { // Restricted access - normally won't happen. } 

不要忘记import Photos

就像forms一样, Swift 2.X版本:

 func checkPhotoLibraryPermission() { let status = PHPhotoLibrary.authorizationStatus() switch status { case .Authorized: //handle authorized status case .Denied, .Restricted : //handle denied status case .NotDetermined: // ask for permissions PHPhotoLibrary.requestAuthorization() { (status) -> Void in switch status { case .Authorized: // as above case .Denied, .Restricted: // as above case .NotDetermined: // won't happen but still } } } } 

“`

斯威夫特3

 func checkPhotoLibraryPermission() { let status = PHPhotoLibrary.authorizationStatus() switch status { case .authorized: //handle authorized status case .denied, .restricted : //handle denied status case .notDetermined: // ask for permissions PHPhotoLibrary.requestAuthorization() { status in switch status { case .authorized: // as above case .denied, .restricted: // as above case .notDetermined: // won't happen but still } } } } 

以下是iOS 8及以上版本(不含ALAssetLibrary)的完整指南:

首先,我们必须提供使用说明 ,现在它是PHPhotoLibrary所要求的。
要做到这一点,我们必须打开info.plist文件,find关键Privacy - Photo Library Usage Description并提供它的价值。 如果密钥不存在,只需创build它。
这里是一个图像例如:
在这里输入图像说明 还要确保info.plist文件中的密钥Bundle name值不为空。

现在描述时,我们可以通过调用requestAuthorization方法来请求授权:

 [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { switch (status) { case PHAuthorizationStatusAuthorized: NSLog(@"PHAuthorizationStatusAuthorized"); break; case PHAuthorizationStatusDenied: NSLog(@"PHAuthorizationStatusDenied"); break; case PHAuthorizationStatusNotDetermined: NSLog(@"PHAuthorizationStatusNotDetermined"); break; case PHAuthorizationStatusRestricted: NSLog(@"PHAuthorizationStatusRestricted"); break; } }]; 

注1: requestAuthorization实际上并不显示每个通话的警报。 它每隔一段时间显示一次,保存用户的答案并每次返回而不是再次显示警报。 但是,因为这不是我们所需要的,所以这是一个有用的代码,每次我们需要权限时都会显示警报(redirect到设置):

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

常见问题1:有些用户抱怨说,在info.plist文件中做了上述变动之后,app不显示警报。
解决scheme:为了进行testing,请尝试将项目文件中的Bundle Identifier更改为其他内容,然后清理并重新生成应用程序。 如果它开始工作,那么一切都很好,重新命名它。

常见问题2:当应用程序获取照片的权限时,有些特定情况下未更新提取结果(并且使用来自这些提取请求的图像的视图仍为空), 按文档中的承诺运行
其实它发生在我们使用这样的错误代码:

 - (void)viewDidLoad { if ([PHPhotoLibrary authorizationStatus] != PHAuthorizationStatusAuthorized) { //Reloading some view which needs photos [self reloadCollectionView]; // ... } else { [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { if (status == PHAuthorizationStatusAuthorized) [self reloadCollectionView]; // ... }]; } // ... } 

在这种情况下,如果用户拒绝授予viewDidLoad权限,然后跳转到设置,允许和跳回到应用程序,视图将不刷新,因为[self reloadCollectionView]和提取请求没有发送。
解决scheme:我们只需要调用[self reloadCollectionView]然后执行其他获取请求,然后请求授权,如下所示:

 - (void)viewDidLoad { //Reloading some view which needs photos [self reloadCollectionView]; if ([PHPhotoLibrary authorizationStatus] != PHAuthorizationStatusAuthorized) { // ... } 

我是这样做的:

 - (void)requestPermissions:(GalleryPermissions)block { PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; switch (status) { case PHAuthorizationStatusAuthorized: block(YES); break; case PHAuthorizationStatusNotDetermined: { [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus authorizationStatus) { if (authorizationStatus == PHAuthorizationStatusAuthorized) { block(YES); } else { block(NO); } }]; break; } default: block(NO); break; } } 

而且我根据成败来发送我需要做的块。

使用ALAssetsLibrary应该可以工作:

 ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus]; switch (status) { case ALAuthorizationStatusNotDetermined: { // not determined break; } case ALAuthorizationStatusRestricted: { // restricted break; } case ALAuthorizationStatusDenied: { // denied break; } case ALAuthorizationStatusAuthorized: { // authorized break; } default: { break; } } 

更新:SWIFT 3 IOS10


注意:导入AppDelegate.swift中的照片如下

// AppDelegate.swift

导入UIKit

导入照片


 func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. photoLibraryAvailabilityCheck() } //MARK:- PHOTO LIBRARY ACCESS CHECK func photoLibraryAvailabilityCheck() { if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.authorized { } else { PHPhotoLibrary.requestAuthorization(requestAuthorizationHandler) } } func requestAuthorizationHandler(status: PHAuthorizationStatus) { if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.authorized { } else { alertToEncouragePhotoLibraryAccessWhenApplicationStarts() } } //MARK:- CAMERA & GALLERY NOT ALLOWING ACCESS - ALERT func alertToEncourageCameraAccessWhenApplicationStarts() { //Camera not available - Alert let internetUnavailableAlertController = UIAlertController (title: "Camera Unavailable", message: "Please check to see if it is disconnected or in use by another application", preferredStyle: .alert) let settingsAction = UIAlertAction(title: "Settings", style: .destructive) { (_) -> Void in let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString) if let url = settingsUrl { DispatchQueue.main.async { UIApplication.shared.open(url as URL, options: [:], completionHandler: nil) //(url as URL) } } } let cancelAction = UIAlertAction(title: "Okay", style: .default, handler: nil) internetUnavailableAlertController .addAction(settingsAction) internetUnavailableAlertController .addAction(cancelAction) self.window?.rootViewController!.present(internetUnavailableAlertController , animated: true, completion: nil) } func alertToEncouragePhotoLibraryAccessWhenApplicationStarts() { //Photo Library not available - Alert let cameraUnavailableAlertController = UIAlertController (title: "Photo Library Unavailable", message: "Please check to see if device settings doesn't allow photo library access", preferredStyle: .alert) let settingsAction = UIAlertAction(title: "Settings", style: .destructive) { (_) -> Void in let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString) if let url = settingsUrl { UIApplication.shared.open(url as URL, options: [:], completionHandler: nil) } } let cancelAction = UIAlertAction(title: "Okay", style: .default, handler: nil) cameraUnavailableAlertController .addAction(settingsAction) cameraUnavailableAlertController .addAction(cancelAction) self.window?.rootViewController!.present(cameraUnavailableAlertController , animated: true, completion: nil) } 

答案从Alvin George更新

 I have a simple solution on swift 2.0 // // AppDelegate.swift // HoneyBadger // // Created by fingent on 14/08/15. // Copyright (c) 2015 fingent. All rights reserved. // import UIKit import Photos @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { self.window?.makeKeyAndVisible() self.window = UIWindow(frame: UIScreen.mainScreen().bounds) let storyboard = UIStoryboard(name: "Main", bundle: nil) let initialViewController = storyboard.instantiateViewControllerWithIdentifier("LoginPageID") self.window?.rootViewController = initialViewController self.window?.makeKeyAndVisible() return true } func applicationDidEnterBackground(application: UIApplication) { print("Application On background", terminator: "") } func applicationDidBecomeActive(application: UIApplication) { cameraAllowsAccessToApplicationCheck() photoLibraryAvailabilityCheck() } //MARK:- CAMERA ACCESS CHECK func cameraAllowsAccessToApplicationCheck() { let authorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) switch authorizationStatus { case .NotDetermined: // permission dialog not yet presented, request authorization AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted:Bool) -> Void in if granted { print("access granted", terminator: "") } else { print("access denied", terminator: "") } }) case .Authorized: print("Access authorized", terminator: "") case .Denied, .Restricted: alertToEncourageCameraAccessWhenApplicationStarts() default: print("DO NOTHING", terminator: "") } } //MARK:- PHOTO LIBRARY ACCESS CHECK func photoLibraryAvailabilityCheck() { if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.Authorized { } else { PHPhotoLibrary.requestAuthorization(requestAuthorizationHandler) } } func requestAuthorizationHandler(status: PHAuthorizationStatus) { if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.Authorized { } else { alertToEncouragePhotoLibraryAccessWhenApplicationStarts() } } //MARK:- CAMERA & GALLERY NOT ALLOWING ACCESS - ALERT func alertToEncourageCameraAccessWhenApplicationStarts() { //Camera not available - Alert let internetUnavailableAlertController = UIAlertController (title: "Camera Unavailable", message: "Please check to see if it is disconnected or in use by another application", preferredStyle: .Alert) let settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString) if let url = settingsUrl { dispatch_async(dispatch_get_main_queue()) { UIApplication.sharedApplication().openURL(url) } } } let cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil) internetUnavailableAlertController .addAction(settingsAction) internetUnavailableAlertController .addAction(cancelAction) self.window?.rootViewController!.presentViewController(internetUnavailableAlertController , animated: true, completion: nil) } func alertToEncouragePhotoLibraryAccessWhenApplicationStarts() { //Photo Library not available - Alert let cameraUnavailableAlertController = UIAlertController (title: "Photo Library Unavailable", message: "Please check to see if device settings doesn't allow photo library access", preferredStyle: .Alert) let settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString) if let url = settingsUrl { UIApplication.sharedApplication().openURL(url) } } let cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil) cameraUnavailableAlertController .addAction(settingsAction) cameraUnavailableAlertController .addAction(cancelAction) self.window?.rootViewController!.presentViewController(cameraUnavailableAlertController , animated: true, completion: nil) } } 

这是我通常使用的一个小而简单的片段。

 - (void)requestPhotoAuthorization:(void (^)(BOOL granted))granted { void (^handler)(PHAuthorizationStatus) = ^(PHAuthorizationStatus status) { if (status == PHAuthorizationStatusAuthorized) granted(YES); else if (status == PHAuthorizationStatusNotDetermined) [PHPhotoLibrary requestAuthorization:handler]; else granted(NO); }; handler([PHPhotoLibrary authorizationStatus]); } 

Swift 2.0+

基于这里的答案组合,我为自己创build了一个解决scheme。 此方法只检查是否没有权限。

我们有一个方法pickVideo()需要访问照片。 如果不是,请授权。

如果没有给出权限, pickVideo()将不会被调用,并且用户不能select一个video。

只要用户没有完全访问照片,您就可以避免让他们挑选或崩溃您的应用程序。

  // Method that requires access to photos func pickVideo(){ // Check for permission if PHPhotoLibrary.authorizationStatus() != .Authorized{ // If there is no permission for photos, ask for it PHPhotoLibrary.requestAuthorization(requestAuthorizationHandler) return } //... pick video code here... } func requestAuthorizationHandler(status: PHAuthorizationStatus){ if PHPhotoLibrary.authorizationStatus() == .Authorized{ // The user did authorize, so, pickVideo may be opened // Ensure pickVideo is called from the main thread to avoid GUI problems dispatch_async(dispatch_get_main_queue()) { pickVideo() } } else { // Show Message to give permission in Settings let alertController = UIAlertController(title: "Error", message: "Enable photo permissions in settings", preferredStyle: .Alert) let settingsAction = UIAlertAction(title: "Settings", style: .Default) { (alertAction) in if let appSettings = NSURL(string: UIApplicationOpenSettingsURLString) { UIApplication.sharedApplication().openURL(appSettings) } } alertController.addAction(settingsAction) // If user cancels, do nothing, next time Pick Video is called, they will be asked again to give permission let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil) alertController.addAction(cancelAction) // Run GUI stuff on main thread dispatch_async(dispatch_get_main_queue()) { self.presentViewController(alertController, animated: true, completion: nil) } } }