How to know if a PHAsset has been modified?

I have found a way to determine whether a PHAsset has been edited or not. Using a PHAssetResource API, you can get an array of data resources for a given asset. If the photo has been modified, it will have at least one resource that is the adjustment data of an edit.

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

Note that if you want to actually work with a resource file, you have to fetch its data using a PHAssetResourceManager API. Also note that this method returns right away - there's no waiting for an async network request, unlike the other answers here.


I have found two ways of checking PHAsset for modifications.

- (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/"]);
    }];
}

EDIT: I was at the point where I needed the same functionality for PHAsset with an image. I used this:

- (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/"]);
     }];
}

Take a look at PHImageRequestOptionsVersion

PHImageRequestOptionsVersionCurrent

Request the most recent version of the image asset (the one that reflects all edits). The resulting image is the rendered output from all previously made adjustments.

PHImageRequestOptionsVersionUnadjusted

Request a version of the image asset without adjustments.
If the asset has been edited, the resulting image reflects the state of the asset before any edits were performed.

PHImageRequestOptionsVersionOriginal

Request the original, highest-fidelity version of the image asset. The resulting image is originally captured or imported version of the asset, regardless of any edits made.

If you ask user before retrieving assets, you know which version user specified. If you get a phasset from elsewhere, you can do a revertAssetContentToOriginal to get the original asset. And PHAsset has modificationDate and creationDate properties, you can use this to tell if a PHAsset is modified.