在iOS 10中请求相机和媒体库权限 - Info.plist

126
我在应用程序中实现了一个WKWebView。在显示的网页上有一个文件输入,可以从照片中导入图像。每当我按下该输入并选择“拍摄照片”或“照片库”时,应用程序会突然崩溃,我认为这是因为应用程序缺少拍照或从库中导入的权限。如何在用户选择其中一种方法(拍照或照片库)时推送权限请求?我使用Swift 3.0与WKWebView。

1
@KiritModi您好,非常感谢。您能否将其发布为答案,以便我可以接受它。 - Alamri
FYI:UIImagePickerController文档从未更新以满足iOS10+的要求(我浏览了每一页,包括传统的Objective-C文档)。 - benc
10个回答

152

您也可以通过编程方式请求访问,我更喜欢这种方式,因为在大多数情况下,您需要知道是否已获得访问权限。

Swift 4 更新:

    //Camera
    AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in
        if response {
            //access granted
        } else {

        }
    }

    //Photos
    let photos = PHPhotoLibrary.authorizationStatus()
    if photos == .notDetermined {
        PHPhotoLibrary.requestAuthorization({status in
            if status == .authorized{
                ...
            } else {}
        })
    }

你没有分享代码,所以我不能确定这对你是否有用,但一般来说,将其作为最佳实践使用。


6
谢谢,这个答案对我有用!对于使用 Swift 4 的人来说,第一行应该改为:"AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in"。 - Kevin
1
谢谢你的回答。它完美地解决了我的问题。不过我还有一个疑问。当你运行requestAuthorization时,它是否会创建一种监听器来等待权限设置完成后再运行代码?起初我以为代码执行会在PHPhotoLibrary.authorizationStatus处停止,但在添加了一堆打印语句后,似乎它仍然继续执行了? - George Kendros
5
Swift 3:AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { response in。别忘了 import AVFoundation - iurii
2
感谢您的回答。如果没有它,我的应用程序将被拒绝,因为应用程序可以在未经允许的情况下访问照片库。 - Makalele
我们仍需要更新info.plist。 - user626776

134

嗨,我遇到了一个问题,就是无法让iPhone7用户设置照片库权限。当iPhone7用户在他们的手机上进入我的应用程序设置时,照片库选项会消失。我在我的info.plist中已经添加了Key:Value。奇怪的是,所有运行iOS 10的设备都能看到这个选项,除了iPhone7用户。例如,运行iOS 10的iPhone6可以看到此选项。我还有什么遗漏吗? - DevKyle
1
您不应该在这些值中包含PRODUCT_NAME,因为它已经包含在Apple消息中。例如,“App名称”想要访问您的照片。 - Elijah

94

信息属性列表(Info.plist)

有限的照片

<key>PHPhotoLibraryPreventAutomaticLimitedAccessAlert</key>
<true/>

相机

<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) camera description.</string>

照片

<key>NSPhotoLibraryUsageDescription</key>
<string>$(PRODUCT_NAME)photos description.</string>

保存照片

<key>NSPhotoLibraryAddUsageDescription</key>
<string>$(PRODUCT_NAME) photos add description.</string>

位置

<key> NSLocationWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) location description.</string>

Apple Music

<key>NSAppleMusicUsageDescription</key>
<string>$(PRODUCT_NAME) My description about why I need this capability</string>

日历

<key>NSCalendarsUsageDescription</key>
<string>$(PRODUCT_NAME) My description about why I need this capability</string>

Siri

<key>NSSiriUsageDescription</key>
<string>$(PRODUCT_NAME) My description about why I need this capability</string>

30

使用上述提到的plist设置和适当的访问器(AVCaptureDevice或PHPhotoLibrary),但如果确实需要,也要向用户发出警告并将他们发送到设置中,如下所示:

Swift 4.0和4.1

func proceedWithCameraAccess(identifier: String){
    // handler in .requestAccess is needed to process user's answer to our request
    AVCaptureDevice.requestAccess(for: .video) { success in
      if success { // if request is granted (success is true)
        DispatchQueue.main.async {
          self.performSegue(withIdentifier: identifier, sender: nil)
        }
      } else { // if request is denied (success is false)
        // Create Alert
        let alert = UIAlertController(title: "Camera", message: "Camera access is absolutely necessary to use this app", preferredStyle: .alert)

        // Add "OK" Button to alert, pressing it will bring you to the settings app
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
          UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!)
        }))
        // Show the alert with animation
        self.present(alert, animated: true)
      }
    }
  }

29

文件: Info.plist

对于相机(Camera)

<key>NSCameraUsageDescription</key>
<string>You can take photos to document your job.</string>

对于相片库,您会想要这个来允许应用程序用户浏览照片库。

<key>NSPhotoLibraryUsageDescription</key>
<string>You can select photos to attach to reports.</string>

22

Swift 5 最简单的方法是在info.plist文件中打开,并在Information Property list旁边选中+号。滚动下拉列表到隐私选项并选择Privacy Camera Usage Description以访问相机,或选择Privacy Photo Library Usage Description以访问照片库。在你做出选择后,在右侧填写字符串值,以包含在弹出框请求权限时向用户显示的文本。相机/照片库权限


12

要请求照片应用权限,您需要添加此代码(Swift 3)

