概要
画像を保存するために、これまで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だったのでちょっと違った。
そのため、asset
のlocalIdentifier
を保存して、そこから復旧する形に変更しました。