写真アプリの写真タブ
最近猫の写真ばかり増大中なのですが、以下画像の通りのような表示になっていて、これはどのように取得するものなのだろうかと調べてみた。ポイントだけですが、わかってみるとなーんだというものです。
ちなみに、分類別やカテゴリという言葉を使っていますが、公式でそのように表現されているわけでは無いと思いますので、適当に脳内変換して読み進めていただければ助かります。
PHCollectionList というクラス
ユーザが作成したアルバム情報などを得るために利用できる用途で結構利用されているようです。なので、写真アプリのアルバムタブで表示されている情報を取得する際には、以下のような感じにすると良いでしょう。ただ、日本語版では、「お気に入り」など日本語表示されたアルバム名称を取得する方法がわからなく、英語で取得されるため、アプリ内部で独自に変換する必要があるのかが不明です。
let debugCollection: ((_ coll: PHAssetCollection) -> Void) = {
(coll) in
if let title = coll.localizedTitle {
print(" <\(title)>")
}
if let sd = coll.startDate {
print(" \(sd)")
}
if let ed = coll.endDate {
print(" \(ed)")
}
if let loc = coll.approximateLocation {
print(" \(loc)")
}
let names = coll.localizedLocationNames
for name in names {
print(" ==\(name)==")
}
}
// デバッグ用情報印字
let debugPrint: ((_ res: PHFetchResult<PHAssetCollection>) -> Void) = {
(res: PHFetchResult<PHAssetCollection>) in
res.enumerateObjects() {
(data,index,stop) -> Void in
print(" -[\(index)] (\(data.estimatedAssetCount))")
debugCollection(data)
}
}
let userAlbums = PHCollectionList.fetchTopLevelUserCollections(with: nil)
debugPrint(userAlbums as! PHFetchResult<PHAssetCollection>)
分類(モーメント、コレクション、年別)別表示方法
内容が無いので、上記情報も提示していますが、写真タブのモーメント、コレクション、年別の情報取得の仕方です。
- モーメント
let opt = PHFetchOptions()
opt.sortDescriptors = [
NSSortDescriptor(key: "startDate", ascending: true)
]
let momlist = PHCollectionList.fetchMomentLists(with: .momentListCluster, options: opt)
momlist.enumerateObjects {
(data, index, stop) in
// 画像(サムネイル)は以下で取得する必要がある
// 画像の取得方法は、ここでは提示しない
let moment = PHAssetCollection.fetchMoments(inMomentList: data, options: opt)
debugPrint(moment)
}
上記titleに各カテゴリとして表示する文字列が得られます。上記画像の「自宅」がそれですが、コードとしては、「Home」となります。これも日本語の自宅に変換する方法を見つけられていません。
カテゴリのサブタイトルは日付と地名が記載されている。日付の日本語化はDateクラスやDateFormatter,Calendarクラスなどを利用する。参照:https://qiita.com/rinov/items/bff12e9ea1251e895306
サブタイトルの地名は配列で取得できるが、表示上は「と」で接続されている、表示しきれない場合(あるいは最大個数を超えた場合)は「その他n件」といった表現に変換している(コードで変換しているのか、変換方法を提供されているのかは不明)
モーメントの情報だけであれば、上記の方法よりも簡単な(数行違いの)方法が実はありまして、以下のようにすれば良いです。
let moment = PHAssetCollection.fetchMoments(with: opt)
debugPrint(moment)
- コレクション
これのコードは基本的にモーメントの最初のコードと同じで、カテゴリ部分の情報を取得してあげれば良いです。
let opt = PHFetchOptions()
opt.sortDescriptors = [
NSSortDescriptor(key: "startDate", ascending: true)
]
let momlist = PHCollectionList.fetchMomentLists(with: .momentListCluster, options: opt)
momlist.enumerateObjects {
(data, index, stop) in
// .momentListYearを指定すると、年ごとで取得できる
// title:各カテゴリのタイトルが取得される
if let title = data.localizedTitle {
print("#\(title)#")
}
// コレクションでカテゴリのサブタイトルの日付
if let sd = data.startDate {
print("[\(sd) -")
}
if let ed = data.endDate {
print(" - \(ed)]")
}
// コレクションでカテゴリのサブタイトルの地名
// 細かな点で日本語化するには工夫が必要となりそう
let names = data.localizedLocationNames
for name in names {
print(" ==\(name)==")
}
// 画像(サムネイル)は以下で取得する必要がある
// 画像の取得方法は、ここでは提示しない
let moment = PHAssetCollection.fetchMoments(inMomentList: data, options: opt)
debugPrint(moment)
}
- 年別
年別の場合、以下引数を変更するのみで、基本内容は同じです。
let momlist = PHCollectionList.fetchMomentLists(with: .momentListYear, options: opt)
おまけ
画像を取得する場合、debugCollection にあるcollを利用し、以下のコードにあるassetsから取得が可能となります。
let opt = PHFetchOptions()
opt.sortDescriptors = [
NSSortDescriptor(key: "creationDate", ascending: true)
]
let assets = PHAsset.fetchAssets(in: coll, options: opt)