Photos frameworkを使ってiPhoneアルバム内の写真を取得・削除する+α
先日、ALPACAという写真整理アプリを同僚とリリースしました。
iOS 8から追加されたPhotos framworkを使った、アルバムを爆速で整理できるアプリです。その道程で色々と勉強になったので、メモがてらエントリを書いてみます。
Photos frameworkとは
Photos framework はiOS 8から新たに追加されたフレームワークです。
Assets Library を置き換えるもので、Aseets Library でできる写真の取得はもちろん、検索や削除などが新たにできるようになりました。
Photos frameworkを使ってみる
それでは実装を追っていきます。まずはimportから。
import Photos
以下の変数も定義しておきます。
var photoAssets = [PHAsset]()
アルバム内の写真を取得する
UIはCollectionViewを使って作っています
画像をすべて取得するには以下のように記述します。
private func getAllPhotosInfo() { photoAssets = [] // 画像をすべて取得 var assets: PHFetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: nil) assets.enumerateObjectsUsingBlock { (asset, index, stop) -> Void in self.photoAssets.append(asset as PHAsset) } println(photoAssets) }
fetchAssetsWithMediaType
で欲しいメディアの種類を指定し、リクエストします。指定できるタイプは以下の4種類です。
enum PHAssetMediaType : Int { case Unknown case Image case Video case Audio }
検索の条件を加える
日付の範囲を絞ったり、ソートして取得するにはPHFetchOptions
で指定します。
例えば日時の新しい順に並べるには、以下のようになります:
private func getAllSortedPhotosInfo() { photoAssets = [] // ソート条件を指定 var options = PHFetchOptions() options.sortDescriptors = [ NSSortDescriptor(key: "creationDate", ascending: false) ] var assets: PHFetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: options) assets.enumerateObjectsUsingBlock { (asset, index, stop) -> Void in self.photoAssets.append(asset as PHAsset) } println(photoAssets) }
上記の例ではfetchAssetsWithMediaType
をコールしてますが、他にも色々なfetchの方法があります。詳しくは公式ドキュメントをご参照ください
https://developer.apple.com/library/IOs/documentation/Photos/Reference/PHAsset_Class/index.html#//apple_ref/doc/uid/TP40014383-CH1-SW2
画像を表示する
上記で取得したPHAsset
をつかって画像を表示してみましょう。
let manager: PHImageManager = PHImageManager() manager.requestImageForAsset(asset, targetSize: CGSizeMake(70, 70), contentMode: .AspectFill, options: nil) { (image, info) -> Void in // 取得したimageをUIImageViewなどで表示する }
PHImageManager
を使ってリクエストし、取得した情報をUIImageViewなどに表示すればOKです。
この resultHandler は場合によって複数回コールされます。大きなサイズの写真を表示するときに時間がかかるため、まずサムネを表示→実際のサイズ表示 と、フレームワークの粋な計らいのようです。これを防ぎたい場合は以下のQiitaが参考になります。
画像を削除する
画像を端末から削除するには以下のように実装します。
private func deleteFirstImage() { let delTargetAsset = photoAssets.first as PHAsset? if delTargetAsset != nil { PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in // 削除などの変更はこのblocks内でリクエストする PHAssetChangeRequest.deleteAssets([delTargetAsset!]) }, completionHandler: { (success, error) -> Void in // 完了時の処理をここに記述 }) } }
削除を実行すると以下のような確認アラートが表示されます。
Delete(日本語環境では「許可」)を選択すると写真が削除されます。
削除後30日までは復元可
削除した写真はすぐに消去されず、30日はゴミ箱に残ります。
上記は「写真」アプリの「アルバム > 最近削除した項目」の画面です。
写真ごとに削除されるまでの日数が表示されており、これが0日になると完全に削除されます。
写真を選択して右上の「Revert」ボタンを押すと上の写真の画面になり、
「Revert 3 photos」を選択すると写真がアルバムに復元されます。
写真アクセスの許可を取得する
許可を求めるシステムアラートを表示する
初めて写真を取得する際、「"あなたのアプリ名"が写真への許可を求めています」 と表示されます。この表示のタイミングを自分でコントロールするにはPHPhotoLibrary.requestAuthorization{...}
を呼び出します。詳しくは以下の記事が参考になります。
許可されていない場合は設定画面に遷移させる
アルバム系アプリや写真加工アプリの場合、写真へのアクセスが拒否されていると困ることが多いかと思います。
その場合はURL Schemeで設定画面へ遷移させ、許可してもらいましょう(iOS 8以降)。
// 設定画面へ遷移する let url = NSURL(string: UIApplicationOpenSettingsURLString) UIApplication.sharedApplication().openURL(url!)
↑こういうアラートを表示するなどして、
↑上記のURL Schemeで設定画面へ遷移。
一度「拒否」すると自分で設定画面に辿り着くのは困難ですので、こういう助け舟も用意しておきたいですね。
以上となります。
ソースコード
今回紹介したコードはこちらからDLできます。
まとめ
iOS 8からの新しいフレームワーク「Photos framework」の使い方でした。
これまでより自由度が高くて、いろいろな写真関連のアプリが作れそうですね!
参考リンク