取得したCore Dataのデータは、各項目内のプロパティを使用して分類することができます。
例えば、日別のToDo項目を保存している場合、日別に分類し、リストの異なるセクションに表示することができます。
あるいは、異なるカテゴリーに基づいて収納する場合にも することもできます。
ステップ1.キー識別子として文字列を作成する
まず、各カテゴリーがそれを説明する文字列を持っていることに注目してください。
たとえば、項目を日付(これは Date オブジェクトです)で割ると、それを文字列に変換できます(7月2日のように)。
これは、Core Data オブジェクトに拡張機能を追加することで可能になります。
extension Item {
@objc
var dateText: String {
guard let date = self.dueDate else {
return "Unknown"
}
return DateFormatter.localizedString(from: date, dateStyle: .short, timeStyle: .none)
}
}
この文字列は、グループ化のためのキー(識別子)としても使われるし、UI表示の目的(テーブルビュー内のセクションタイトル)にも使われる。
ステップ2. セクション化されたフェッチリクエスト @SectionedFetchRequest
を作成する
@FetchRequest
の代わりに、@SectionedFetchRequest
を使用します。
@SectionedFetchRequest<String, Item>(
sectionIdentifier: \.dateText,
sortDescriptors: [SortDescriptor(\.date, order: .reverse)]
)
private var itemSections: SectionedFetchResults<String, Item>
ここでは、各セクションの識別子(キー)は dateText
の値になります(つまり、2つのCore Dataの項目が同じキー(同じdateTextの値)を持っていれば、一緒にグループ化されることになります)。
また、この識別子を変更することで、異なるグループ分けを行うこともできます。
例えば、カテゴリごとにグループ化することができる。
sortDescriptors
は、結果配列の並び順を記述します。
ここでは、日付の逆順に基づいてソートしています。
ステップ3.結果をループで処理する
変数 itemSections
の値は、グループ (セクション) の配列になります。
まず、すべてのグループに対してループ処理を行います。
ForEach(itemSections) { itemSection in ... }
各グループに対して、 .id
変数で識別子を読み込んで表示します(この例では、 dateText
の結果です)。
それから、各グループをループしてアイテムを取得することができます。
たとえば、異なるグループのすべてのエントリを表示するSwiftUIのコードは次のとおりです。
ForEach(itemSections) { itemSection in
Section(itemSection.id) {
ForEach(itemSection) { itemEntry in
VStack(alignment: .leading) {
Text(itemEntry.content ?? "")
.font(.headline)
Text(itemEntry.dateText)
}
}
}
}
2つのセクションがあり(日の文字列 dateText
を基準にグループ化)、セクションのタイトルが識別子となります。
同じロジックをUIKitアプリケーションに適用することができます。
コード例
テストレコードを追加するボタンがあります。
また、Core Dataのエントリーをカテゴリーや時間に基づいてグループ化する機能があります。
カテゴリに基づくグループ化のためのXcodeプロジェクトのサンプルです
日付を基準にグループ化するためのXcodeプロジェクトのサンプルです
関連記事 (Core Data)
お読みいただきありがとうございました。
☺️ Twitter @MszPro
🐘 Mastodon @me@mszpro.com