if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
    let imagePicker = UIImagePickerController()
    imagePicker.sourceType = .photoLibrary
    imagePicker.allowsEditing = true
    self.present(imagePicker, animated: true, completion: { })
}

即使我使用上述代码将"设置"中的照片访问权限设置为"从不",我仍然可以显示图像 Select 器并显示照片.在展示之前我会判断PHPhotoLibrary.authorizationStatus(),但我想知道这是预期的行为吗?

推荐答案

好吧,你可以把答案和 comments 拼凑起来,但是试着讲一个更完整的故事...


在iOS 11中,UIImagePickerController次运行是作为应用程序的一个单独进程进行的.这意味着:

  1. 你的应用程序无法看到用户的整个照片库——它只能对用户在图像 Select 器中 Select 的任何资源进行只读访问.
  2. 因为(1),你的应用不需要标准的隐私授权来访问照片库.用户明确 Select 在你的应用程序中使用的特定assets资源 (或多个),这意味着用户正在授予你的应用程序读取相关assets资源 的权限.

你可以看到更多关于这in the WWDC17 talk on PhotoKit的信息.

(顺便说一句,这款手机与iOS 9之后你看到的in the Contacts framework款手机相匹配;如果你显示联系人选取器,你的应用程序只会一次性删除用户选取的联系人的联系信息,而不需要对联系人数据库进行读/写访问,因此联系人选取器不需要特殊的隐私权限.)


PHPhotoLibrary and its authorization status reflect the global read/write permission for Photos access that users can control from Settings > Privacy. (That's the one where your Info.plist needs NSPhotoLibraryUsageDescription.) Any use of the PHPhotoLibrary API requires this permission, regardless of whether your app's use of that API is only for writing or only for reading. This has been true since PhotoKit was introduced in iOS 8.

如果您没有使用PHPhotoLibraryPHAsset等,iOS 11中新增了一些更窄的权限选项(不是Photos.framework API的一部分):

  • 如上所述,UIImagePickerController不需要全面隐私设置权限,因为每次使用都会授予所选特定assets资源 的一次性读取权限.
  • 如果只需要向照片库添加新资源,请使用UIImageWriteToSavedPhotosAlbumUISaveVideoAtPathToSavedPhotosAlbum.有了这些,你可以在你的信息中输入NSPhotoLibraryAddUsageDescription.plist——然后系统的隐私设置将向用户明确表示,他们没有授予您查看或修改现有assets资源 的权限,只是为了添加新assets资源 .

    如果用户授予"仅添加"权限,则它仅适用于那些UIKit函数-try 使用PHPhotoLibrary仍将提示(并需要Info.plist键)读/写访问权限.

    有关仅添加隐私设置的更多信息,请参见this part of the WWDC17 talk.

Swift相关问答推荐

Swift UI在视图中排序不同的 struct

如何在visionOS中进行购买?&# 39;购买(选项:)在visionOS中不可用

是否在字符串属性上搜索数组和子数组?

仅使用@MainActor注释类的部分时的并发问题

当计数大于索引时,索引超出范围崩溃

正在接收具有不完整数据错误的URL请求

如何在SWIFT Memory中处理对VAR数组的更新(对COW感到困惑)

物理主体未与 spritekit Swift 的网格图案上的纹理图像对齐

应该在ViewModel还是ViewController中使用"Task {}"?

仅当 boolean 为真时才实现方法(application:didReceiveRemoteNotification)

如何将视图添加到多行文本视图的末尾?

如何将变量添加到不属于可解码部分的 struct ?

临时添加到视图层次 struct 后,Weak view引用不会被释放

Swift 函数 vs 惰性变量 vs 计算(computed)属性 - 区别?

Swift 5.0 编译器无法导入使用 Swift 4.2.1 编译的模块

将if let与逻辑或运算符一起使用

Type 应该采用什么协议来让泛型函数将任何数字类型作为 Swift 中的参数?

Swift - 迭代 struct 对象时如何对其进行变异

在 Swift 中覆盖 UIScrollView 的委托属性(就像 UICollectionView 一样)

Swift performSegueWithIdentifier 不起作用