PHPhotoLibrary.requestAuthorization({ 
       (newStatus) in 
         if newStatus ==  PHAuthorizationStatus.authorized { 
          /* do stuff here */ 
    } 
})

请不要忘记在info.plist中添加以下代码:<key>NSPhotoLibraryUsageDescription</key> <string>您可以选择照片附加到报告中。</string> - marcomoreira92
奇怪,我没有任何问题。我将这段代码添加到按钮上,然后使用我的iOS 10.3.1 iPhone 进行测试,它可以正常工作。 - marcomoreira92

10

我编写了一个扩展程序,考虑了所有可能的情况:

  • 如果允许访问,则会运行代码onAccessHasBeenGranted
  • 如果访问未确定,则将调用requestAuthorization(_:)
  • 如果用户拒绝了您的应用程序访问照片库,则会显示一个窗口,提供前往设置并允许访问的选项。在此窗口中,他将可以使用“取消”和“设置”按钮。当他按下“设置”按钮时,将打开您的应用程序设置。

用法示例:

PHPhotoLibrary.execute(controller: self, onAccessHasBeenGranted: {
    // access granted... 
})

扩展代码:

import Photos
import UIKit

public extension PHPhotoLibrary {
   
   static func execute(controller: UIViewController,
                       onAccessHasBeenGranted: @escaping () -> Void,
                       onAccessHasBeenDenied: (() -> Void)? = nil) {
      
      let onDeniedOrRestricted = onAccessHasBeenDenied ?? {
         let alert = UIAlertController(
            title: "We were unable to load your album groups. Sorry!",
            message: "You can enable access in Privacy Settings",
            preferredStyle: .alert)
         alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
         alert.addAction(UIAlertAction(title: "Settings", style: .default, handler: { _ in
            if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
               UIApplication.shared.open(settingsURL)
            }
         }))
         DispatchQueue.main.async {
            controller.present(alert, animated: true)
         }
      }

      let status = PHPhotoLibrary.authorizationStatus()
      switch status {
      case .notDetermined:
         onNotDetermined(onDeniedOrRestricted, onAccessHasBeenGranted)
      case .denied, .restricted:
         onDeniedOrRestricted()
      case .authorized:
         onAccessHasBeenGranted()
      @unknown default:
         fatalError("PHPhotoLibrary::execute - \"Unknown case\"")
      }
   }
   
}

private func onNotDetermined(_ onDeniedOrRestricted: @escaping (()->Void), _ onAuthorized: @escaping (()->Void)) {
   PHPhotoLibrary.requestAuthorization({ status in
      switch status {
      case .notDetermined:
         onNotDetermined(onDeniedOrRestricted, onAuthorized)
      case .denied, .restricted:
         onDeniedOrRestricted()
      case .authorized:
         onAuthorized()
      @unknown default:
         fatalError("PHPhotoLibrary::execute - \"Unknown case\"")
      }
   })
}

嘿@dronpop,你的解决方案很好,我已经使用了它,但是当我第一次安装应用程序并且不允许时,应用程序就会崩溃。你能告诉我如何解决吗? - Rana Ali Waseem
@RanaAliWaseem,我修复了崩溃问题。很可能你遇到了这个问题中描述的错误。 - dronpopdev
我遇到了崩溃问题。iyziliOSApp[3585:195420] [动画] +[UIView setAnimationsEnabled:] 在后台线程中被调用。在UIView或其子类上从后台线程执行任何操作都是不支持的,可能会导致意外和隐蔽的行为。跟踪=(然后,由于未捕获的异常 'NSInternalInconsistencyException' 终止应用程序,原因:在从主线程访问后台线程之后,不能从后台线程对布局引擎进行修改。 - Rana Ali Waseem
是的,正如你提到的问题,我也遇到了,但是该如何解决呢? - Rana Ali Waseem
@RanaAliWaseem 修复 - dronpopdev
请更新答案,有修复。DispatchQueue.main.async { onAccessHasBeenGranted() }DispatchQueue.main.async { onAuthorized() } - Rana Ali Waseem

1
在您的项目的 info.plist 中添加以下这些 keys,并提供所需的 string 消息以用于 Request Permissions

照片

Privacy - Photo Library Additions Usage Description

Privacy - Photo Library Usage Description

相机

Privacy - Camera Usage Description

最好详细检查所有受保护资源的苹果技术文档,包括 蓝牙、日历、相机和麦克风、联系人 Face ID、位置、照片等

https://developer.apple.com/documentation/technologies

前往上述链接并搜索:
属性列表键->包资源->信息属性列表->受保护的资源 在您的项目中实施的快速指南视频 谢谢!:)

0

Swift 5iOS 13中实现摄像头会话的绝佳方法

https://github.com/egzonpllana/CameraSession

Camera Session是一款iOS应用程序,旨在提供最简单的AVCaptureSession实现方式。

通过该应用程序,您可以找到以下相机会话的实现:

  • 使用本地相机拍照或录制视频。
  • 使用本地方法导入照片和视频。
  • 自定义选择资产(如照片和视频)的方式,可从库中选择一个或多个资产。
  • 自定义相机拍摄照片或视频,可以按住按钮记录,并提供选项。
  • 分离的相机权限请求。

自定义相机功能包括手电筒旋转相机选项。


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