如何使用PHPicker在iOS系统无授权下获取资源

admin 2025-05-12 169人围观 ,发现46个评论

在本篇文章中,我将详细介绍如何正确使用PHPicker以及何时应该使用PHPicker。我撰写这篇文章的原因是:在尝试使用PHPicker访问资源库时遇到了一些问题。互联网上的许多文章提供的方法都是错误的,从而导致了对PHPicker和iOS权限的一些核心问题的误解。

01

PHPicker是什么?

PHPickerViewController

PHPickerConfiguration

PHPickerFilter

PHPickerResult

letphotoLibrary=()varconfig=PHPickerConfiguration(photoLibrary:photoLibrary)letselectedCount==min(4-selectedCount,4)=(type==.pic?limited:1)=(type==.pic?.images:.videos)letpickerViewController=PHPickerViewController(configuration:config)=?.present(pickerViewController,ani

02

真的需要用户授权吗?

当用户给予受限访问模式时,如果需要获得未授权的额外资源,网络上很多文章建议你使用PHAsset和PHPicker来获取额外的数据,这样做的问题是,你必须具有访问资源库的权限,这违背了苹果建议的使用PHPicker的初衷:在不请求权限的情况下使用的选择器。

我们来模拟一下流程:你的的应用程序请求访问用户资源库的权限,用户说:“我将只给这个应用程序有限的访问一些照片。”此时,如果你的应用程序打开PHPicker并显示所有的照片;用户说:“奇怪,我以为我只给有限的访问权限,为什么所有照片都有?”;接下来,用户选择了一张他没有给我们访问权限的照片。应用程序现在需要什么都不做,为了使用PHAsset获得他选择的照片的元数据(metadata),他们必须再次更新他们的权限。用户感到困惑。

所以,如果你的目的非常明确,就是需要用户给予额外的资源授权来获得PHAsset对象,应该使用iOS14的新().presentLimitedLibraryPicker(from:vc),反之,使用PHPicker不应该申请获得用户授权,正确的做法是使用PHPickerViewControllerDelegate返回的NSItemProvider获得元数据(metadata)信息,我将在稍后详细介绍。

03

使用PHPicker的方式

1、错误方式

下面这段代码是网络上广泛被转载的一段错误代码:

importUIKitimportPhotosUIclassPhotoKitPickerViewController:UIViewController,PHPickerViewControllerDelegate{@IBActionfuncpresentPicker(_ser:Any){letphotoLibrary=()letconfiguration=PHPickerConfiguration(photoLibrary:photoLibrary)letpicker=PHPickerViewController(configuration:configuration)=selfpresent(picker,animated:true)}funcpicker(_picker:PHPickerViewController,didFinishPickingresults:[PHPickerResult]){(animated:true)letidentifiers=(\.assetIdentifier)letfetchResult=(withLocalIdentifiers:identifiers,options:nil)//TODO:DosomethingwiththefetchresultifyouhavePhotosLibraryaccess}}

在这段代码中,你使用PHPickerViewController选择了受限制的资源,但是在调用时返回了一个空结果。这是因为fetchAssets方法只能检索用户授权访问的所有资源,而在受限制模式下,只有最近的受限制资源可供访问,所以这种方式是错误的!

2、正确方式

04

通过前一步骤,我们已经知道了资源的类型。接下来通过NSItemProvider的API加载图片内容和获得元数据信息;查阅NSItemProvider(1)文档,可以看到加载数据,主要提供了下面几种API:

loadDataRepresentation:返回资源Data数据

loadFileRepresentation:返回资源URL

loadObject:指定资源类型返回

这里我推荐使用loadDataRepresentation,返回Data数据,方便下一步获得元数据信息。

在处理业务model转换函数中,由于Data类型很容易转换成UIImage,并且通过将Data转换为CFData类型,可以通过系统预设的key/value键值对获得元数据信息,

letimgSrc=CGImageSourceCreateWithData(data,optionsasCFDictionary)letmetadata=CGImageSourceCopyPropertiesAtIndex(imgSrc,0,optionsasCFDictionary)colorModel=metadata[kCGImagePropertyColorModel]as?StringpixelWidth=metadata[kCGImagePropertyPixelWidth]as?Double;pixelHeight=metadata[kCGImagePropertyPixelHeight]as?Double;

这里我们使用了Github上开源的ExifData(2)代码,完整实现了所有字段的获取封装,使用起来非常方便。

funccreatePhotoResourcesModel(data:Data?,assetIdentifier:String?)-SNSResourcesModel?{guardletimageData=data,letuiimage=UIImage(data:imageData)else{returnnil}letmodel=SNSResourcesModel()==.=.==uiimageletexifData=ExifData(data:imageData)=Int(??0)=Int(??0)==.GIF{==imageData}returnmodel}

05

处理特殊格式图片

如果用户在资源库中选择了一张WebP格式图片或者GIF动图,由于展示所需代码和形式均不同,所以需要特别区分,那么如何来区别处理呢?

我们可以通过UTType来具体区分不同类型,UTType是UniformTypeIdentifier的缩写,用于标识特定类型的文件或数据。在macOS和iOS等操作系统中,UTType通常用于识别文件类型、将文件分组到合适的应用程序中、在不同应用程序之间共享数据等。

UTType由两部分组成:类型标识符(typeidentifier)和类型标签(typetag)。类型标识符是一串唯一的字符串,用于标识特定类型的文件或数据,通常采用反向DNS风格的命名方式,如、等。类型标签是一个可选的字符串,用于描述特定类型的文件或数据,例如"PDFdocument"或"JPEGimage"等。

if(()){//图片处理//判断(){//处理webp}//判断(){//处理GIF}}

06

06

获取加载进度

当获取的资源文件较大时,我们需要获得加载数据的进度,此时可以使用NSItemProvider的加载数据函数提供的返回值NSProgress对象。

varprogress:Progress?progress=(forTypeIdentifier:){data,errorin//}//添加观察者progress?.addObserver(self,forKeyPath:"fractionCompleted",options:[.new],context:nil)overridefuncobserveValue(forKeyPathkeyPath:String?,ofobject:Any?,change:[NSKeyValueChangeKey:Any]?,context:UnsafeMutableRawPointer?){ifkeyPath=="fractionCompleted"{print("fractionCompleted=\(?.fractionCompleted)")}}

在上面的示例代码中,我们首先创建了一个NSItemProvider对象和一个指定类型标识符。然后,我们使用loadDataRepresentation(forTypeIdentifier:completionHandler:)方法加载数据,并返回一个NSProgress对象。我们可以将该对象添加为观察者,并在观察者的回调方法中更新进度条的值。

请注意,NSProgress对象是线程安全的,因此可以在不同的线程中使用。此外,如果你需要在多个地方使用同一个NSProgress对象;

NSProgress对象的fractionCompleted属性,该属性表示任务的完成度,其值在0.0和1.0之间。

06

总结

本文要点包含以下:

PHPicker是iOS14开始引入的新组件,它允许在不需要用户授权的情况下访问照片库的所有资源;

使用PHPicker的正确方式是通过PHPickerViewControllerDelegate回调返回的NSItemProvider来获取所选资源,而不是通过PHAsset来获取,后者需要提前获取用户的相册访问授权;

通过UTType可以进一步判断特殊格式资源如webp、gif等进行不同处理;

可以通过NSProgress监听资源加载进度;

正确使用PHPicker可以避免引起用户疑惑,提高用户体验,是iOS14访问多媒体资源的推荐方式。

总之,本文详细介绍了在iOS14中如何正确使用PHPicker访问用户选择的部分照片资源,其要点是不需要提前获取授权,通过NSItemProvider处理多媒体资源,这是一种更符合系统设计初衷和提高用户体验的方式。

标注参考链接:

(1)

(2)

其他参考链接:

(1)

(2)

(3)

(4)

(5)

作者:狐友靳凯

出处:

猜你喜欢
    不容错过