获取 URL 个新创建的资产,iOS 9 种样式

Get URL of a newly created asset, iOS 9 style

ALAssetsLibrary 这些天已被弃用,但实际上 SO 上的所有示例仍在使用它。对于我的 objective,我需要知道添加到照片库的视频的 URL,以便我可以将视频分享到 Instagram 应用程序(这是 Instagram 接受视频的唯一方式)。 URL 应该以 "assets-library://..."

开头

这很简单 ALAssetsLibrary:

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:videoFilePath completionBlock:^(NSURL *assetURL, NSError *error) {  // ...

上面,URL 作为参数传递给完成块。但是 iOS 9 与 PHPhotoLibrary class 和 performChanges 方法兼容的方法呢?

var videoAssetPlaceholder:PHObjectPlaceholder!  // property

// ...

let videoURL = NSBundle.mainBundle().URLForResource("Video_.mp4", withExtension: nil)!

let photoLibrary = PHPhotoLibrary.sharedPhotoLibrary()
photoLibrary.performChanges({
    let request = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(videoURL)
    self.videoAssetPlaceholder = request?.placeholderForCreatedAsset
},
completionHandler: { success, error in
    if success
    {
        // The URL of the video asset?
    }
})

这是我最终得到的结果:

let videoURL = NSBundle.mainBundle().URLForResource("Video_.mp4", withExtension: nil)!

let photoLibrary = PHPhotoLibrary.sharedPhotoLibrary()
var videoAssetPlaceholder:PHObjectPlaceholder!
photoLibrary.performChanges({
    let request = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(videoURL)
    videoAssetPlaceholder = request!.placeholderForCreatedAsset
},
completionHandler: { success, error in
    if success {
        let localID = videoAssetPlaceholder.localIdentifier
        let assetID =
            localID.stringByReplacingOccurrencesOfString(
                "/.*", withString: "",
                options: NSStringCompareOptions.RegularExpressionSearch, range: nil)
        let ext = "mp4"
        let assetURLStr =
            "assets-library://asset/asset.\(ext)?id=\(assetID)&ext=\(ext)"

        // Do something with assetURLStr
    }
})

很好的答案和伪造的,谢谢 Desmond。

这是更新后的答案:

Swift 3

var assetPlaceholder: PHObjectPlaceholder!
    PHPhotoLibrary.shared().performChanges({
        let assetRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL as URL!)
        assetPlaceholder = assetRequest?.placeholderForCreatedAsset
    }, completionHandler: { (success, error) in
        if success {
            let localID = assetPlaceholder.localIdentifier
            let assetID = localID.replacingOccurrences(of: "/.*", with: "", options: NSString.CompareOptions.regularExpression, range: nil)
            let ext = "mp4"
            let assetURLStr = "assets-library://asset/asset.\(ext)?id=\(assetID)&ext=\(ext)"

            // Do what you want with your assetURLStr
        } else {
            if let errorMessage = error?.localizedDescription {
                print(errorMessage)
            }
        }
    })

更进一步

虽然目前这很完美,但如果没有这个 "manual" 解决方案,有人会知道 "cleaner" 获得这个 "assets-library" URL 的方法吗?

我找到了这个 interesting thread,但它只给出了 "file:///var/..." URL