如何知道PHAsset是否已被修改?

时间:2014-10-30 12:34:26

标签: ios objective-c photos photokit

更具体地说,您如何知道PHAsset当前版本的标的资产是否与原始版本不同?

我的用户只需要在必要时在当前或原始资产之间进行选择。然后我需要他们对PHImageRequestOptions.version的回答。

4 个答案:

答案 0 :(得分:4)

我找到了两种检查PHAsset进行修改的方法,并将其发布为Gist

- (void)tb_checkForModificationsWithEditingInputMethodCompletion:(void (^)(BOOL))completion {
    PHContentEditingInputRequestOptions *options = [PHContentEditingInputRequestOptions new];
    options.canHandleAdjustmentData = ^BOOL(PHAdjustmentData *adjustmentData) { return YES; };

    [self requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
        if (completion) completion(contentEditingInput.adjustmentData != nil);
    }];
}

- (void)tb_checkForModificationsWithAssetPathMethodCompletion:(void (^)(BOOL))completion {
    PHVideoRequestOptions *options = [PHVideoRequestOptions new];
    options.deliveryMode = PHVideoRequestOptionsDeliveryModeFastFormat;

    [[PHImageManager defaultManager] requestAVAssetForVideo:self options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
        if (completion) completion([[asset description] containsString:@"/Mutations/"]);
    }];
}

编辑:我当时需要PHAsset与图像相同的功能。我用过这个:

- (void)tb_checkForModificationsWithAssetPathMethodCompletion:(void (^)(BOOL))completion {
    [self requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
        NSString *path = (contentEditingInput.avAsset) ? [contentEditingInput.avAsset description] : contentEditingInput.fullSizeImageURL.path;
        completion([path containsString:@"/Mutations/"]);
     }];
}

答案 1 :(得分:2)

查看PHImageRequestOptionsVersion

<强> PHImageRequestOptionsVersionCurrent

  

请求最新版本的图片资源(反映所有修改的版本)。   生成的图像是所有先前进行的调整的渲染输出。

<强> PHImageRequestOptionsVersionUnadjusted

  

无需调整即可申请图像资产的版本   如果资产已被编辑,则生成的图像会在执行任何编辑之前反映资产的状态。

<强> PHImageRequestOptionsVersionOriginal

  

请求图像资源的原始,最高保真版本。该   生成的图像最初是捕获或导入的版本   资产,无论是否进行任何编辑。

如果在检索资产之前询问用户,则知道用户指定的版本。如果从其他地方获得了phasset,则可以执行revertAssetContentToOriginal来获取原始资产。并且PHAsset具有modificationDate和creationDate属性,您可以使用它来判断PHAsset是否被修改。

答案 2 :(得分:2)

我找到了一种方法来确定是否已编辑PHAsset。使用PHAssetResource API,您可以获取给定资产的数据资源数组。如果照片已被修改,则至少有一个资源是编辑的调整数据。

let adjustmentResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .adjustmentData }
if adjustmentResources.count > 0 {
    //photo has been edited
}

请注意,如果您想要实际使用资源文件,则必须使用PHAssetResourceManager API获取其数据。另请注意,此方法立即返回 - 没有等待异步网络请求,与此处的其他答案不同。

答案 3 :(得分:0)

我发现这个代码是目前唯一正常工作的代码,它处理大多数边缘情况。它可能不是最快的,但适用于大多数图像类型。它采用尽可能小的原始图像和修改后的图像,并比较它们的数据内容。

@implementation PHAsset (Utilities)
- (void)checkEditingHistoryCompletion:(void (^)(BOOL edited))completion
{
    PHImageManager *manager = [PHImageManager defaultManager];

    CGSize compareSize = CGSizeMake(64, 48);

    PHImageRequestOptions *requestOptions = [PHImageRequestOptions new];
    requestOptions.synchronous = YES;
    requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
    requestOptions.version = PHImageRequestOptionsVersionOriginal;

    [manager requestImageForAsset:self
                       targetSize:compareSize
                      contentMode:PHImageContentModeAspectFit
                          options:requestOptions
                    resultHandler:^(UIImage *originalResult, NSDictionary *info) {

                        UIImage *currentImage = originalResult;

                        requestOptions.version = PHImageRequestOptionsVersionCurrent;

                        [manager requestImageForAsset:self
                                           targetSize:currentImage.size
                                          contentMode:PHImageContentModeAspectFit
                                              options:requestOptions
                                        resultHandler:^(UIImage *currentResult, NSDictionary *info) {

                                            NSData *currData = UIImageJPEGRepresentation(currentResult, 0.1);
                                            NSData *orgData = UIImageJPEGRepresentation(currentImage, 0.1);

                                            if (completion) {

                                                //handle case when both images cannot be retrived it also mean no edition
                                                if ((currData == nil) && (orgData == nil)) {
                                                    completion(NO);
                                                    return;
                                                }

                                                completion(([currData isEqualToData:orgData] == NO));
                                            }
                                        }];
                    }];
}

@end