Retrieve ALAsset or PHAsset from file URL

2019-01-15 14:21发布

问题:

Selecting images in Photos.app to pass to an action extension seems to yield paths to images on disk (e.g.: file:///var/mobile/Media/DCIM/109APPLE/IMG_9417.JPG). Is there a way to get the corresponding ALAsset or PHAsset?

The URL looks like it corresponds to the PHImageFileURLKey entry you get from calling PHImageManager.requestImageDataForAsset. I'd hate to have to iterate through all PHAssets to find it.

回答1:

I did what I didn't want to do and threw this dumb search approach together. It works, although it's horrible, slow and gives me memory issues when the photo library is large.

As a noob to both Cocoa and Swift I'd appreciate refinement tips. Thanks!

func PHAssetForFileURL(url: NSURL) -> PHAsset? {
    var imageRequestOptions = PHImageRequestOptions()
    imageRequestOptions.version = .Current
    imageRequestOptions.deliveryMode = .FastFormat
    imageRequestOptions.resizeMode = .Fast
    imageRequestOptions.synchronous = true

    let fetchResult = PHAsset.fetchAssetsWithOptions(nil)
    for var index = 0; index < fetchResult.count; index++ {
        if let asset = fetchResult[index] as? PHAsset {
            var found = false
            PHImageManager.defaultManager().requestImageDataForAsset(asset,
                options: imageRequestOptions) { (_, _, _, info) in
                    if let urlkey = info["PHImageFileURLKey"] as? NSURL {
                        if urlkey.absoluteString! == url.absoluteString! {
                            found = true
                        }
                    }
            }
            if (found) {
                return asset
            }
        }
    }

    return nil
}


回答2:

So this is commentary on ("refinement tips") to your auto-answer. SO comments don't cut it for code samples, so here we go.

  1. You can replace your for-index loop with a simpler for-each loop. E.g. something like:

    for asset in PHAsset.fetchAssetsWithOptions(nil)
    
  2. As of the last time I checked, the key in info["PHImageFileURLKey"] is undocumented. Be apprised. I don't think it will get you rejected, but the behavior could change at any time.