Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
7
Help us understand the problem. What is going on with this article?

More than 3 years have passed since last update.

@Takumi_Mori

Photos.frameworkで画像を保存して保存先を取得

概要

画像を保存するために、これまでUIImageWriteToSavedPhotosAlbumを利用していましたが保存先のURLが欲しくなったので他の方法を調査。
ALAssetsLibraryを利用すれば簡単に保存先が取得できるが、これはiOS9からdeprecated。
そのためPhotos.frameworkを使う必要があったが、通常の方法ではパスが取得できなかった。

実装

参考 : How to get the URL of an image just added in PHPhotoLibrary

var localId:String?
PHPhotoLibrary.shared().performChanges({
    let request = PHAssetChangeRequest.creationRequestForAsset(from: result)
    localId = request.placeholderForCreatedAsset?.localIdentifier
}, completionHandler: { (granted, error) in
    DispatchQueue.main.async {
        if let localId = localId {
            let results = PHAsset.fetchAssets(withLocalIdentifiers: [localId], options: nil)
            if results.count > 0 {
                let asset = results.firstObject
            }
        }
    }
})

ここまでやって、ようやくPHAssetを取得できるのであとは以下のようなextensionを使って取得する。なんでこんなに複雑になったのか・・・。

参考 : How to get URL for a PHAsset?

以下のコードを、例えばPHAssetExtension.swiftなどのファイルで保存するなり書くなり。

import Photos

extension PHAsset {

    func getURL(completionHandler : @escaping ((_ responseURL : URL?) -> Void)){
        if self.mediaType == .image {
            let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
            options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
                return true
            }
            self.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [AnyHashable : Any]) -> Void in
                completionHandler(contentEditingInput!.fullSizeImageURL as URL?)
            })
        } else if self.mediaType == .video {
            let options: PHVideoRequestOptions = PHVideoRequestOptions()
            options.version = .original
            PHImageManager.default().requestAVAsset(forVideo: self, options: options, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) -> Void in
                if let urlAsset = asset as? AVURLAsset {
                    let localVideoUrl: URL = urlAsset.url as URL
                    completionHandler(localVideoUrl)
                } else {
                    completionHandler(nil)
                }
            })
        }
    }
}

追記

実際にはあとからPHAssetを復旧させるつもりでURLが欲しかったんですが、これで取れるのは画像の実態があるfile保存先URLだったのでちょっと違った。
そのため、assetlocalIdentifierを保存して、そこから復旧する形に変更しました。

7
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
7
Help us understand the problem. What is going on with this article?