请求PHAsset的图像数据时,PHImageManager的行为异常

时间:2020-04-22 07:57:55

标签: ios swift iphone

我正在创建一个基本的图像编辑器,该编辑器将获取图像并应用基本的元数据更改。应用所有修改后,我使用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
}]

1 个答案:

答案 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)
        })

    }