从相册中获取 GIF 的一些小 Tip
在 iOS 8 的时候,Apple 推出了 PhotoKit 框架,提供了一系列丰富的接口,想了解 PhotoKit 的同学,可以看下 Apple 的示例:Example app using Photos framework。
如何判断 GIF 资源
1. 获取 PHAsset
的资源对象 PHAssetResource
,通过其 uniformTypeIdentifier
或 originalFilename
属性来判断是否为 GIF:
|
|
关于PHAssetResource
,每个 PHAsset 对象都会引用一个或多个资源(resource),一个被修改过的图片的PHAsset
对象会包含图片编辑之前和之后的 resource,以及关于描述这次编辑的PHAdjustmentData
对象的 resource。我们可以将一个修改过后的 GIF 的 PHAsset
所包含的 PHAssetResource
打印出来看下:
|
|
从打印出的信息可以看到,在 GIF 被修改之后,UTI 从com.compuserve.gif
变成了 public.jpeg
,所以这里如果还通过 UTI 来判断的话,就会错漏,只能通过 fileName 来判断。
另外, PHAssetResource
类只支持 iOS 9.0+。
2. 通过获取 PHAsset
的元数据来判断:
|
|
同样,这里也需要考虑到 GIF 被修改的情况,requestOption.version
默认是 current
,即如果图片被修改过的话,返回的就是包含所有调整和修改的图像数据,因此我们需要将其设置为 unadjusted
来获取原始的图像数据。
相比上面的方法,这种方法更快速,用时更少。
关于 localIdentifier
localIdentifier
是 PHAsset
的父类 PHObject
的一个属性,是每个图片资源独有的标识符。
我在开发 notGIF 的时候,每次启动时都需要遍历相册中的所有图片来获取其中的 GIF,这个操作非常的耗时,十分影响用户体验。我尝试过将其拆分成多个任务,分发到多个线程同时进行,虽然有些效果,但还是不尽如人意,毕竟随着相册中照片数量的增加,其所消耗的时间是线性增长的。
这时候,localIdentifier
就有了用武之地。因为 localIdentifier
是识别图片资源的唯一标识符,所以,我们可以在第一次获取到相册中的 GIF 的时候,将其获取到的所有 GIF 的 localIdentifier
记录下来。这样,下次启动的时候,就可以通过这些 localIdentifier
来直接获取 GIF 资源:
|
|
如果 localIdentifier
所对应的图片资源被删除或不存在的话,PHAsset.fetchAssets(withLocalIdentifiers: options:)
会自动过滤掉。同时,我们可以在后台去检测相册是否有变化,如果有,则更新 UI 以及 所存储的 localIdentifier
的信息。
获取相册中图片的 url
在适配 iMessage Extension 的时候,需要通过图片的 url 来获取和发送图片,PhotoKit 也提供了获取图片资源 url 的方法:
|
|