【问题标题】:Get PHAsset from iOS Share Extension从 iOS 共享扩展获取 PHAsset
【发布时间】:2016-03-21 13:33:45
【问题描述】:

我正在为我的 iOS 应用程序开发照片共享扩展程序。在扩展中,我能够成功地从 NSItemProvider 检索 UIImage 对象。

但是,我希望能够与我的容器应用共享图像,而不必将整个图像数据存储在我的共享用户默认值中。有没有办法获取用户在共享扩展中选择的图像的 PHAsset(如果他们从他们的设备中选择)?

关于照片框架 (https://developer.apple.com/library/ios/documentation/Photos/Reference/Photos_Framework/) 的文档中有一行说“这种架构可以轻松、安全且高效地处理来自多个线程或多个应用和应用扩展的相同资产。”

这行让我觉得有一种方法可以在扩展程序和容器应用程序之间共享相同的 PHAsset,但我还没有想出任何方法来做到这一点?有没有办法做到这一点?

【问题讨论】:

    标签: ios phasset phphotolibrary share-extension


    【解决方案1】:

    这仅在 NSItemProvider 为您提供具有以下格式的 URL 时有效:

    file:///var/mobile/Media/DCIM/100APPLE/IMG_0007.PNG

    这并不总是适用于您的所有资产,但如果它返回的 URL 为:

    file:///var/mobile/Media/PhotoData/OutgoingTemp/2AB79E02-C977-4B4A-AFEE-60BC1641A67F.JPG

    那么 PHAsset 将永远找不到您的资产。此外,后者是您文件的副本,因此如果您碰巧有一个非常大的图像/视频,iOS 会将其复制到该 OutgoingTemp 目录中。文档中没有说明何时删除,希望很快。

    我认为这是 Apple 在共享扩展和 PHPhotoLibrary 框架之间留下的巨大差距。 Apple 应该很快就会创建一个 API 来关闭它。

    【讨论】:

    • 我看到应用程序也可以使用 OutgoingTemp,但尚未确定如何使用。
    • @a-r-studios 也许我们可以从文件的元数据(EXIF)中检查图像的创建日期,然后与 PHAsset.creationDate 匹配?
    • 这方面有什么更新吗?我的意思是,我们现在有 2021 年了——苹果应该希望现在已经解决了这个问题,不是吗?
    【解决方案2】:

    如果图像是从照片应用程序共享的,您可以获得 PHAsset。项目提供者将为您提供一个包含图像文件名的 URL,您可以使用它来匹配 PHAsset。

    /// Assets that handle through handleImageItem:completionHandler:
    private var handledAssets = [PHAsset]()
    
    /// Key is the matched asset's original file name without suffix. E.g. IMG_193
    private lazy var imageAssetDictionary: [String : PHAsset] = {
    
        let options = PHFetchOptions()
        options.includeHiddenAssets = true
    
        let fetchResult = PHAsset.fetchAssetsWithOptions(options)
    
        var assetDictionary = [String : PHAsset]()
    
        for i in 0 ..< fetchResult.count {
            let asset = fetchResult[i] as! PHAsset
            let fileName = asset.valueForKey("filename") as! String
            let fileNameWithoutSuffix = fileName.componentsSeparatedByString(".").first!
            assetDictionary[fileNameWithoutSuffix] = asset
        }
    
        return assetDictionary
    }()
    
    ...
    
    provider.loadItemForTypeIdentifier(imageIdentifier, options: nil) { imageItem, _ in
        if let image = imageItem as? UIImage {
          // handle UIImage
        } else if let data = imageItem as? NSData {
          // handle NSData 
        } else if let url = imageItem as? NSURL {
             // Prefix check: image is shared from Photos app
             if let imageFilePath = imageURL.path where imageFilePath.hasPrefix("/var/mobile/Media/") {
                 for component in imageFilePath.componentsSeparatedByString("/") where component.containsString("IMG_") {
    
            // photo: /var/mobile/Media/DCIM/101APPLE/IMG_1320.PNG
            // edited photo: /var/mobile/Media/PhotoData/Mutations/DCIM/101APPLE/IMG_1309/Adjustments/FullSizeRender.jpg
    
                    // cut file's suffix if have, get file name like IMG_1309.
                    let fileName = component.componentsSeparatedByString(".").first!
                    if let asset = imageAssetDictionary[fileName] {
                        handledAssets.append(asset)
                        imageCreationDate = asset.creationDate
                    }
                        break
                    }
                }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多