12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-01-23

概要

画像を保存するために、これまで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を保存して、そこから復旧する形に変更しました。

12
8
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?