リレーショナルなデータをローカル保存するための定番はSQLite。それに加えてiOSにはCoreDataという選択肢もある。CoreDataも中身はSQLiteデータベースに保存されるが隠蔽されている。どちらを使うのが良いか。
結論から言うと、単にローカルに保存するだけなら、個人的にはSQLiteで良いと思いました。SQLiteに馴染みがあるなら、なおさらのこと。
SQLiteで実装する場合、モデルクラスとDBにアクセスするDAOクラスの2つを用意するなどの方法があります。
- Person
- id
- name
- age
- PsersonDAO
- findAllPerson()
- findPersonByName(name: String)
- insertPerson(person: Person)
- updatePerson(person: Person)
DAOの各メソッドでSQLiteへのアクセスを書いて、モデルクラスからオブジェクトとして具現化する。PersonクラスのプロパティをどれだけいじろうがDAOのinsertPerson/updatePersonメソッドに渡さないかぎりDBには影響がない。また、これらのメソッドを呼んでもPerson以外のモデルには影響がない。
これに対してCoreDataのモデルは、NSManagedObjectを継承したクラスとなる。そしてプロパティをいじった後に、NSManagedObjectContext#saveを呼んだら、このContextにひもづくモデルオブジェクトすべてが保存される。
モデルオブジェクトは、いろんな画面で持つことになる。ある画面でプロパティを表示上一時的にプロパティをいじるが保存はしたくないようなこともある。SQLiteの例では、このことはたいして問題にならない。
しかしCoreDataのモデルを複数の画面で持つと、ある画面で保存ボタンを押した時に、NSMangedObjectContext#saveを呼ぶと、保存する意図のなかった画面のオブジェクトの方も保存されてしまう。そうならないための一番てっとり早い方法は、結局こうなるのではないか。
- Person
- id
- name
- age
- PersonMO(NSManagedObjectのサブクラス)
- id
- name
- age
- PsersonDAO
- findAllPerson()
- findPersonByName(name: String)
- insertPerson(person: Person)
- updatePerson(person: Person)
PersonDAOでのみPersonMOを通じてCoreDataへの読み書きを行い、DAOから外はNSManagedObjectContextとひもづかないPersonオブジェクトを使う。つまりViewControllerではPersonオブジェクトを保持するようにする。
このように実装するなら結局、SQLiteを使うのとコストはあまり変わらないし、パフォーマンスも良いだろう。さらにSQLiteを直接使うので、SQLiteでできることは何でもできる。
ただし、iCloudで複数端末で同期したい場合は、CoreDataを使ったほうが楽である。CoreDataを使うだけでマージを除く同期の大部分はSDKレベルで勝手にやってくれる。