iOS11 即使设置设为 "never" 也可以访问照片库
iOS11 photo library access is possible even if settings are set to "never"
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: { })
}
即使我使用上述代码将“设置”中的照片访问权限设置为 "Never",我仍然可以显示图像选择器并显示照片。我会在显示之前检查 PHPhotoLibrary.authorizationStatus()
,但我想知道这是预期的行为吗?
这是预期的行为吗? - 是的。
true if the device supports the specified source type; false if the specified source type is not available.
它会告诉您设备是否支持源类型,但不会告诉您应用是否有权访问它。
正如您在问题中已经提到的,PHPhotoLibrary.authorizationStatus()
将是检查此问题的正确方法。
UIImagePickerController和PHPhotoLibrary负责不同的区域。
您应该同时检查:身份验证状态和来源可用性。
PHAuthorizationStatus
Information about your app’s authorization to access the user’s Photos
library.
isSourceTypeAvailable
Discussion
Because a media source may not be present or may be unavailable,
devices may not always support all source types.
For example, if you
attempt to pick an image from the user’s library and the library is
empty, this method returns false. Similarly, if the camera is already
in use, this method returns false.
这种(新)行为确实对我来说听起来合乎逻辑,原因如下。使用 UIImagePickerController
时,您的应用实际上无法访问 any 照片。当发生这种情况时,它只会看到您的用户选择的那个;如果用户点击选择器中的取消 none,其中的那些将对应用程序可用。
PHPhotoLibrary
是单独框架 Photos 的一部分,您可以在其中对用户的照片库做很多事情,因此需要许可。
因此,如果您只使用 UIImagePickerController
,我建议 不要 将照片内容混入。
免责声明:尚未听说 Apple 人员的任何官方声明。 This forum thread looks relevant, maybe we get a reply there. UPD: there it is,同样的想法。
此外,如果您足够邪恶,理论上您可以 fiddle 在运行时使用 UIImagePickerController
查看层次结构并检查用户在那里看到的任何内容。但这又是苹果要处理的事情,我们应该友善一点:-)
好的,您已经可以根据答案和评论将其拼凑起来,但要尝试讲述一个更完整的故事...
在 iOS 11 中,UIImagePickerController
作为独立于您的应用程序的进程运行。这意味着:
- 您的应用无法查看用户的整个照片库 — 它只对用户在图像选择器中选择的任何资产获得只读访问权限。
- 由于 (1),您的应用不需要标准隐私授权即可访问照片库。用户明确选择一个(或多个)特定资产用于您的应用,这意味着用户授予您的应用读取相关资产的权限。
您可以查看更多相关信息 in the WWDC17 talk on PhotoKit。
(顺便说一句,此模型与您自 iOS 9 以来看到的 in the Contacts framework 相匹配;如果您显示联系人选择器,您的应用只会获得一次性的联系人信息用户选择的联系人,而不是对联系人数据库的持续 read/write 访问,因此联系人选择器不需要特殊的隐私权限。)
PHPhotoLibrary
及其授权状态反映了用户可以从“设置”>“隐私”中控制的照片访问的全局 read/write 权限。 (这是您的 Info.plist 需要 NSPhotoLibraryUsageDescription
的地方。)任何对 PHPhotoLibrary
API 的使用都需要此权限,无论您的应用程序是否使用 API仅用于写作或仅用于阅读。自从在 iOS 8.
中引入 PhotoKit 以来,情况就是如此。
如果您不使用 PHPhotoLibrary
、PHAsset
等,iOS 11 中新增了更窄的权限选项(不属于 Photos.framework API):
- 如上所述,
UIImagePickerController
不需要全面的隐私设置权限,因为每次使用都会授予对所选特定资产的一次性读取权限。
如果您只需要将新资产添加到照片库,请使用 UIImageWriteToSavedPhotosAlbum
or UISaveVideoAtPathToSavedPhotosAlbum
。对于这些,您可以将 NSPhotoLibraryAddUsageDescription
放入您的 Info.plist - 然后系统的隐私设置将向用户明确表示他们没有授予您查看或修改现有资产的权限,只能添加新资产。
如果用户授予仅添加权限,则它仅适用于那些 UIKit 函数 — 尝试使用 PHPhotoLibrary
仍会提示输入(并需要 Info.plist 键)read/write 访问。
有关仅添加隐私设置的更多信息,请参阅 this part of the WWDC17 talk。
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: { })
}
即使我使用上述代码将“设置”中的照片访问权限设置为 "Never",我仍然可以显示图像选择器并显示照片。我会在显示之前检查 PHPhotoLibrary.authorizationStatus()
,但我想知道这是预期的行为吗?
这是预期的行为吗? - 是的。
true if the device supports the specified source type; false if the specified source type is not available.
它会告诉您设备是否支持源类型,但不会告诉您应用是否有权访问它。
正如您在问题中已经提到的,PHPhotoLibrary.authorizationStatus()
将是检查此问题的正确方法。
UIImagePickerController和PHPhotoLibrary负责不同的区域。
您应该同时检查:身份验证状态和来源可用性。
PHAuthorizationStatus
Information about your app’s authorization to access the user’s Photos library.
isSourceTypeAvailable
Discussion
Because a media source may not be present or may be unavailable, devices may not always support all source types.
For example, if you attempt to pick an image from the user’s library and the library is empty, this method returns false. Similarly, if the camera is already in use, this method returns false.
这种(新)行为确实对我来说听起来合乎逻辑,原因如下。使用 UIImagePickerController
时,您的应用实际上无法访问 any 照片。当发生这种情况时,它只会看到您的用户选择的那个;如果用户点击选择器中的取消 none,其中的那些将对应用程序可用。
PHPhotoLibrary
是单独框架 Photos 的一部分,您可以在其中对用户的照片库做很多事情,因此需要许可。
因此,如果您只使用 UIImagePickerController
,我建议 不要 将照片内容混入。
免责声明:尚未听说 Apple 人员的任何官方声明。 This forum thread looks relevant, maybe we get a reply there. UPD: there it is,同样的想法。
此外,如果您足够邪恶,理论上您可以 fiddle 在运行时使用 UIImagePickerController
查看层次结构并检查用户在那里看到的任何内容。但这又是苹果要处理的事情,我们应该友善一点:-)
好的,您已经可以根据答案和评论将其拼凑起来,但要尝试讲述一个更完整的故事...
在 iOS 11 中,UIImagePickerController
作为独立于您的应用程序的进程运行。这意味着:
- 您的应用无法查看用户的整个照片库 — 它只对用户在图像选择器中选择的任何资产获得只读访问权限。
- 由于 (1),您的应用不需要标准隐私授权即可访问照片库。用户明确选择一个(或多个)特定资产用于您的应用,这意味着用户授予您的应用读取相关资产的权限。
您可以查看更多相关信息 in the WWDC17 talk on PhotoKit。
(顺便说一句,此模型与您自 iOS 9 以来看到的 in the Contacts framework 相匹配;如果您显示联系人选择器,您的应用只会获得一次性的联系人信息用户选择的联系人,而不是对联系人数据库的持续 read/write 访问,因此联系人选择器不需要特殊的隐私权限。)
PHPhotoLibrary
及其授权状态反映了用户可以从“设置”>“隐私”中控制的照片访问的全局 read/write 权限。 (这是您的 Info.plist 需要 NSPhotoLibraryUsageDescription
的地方。)任何对 PHPhotoLibrary
API 的使用都需要此权限,无论您的应用程序是否使用 API仅用于写作或仅用于阅读。自从在 iOS 8.
如果您不使用 PHPhotoLibrary
、PHAsset
等,iOS 11 中新增了更窄的权限选项(不属于 Photos.framework API):
- 如上所述,
UIImagePickerController
不需要全面的隐私设置权限,因为每次使用都会授予对所选特定资产的一次性读取权限。 如果您只需要将新资产添加到照片库,请使用
UIImageWriteToSavedPhotosAlbum
orUISaveVideoAtPathToSavedPhotosAlbum
。对于这些,您可以将NSPhotoLibraryAddUsageDescription
放入您的 Info.plist - 然后系统的隐私设置将向用户明确表示他们没有授予您查看或修改现有资产的权限,只能添加新资产。如果用户授予仅添加权限,则它仅适用于那些 UIKit 函数 — 尝试使用
PHPhotoLibrary
仍会提示输入(并需要 Info.plist 键)read/write 访问。有关仅添加隐私设置的更多信息,请参阅 this part of the WWDC17 talk。