我正在使用 PHPickerViewController 来选择图像和视频。因为我的应用程序存储文件并将它们用于非 iOS 应用程序,所以我对使用 livephotos 不感兴趣。目前我正在使用以下方法从 livePhoto 中提取图像,这归功于我结合的以下两个教程:
https://www.appcoda.com/phpicker/
https://www.limit-point.com/blog/2018/live-photos/
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
if results != nil {
for result in results! {
let itemProvider = result.itemProvider
guard let typeIdentifier = itemProvider.registeredTypeIdentifiers.first,
let utType = UTType(typeIdentifier)
else { continue }
if utType.conforms(to: .image) {
self.getPhoto(from: itemProvider, isLivePhoto: false)
} else if utType.conforms(to: .movie) {
self.getVideo(from: itemProvider, typeIdentifier: typeIdentifier)
} else {
self.getPhoto(from: itemProvider, isLivePhoto: true)
}
}
}
}
private func getPhoto(from itemProvider: NSItemProvider, isLivePhoto: Bool) {
let objectType: NSItemProviderReading.Type = !isLivePhoto ? UIImage.self : PHLivePhoto.self
if itemProvider.canLoadObject(ofClass: objectType) {
itemProvider.loadObject(ofClass: objectType) { object, error in
if let error = error {
print(error.localizedDescription)
}
if !isLivePhoto {
if let image = object as? UIImage {
DispatchQueue.main.async {
// use image
}
}
} else {
if let livePhoto = object as? PHLivePhoto {
DispatchQueue.main.async {
let livePhotoResources = PHAssetResource.assetResources(for: livePhoto)
for resource in livePhotoResources {
if resource.type == .photo {
let buffer = NSMutableData()
var dataRequestID:PHAssetResourceDataRequestID = PHInvalidAssetResourceDataRequestID
let options = PHAssetResourceRequestOptions()
options.isNetworkAccessAllowed = true
dataRequestID = PHAssetResourceManager.default().requestData(for: resource, options: options, dataReceivedHandler: { (data:Data) in
buffer.append(data)
}, completionHandler: { (error:Error?) in
// buffer now contains the resource data
if let image = UIImage(data: buffer as Data) {
// use image
}
})
}
}
}
}
}
}
}
}
这种方法似乎工作正常,我可以获得照片和 livePhoto 的 UIImage。
我想知道是否有更简单的方法来解决这个问题?PHPickerViewController 预览只是图像,所以我可以直接为 livePhoto 提取该图像资源吗?
此外,选择器定义如下:
var config = PHPickerConfiguration()
config.filter = .any(of: [.images, .videos, .livePhotos])
config.selectionLimit = 10
config.preferredAssetRepresentationMode = .current
let controller = PHPickerViewController(configuration: config)
我希望只定义没有 livePhotos 的过滤器就可以让我看到 livePhotos 并让 livePhotos 的 uiType.conforms(to: .image) 返回 true,但事实并非如此。