ios - PHAssetResource.assetResources 使用有效的 PHAsset 返回零结果
问题描述
我正在尝试获取 PHAsset 的资产资源,但遇到了一些麻烦。我能够毫无问题地获取 PHAsset,但资产的资源始终为空。并非每张照片都会发生这种情况,但特别是其中一张给我带来了麻烦。好奇我是否缺少某些东西,这是在某些情况下的预期行为。
import UIKit
import Photos
import PhotosUI
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
requestPhotoLibraryAuthorization() { success in
let identifier = "E218D471-E616-4E39-99C3-624D13D9B661/L0/001"
let assets = self.fetchPHAssets(identifiers: [identifier])
guard assets.count > 0 else { return }
let imageOptions = PHImageRequestOptions()
imageOptions.deliveryMode = .highQualityFormat
imageOptions.isNetworkAccessAllowed = true
PHImageManager.default().requestImage(for: assets[0], targetSize: PHImageManagerMaximumSize, contentMode: .default, options: imageOptions) { (image, info) in
print(String(describing: info)) // never called
}
self.saveAssetToDisk(asset: assets[0]) { image in
guard let image = image else { return }
self.imageView.image = image
}
}
}
func fetchPHAssets(identifiers: [String]) -> [PHAsset] {
let options = PHFetchOptions()
options.includeAllBurstAssets = false
options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
options.fetchLimit = identifiers.count
options.includeAssetSourceTypes = [.typeCloudShared, .typeiTunesSynced, .typeUserLibrary]
let assetResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: options)
var assetArray:[PHAsset] = []
for i in 0..<assetResult.count {
let asset = assetResult[i]
assetArray.append(asset)
}
return assetArray
}
func saveAssetToDisk(asset: PHAsset, onComplete: @escaping (UIImage?)->()) {
let resources = PHAssetResource.assetResources(for: asset)
guard resources.count > 0 else { return }
let resource = resources[0]
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentUrl = urls[0]
let resourceUrl = documentUrl.appendingPathComponent(resource.originalFilename, isDirectory: false)
// write image
let options = PHAssetResourceRequestOptions()
options.isNetworkAccessAllowed = true
if !FileManager.default.fileExists(atPath: resourceUrl.path) {
PHAssetResourceManager.default().writeData(for: resource, toFile: resourceUrl, options: options) { error in
if error == nil {
guard let image = UIImage(contentsOfFile: resourceUrl.path) else { return }
onComplete(image)
}
}
} else {
onComplete(UIImage(contentsOfFile: resourceUrl.path))
}
}
let requestPhotoLibraryKey = "hasRequestedPhotoAccess"
func requestPhotoLibraryAuthorization(onComplete: @escaping (Bool) -> ()) {
let status = PHPhotoLibrary.authorizationStatus()
if status == .notDetermined {
PHPhotoLibrary.requestAuthorization { status in
if status == PHAuthorizationStatus.authorized {
UserDefaults.standard.set(true, forKey: self.requestPhotoLibraryKey)
onComplete(true)
}
}
} else if status == .authorized {
UserDefaults.standard.set(true, forKey: requestPhotoLibraryKey)
onComplete(true)
} else if status == .denied {
onComplete(false)
}
}
}
解决方案
没有看到照片框架 requestImageDataForAsset 中描述的错误消息偶尔会失败,但我能够追踪到有问题的图像是 iCloud 共享相册的一部分。按照他们的建议解决了我的问题。
推荐阅读
- javascript - 如何将参数传递到嵌入中
- html - 如何在 html 中将 from 放入 from 中
- colors - 树莓派 + neopixel:如果 RGB LED 的亮度降低,是否意味着某些颜色无法渲染?
- node.js - 如何在 nodejs 中修复此架构错误?
- c++ - 声明变量时没有初始化的 C++ 自动类型推导
- c++11 - 玻璃珠 - 后缀阵列如何应用在这里?
- c# - CrystalReport 不显示正确的数据
- python - Python - 将 JSON 读取文件转换为可用的 DataFrame
- html - 悬停时 li 的背景颜色无法正常工作
- c++ - 在我的以下代码中获取 MLE(内存限制错误)。尝试解决 ROUND C 2019(问题 A- Wiggle Walk)Kickstart 问题