虽然这个问题有点老了,但我将解释我是如何解决它的,因为我遇到了同样的问题,并且从未在互联网上找到任何适用于照片框架的有效解决方案。
由于 Apple API 的设计方式,确实不可能直接从 ALAsset 和 PHAsset 源文件上传。因此,让我开始讨论如何使用旧的(现已弃用的)API - AssetsLibrary 解决这个问题。
ALAssetRepresentation
有一种很棒的方法getBytes:fromOffset:length:error:
可以直接转换为NSInputStream
's read:maxLength:
。这为您提供了如何从一个实例中放置流的许多选项ALAsset
——您可以创建一对绑定的输入和输出流,或者您可以选择使用更复杂的子类NSInputStream
化路径。
因此,在使用 Photos Framework 时,这为您提供了第一个解决方案:您可以尝试从 a获取ALAsset
URL,PHAsset
然后回退到从旧的ALAssetRepresentation
. 是的,没有记录此 URL 转换,是的,AssetsLibrary 现在已被弃用,但是嘿 - 这是一个选项。并且有一篇关于 Medium 的文章表明它确实是一个可行的解决方案。
现在让我们继续讨论照片框架。
在 iOS 9 中,Apple 引入了一个PHAssetResourceManager
适合我们目的的新类。这是一种冗长的方法requestDataForAssetResource:options:dataReceivedHandler:completionHandler:
a) 逐步为您提供大量资产数据;b) 它提供对这些底层数据资源的直接访问,并且如果照片存在于手机上(即不是来自 iCloud),则不需要文件系统的任何额外空间。旁注:“b)”中的语句实际上并没有记录,但在现实生活中被证明是正确的——你可以尝试填满设备的存储空间并调用这个方法,它会很好地工作。但是,有一些注意事项PHAssetResourceManager
- 它异步传递数据并且数据块是任意大小的。很容易理解为什么这个新的 API 看起来像它的样子 - 使用照片框架,您可以使用相同的方法来处理本地和 iCloud 资产。但总而言之,这个新方法并没有像方法NSInputStream
那样很好地转换为 's 接口。但请放心,我们可以利用此方法的一个特性使其对消费者友好,使其看起来就像旧方法一样。此方法按顺序将其数据传递到串行队列中。这意味着我们可以使用有界阻塞队列来创建一个看起来像. 有了这样的方法之后,获取资产的字节就变得超级容易了。getBytes:fromOffset:length:error:
ALAssetRepresentation
getBytes:fromOffset:length:error:
requestDataForAssetResource:options:dataReceivedHandler:completionHandler:
func nextChunk() throws -> Data?
实际上,这正是我在库PHAssetResourceInputStream中所做的。它承担了从 Photos Framework 获取资产字节背后的所有繁重工作,并为您提供了一个简单的 API,所以我希望它对遇到同样问题的人有所帮助。
TL;博士
PHAssetResourceManager
会让你开心。