从文件 URL 中检索 ALAsset 或 PHAsset

Retrieve ALAsset or PHAsset from file URL

选择 Photos.app 中的图像以传递给动作扩展似乎会生成磁盘上图像的路径(例如:file:///var/mobile/Media/DCIM/109APPLE/IMG_9417.JPG)。有没有办法得到对应的ALAsset或PHAsset?

URL 看起来对应于您通过调用 PHImageManager.requestImageDataForAsset 获得的 PHImageFileURLKey 条目。我讨厌必须遍历所有 PHAsset 才能找到它。

我做了我不想做的事,把这种愚蠢的搜索方法放在一起。它可以工作,尽管它很糟糕,速度很慢,并且当照片库很大时会给我带来记忆问题。

作为 Cocoa 和 Swift 的菜鸟,我希望得到改进提示。谢谢!

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
}

这是对 ("refinement tips") 您的自动回答的评论。所以评论不会为代码示例削减它,所以我们开始吧。

  1. 您可以将 for-index 循环替换为更简单的 for-each 循环。例如。类似于:

    for asset in PHAsset.fetchAssetsWithOptions(nil)
    
  2. 截至我上次检查时,info["PHImageFileURLKey"] 中的密钥未记录在案。被告知。我不认为这会让你被拒绝,但行为可能随时改变。