今回も先日作ったシンプルTodoアプリを例に解説していく。

【SwiftUI】CoreDataを使ったTodoアプリにスワイプによる削除機能を追加する

CoreDataでデータの取得をする場合、FetchRequestを使用して以下のようにおこなう。

@FetchRequest(
  sortDescriptors: [NSSortDescriptor(keyPath: \Task.name, ascending: false)],
  animation: .default
)
var tasks: FetchedResults<Task>

ただ、この例の場合はキーがTask.nameとなっているため、実際にタスクを追加していくと、登録したタスク名によってリストに追加される位置がバラバラになってしまう。

まず、Test1、Test2の順でタスクをあらかじめ登録した画面がこちら。

ここにHogeを追加してみる。

するとHogeが最下部に追加されてしまう。

登録したタスク名によって追加される位置が異なってしまうのは挙動としておかしいので、これを改善していく。

オブジェクトのID順に並び替える

FetchRequestの条件を以下のように書き換える。

@FetchRequest(
  sortDescriptors: [NSSortDescriptor(keyPath: \Task.objectID, ascending: true)],
  animation: .default
)
var tasks: FetchedResults<Task>

keyPathにエンティティのobjectIDを指定しているところがポイント。

CoreDataはデータを生成したときに一意のオブジェクトIDが発行されるので、これをキーにすることで登録した順にソートしたデータ一覧を取得することができる。

一度登録したタスクを全て削除し、再度Test1、Test2、Hogeの順で登録すると、期待どおりの動作になっていることが分かる。