if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: { })
}
即使我用上面的代码将"设置"中对照片的访问设置为"从不",我仍然可以呈现图像选择器并显示照片。在显示PHPhotoLibrary.authorizationStatus()
之前,我会检查它,但我想知道这是预期的行为吗?
好吧,你可以从答案和评论中拼凑出来,但为了讲述一个更完整的故事。。。
在iOS 11中,UIImagePickerController
作为独立于应用程序的进程运行。这意味着:
- 您的应用程序无法查看用户的整个照片库——它只能对用户在图像选择器中选择的任何资产进行只读访问
- 由于(1),您的应用程序访问照片库不需要标准的隐私授权。用户明确选择一个(或多个)特定资产用于您的应用程序,这意味着用户授予您的应用读取有问题资产的权限
您可以在PhotoKit上的WWDC17演讲中看到更多关于此的信息。
(顺便说一句,这个模型与你在iOS 9以来在Contacts框架中看到的相匹配;如果你显示联系人选择器,你的应用程序只会一次性删除用户选择的联系人的联系人信息,而不会对联系人数据库进行读写访问,因此联系人选择器不需要特殊的隐私权限。)
PHPhotoLibrary
及其授权状态反映了用户可以从"设置">"隐私"控制的照片访问的全局读/写权限。(这是您的Info.plist需要NSPhotoLibraryUsageDescription
的地方。)任何对PHPhotoLibrary
API的使用都需要此权限,无论您的应用程序对该API的使用是仅用于写入还是仅用于读取。自从PhotoKit在iOS 8中推出以来,情况一直如此。
如果您不使用PHPhotoLibrary
、PHAsset
等,则iOS 11中新增了更窄的权限选项(而不是Photos.framework API的一部分):
- 如上所述,
UIImagePickerController
不需要一揽子隐私设置权限,因为每次使用都会授予所选特定资产的一次性读取权限 -
如果您只需要将新资产添加到照片库,请使用
UIImageWriteToSavedPhotosAlbum
或UISaveVideoAtPathToSavedPhotosAlbum
。有了这些,你可以将NSPhotoLibraryAddUsageDescription
放在你的Info.plist中——然后系统的隐私设置会向用户明确表示,他们不会允许你查看或修改现有资产,只允许你添加新资产。如果用户授予"仅添加"权限,则它仅适用于那些UIKit函数——尝试使用
PHPhotoLibrary
仍然会提示(并需要Info.plist键)读取/写入权限。有关仅添加隐私设置的更多信息,请参阅WWDC17谈话的这一部分。
这是预期行为吗-是。
从文档-https://developer.apple.com/documentation/uikit/uiimagepickercontroller/1619144-issourcetypeavailable
true,如果设备支持指定的源类型;如果指定的源类型不可用,则为false。
它告诉您设备是否支持源类型,而不是应用程序是否有权访问它。
正如您在问题中已经提到的,PHPhotoLibrary.authorizationStatus()
将是检查此问题的正确方法。
这种(新)行为对我来说听起来很合乎逻辑,原因如下。使用UIImagePickerController
时,您的应用程序实际上无法访问任何照片。当这种情况发生时,它只看到用户选择的那个;如果用户在选择器中点击"取消",应用程序将无法使用这些选项。
PHPhotoLibrary
是一个单独的框架Photos的一部分,在这里你可以使用用户的照片库做很多事情,因此需要权限。
因此,如果您只使用UIImagePickerController
,我建议不要在.中混合照片内容
免责声明:没有听到任何来自苹果公司的官方声明。这个论坛帖子看起来很相关,也许我们会在那里得到回复UPD:是的,同样的想法。
此外,如果你足够邪恶,理论上你可以在运行时篡改UIImagePickerController
视图层次结构,并检查用户在那里看到的任何内容。但这又是苹果要处理的问题,我们应该友善一点:-)
您应该同时检查:身份验证状态和源可用性。
授权状态
有关应用程序访问用户照片的授权的信息图书馆
isSourceTypeAvailable
讨论
因为媒体源可能不存在或者可能不可用,设备可能并不总是支持所有源类型。
例如,如果尝试从用户的库中拾取图像,而库为空,此方法返回false。类似地,如果相机已经在使用中,此方法返回false。