我正在创建一个基本的图像编辑器,该编辑器将获取图像并应用基本的元数据更改。应用所有修改后,我使用PHAssetChangeRequest
将修改提交到照片库。
我的理解是,这样做不是在修改原始媒体,而是在创建新的PHAssetResource
。
我可以确认我的编辑工作正常,并且新的PHAssetResources
已添加到PHAsset
中。请参阅下面的日志。
为什么当我请求此资产的图像数据时(发生修改后),即使使用options.version = .current
进行请求,我也得到了原始资产。
关闭应用程序并重新启动它似乎可以纠正此问题,并且从该点开始,完全相同的函数会返回正确的,经过修改的图像数据。这样,该应用程序将完全从照片库重新加载所有资产。但这不应影响从资产请求实际图像数据。
是否有一种方法可以强制资产资源的isCurrent
属性,或者我是否缺少某些东西?
///Loads the photos data using a completion handler
func getPhotoData(photo: Photo, reflectingEdits: Bool = true, completionHandler: @escaping (Data?) -> ()){
let options = PHImageRequestOptions()
options.isNetworkAccessAllowed = true
options.version = .original
if(reflectingEdits){
options.version = .current
}
manager.requestImageDataAndOrientation(for: photo.asset, options: options, resultHandler: {
data, uti, orientation, info in
print("Succesfully delivered image (\(String(describing: uti))) -> \(data?.count ?? 0) bytes")
completionHandler(data)
})
}
之前
[<PHAssetResource: 0x28328eb50> {
type: video_cmpl
uti: com.apple.quicktime-movie
filename: IMG_0067.MOV
asset: 8B5B03FE-9862-4DD9-BB81-C9753FDE328B/L0/001
locallyAvailable: YES
fileURL: file:///var/mobile/Media/PhotoData/CPLAssets/group125/5571C124-DF27-4636-9AFC-23786A33850B.MOV
width: 980
height: 1308
fileSize: 2403227
analysisType: unavailable
cplResourceType: OriginalVidCompl
isCurrent: YES
}, <PHAssetResource: 0x283281dd0> {
type: photo
uti: public.heic
filename: IMG_0067.HEIC
asset: 8B5B03FE-9862-4DD9-BB81-C9753FDE328B/L0/001
locallyAvailable: YES
fileURL: file:///var/mobile/Media/PhotoData/CPLAssets/group125/5571C124-DF27-4636-9AFC-23786A33850B.HEIC
width: 3024
height: 4032
fileSize: 1331238
analysisType: never-download
cplResourceType: Original
isCurrent: YES
}]
之后
[<PHAssetResource: 0x28329d320> {
type: adjustment
uti: com.apple.property-list
filename: Adjustments.plist
asset: 8B5B03FE-9862-4DD9-BB81-C9753FDE328B/L0/001
locallyAvailable: YES
fileURL: file:///var/mobile/Media/PhotoData/Mutations/PhotoData/CPLAssets/group125/5571C124-DF27-4636-9AFC-23786A33850B/Adjustments/Adjustments.plist
width: 0
height: 0
fileSize: 7129
analysisType: unavailable
cplResourceType: Unknown
isCurrent: NO
}, <PHAssetResource: 0x28329d440> {
type: video_cmpl
uti: com.apple.quicktime-movie
filename: IMG_0067.MOV
asset: 8B5B03FE-9862-4DD9-BB81-C9753FDE328B/L0/001
locallyAvailable: YES
fileURL: file:///var/mobile/Media/PhotoData/CPLAssets/group125/5571C124-DF27-4636-9AFC-23786A33850B.MOV
width: 980
height: 1308
fileSize: 2403227
analysisType: unavailable
cplResourceType: OriginalVidCompl
isCurrent: YES
}, <PHAssetResource: 0x28329cfc0> {
type: photo
uti: public.heic
filename: IMG_0067.HEIC
asset: 8B5B03FE-9862-4DD9-BB81-C9753FDE328B/L0/001
locallyAvailable: YES
fileURL: file:///var/mobile/Media/PhotoData/CPLAssets/group125/5571C124-DF27-4636-9AFC-23786A33850B.HEIC
width: 3024
height: 4032
fileSize: 1331238
analysisType: never-download
cplResourceType: Original
isCurrent: YES
}, <PHAssetResource: 0x28329d170> {
type: photo_full
uti: public.jpeg
filename: FullSizeRender.jpg
asset: 8B5B03FE-9862-4DD9-BB81-C9753FDE328B/L0/001
locallyAvailable: YES
fileURL: file:///var/mobile/Media/PhotoData/Mutations/PhotoData/CPLAssets/group125/5571C124-DF27-4636-9AFC-23786A33850B/Adjustments/FullSizeRender.jpg
width: 4032
height: 3024
fileSize: 2036693
analysisType: unavailable
cplResourceType: JPEGFull
isCurrent: NO
}]
答案 0 :(得分:0)
我通过使用PHAssetResourceManager
手动请求适当的资源来解决此问题。
我找不到任何文档来证明我的理论,但是我的猜测是,在执行PHAssetChangeRequest
时,新的PHAssetResource
不会立即设置为最新。也许有一些动作,例如PHImageManager
类的实例化,它会更新设置为当前资源的资源。
我使用PHAssetResourceManager.requestData...
来检索具有所需的特定PHAssetResource
属性的type
。它不像原始方法那样简单,这次又分为两个不同的函数,但这意味着我不必依靠PHImageManager的帮助来决定要获取的相关资源。
///Loads the edited photos data using a completion handler
private func getEditedPhotoData(photo: Photo, completionHandler: @escaping (Data?) -> ()){
if let editedPhoto = PHAssetResource.assetResources(for: photo.asset).first(where: {$0.type == .fullSizePhoto || $0.type == .alternatePhoto}){
PHAssetResourceManager.default().requestData(for: editedPhoto, options: nil, dataReceivedHandler: completionHandler, completionHandler: {
error in
if(error != nil){
completionHandler(nil)
}
})
}else{
completionHandler(nil)
}
}
/// Loads the photos original data using a completion handler
private func getOriginalPhotoData(photo: Photo, completionHandler: @escaping (Data?) -> ()){
let options = PHImageRequestOptions()
options.isNetworkAccessAllowed = true
options.version = .original
manager.requestImageDataAndOrientation(for: photo.asset, options: options, resultHandler: {
data, uti, orientation, info in
completionHandler(data)
})
}