【Swift/Core Data】RelationShipの実装方法!テーブル連携
この記事からわかること
- SwiftでCore Dataを利用する方法
- エンティティ(NSManagedObject)にRelationShipを設定する方法
- 一対一や一対多などのリレーションの実装
- Inverseとは?
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- iOS:17.0
- Swift:5.9
- macOS:Sonoma 14.1
RelationShipとは?
RelationShipとは異なるテーブル同士の関係を紐付けることです。これにより複数のテーブルがまるで1つのテーブルのように扱うことができ、レコード(行)に重複した情報を持たせる必要がなくなるため、スッキリとしたデータ構造で管理することができるようになります。例えばPerson
テーブルとCompany
テーブルがある場合、RelationShipを活用することで人の情報と会社の情報を切り離して定義することができるようになります。
以下のテーブルではPersonテーブルの「会社」で関係が紐づいています。
Personテーブル
id | 名前 | 年齢 | 会社 |
---|---|---|---|
1 | 吉田 真紘 | 27 | ABCデザイン |
2 | 長谷 慎二 | 34 | ABCデザイン |
3 | 川本 依 | 17 | XYZ制作 |
Companyテーブル
id | 名前 | 所在地 |
---|---|---|
1 | ABCデザイン | 東京都 |
2 | XYZ制作 | 神奈川県 |
RelationShipのタイプ
RelationShipには関係性の違いから3つのタイプに分かれています。
一対一リレーションシップ
各レコードが別のテーブル内のただ一つのレコードと関連付けられている状態。例えば、Personから見てCompanyは一対一リレーションシップの関係になる
一対多リレーションシップ
あるテーブルの一つのレコードが別のテーブル内の複数のレコードと関連付けられている状態。Companyには複数のPersonが紐づいているので一対多リレーションシップの関係になる
多対多リレーションシップ
両方のテーブルが複数のレコード同士を関連付けている状態。学生と科目のような関係で、1人の学生が複数の科目を取り、1つの科目が複数の学生によって選ばれる場合に多対多リレーションシップの関係になる
Core DataでRelationshipを実装する方法
Core Dataでエンティティ(テーブル)同士のRelationshipを実装するには「プロジェクト名.xcdatamodel」から設定します。まずはPerson
エンティティとCompany
エンティティをそれぞれ定義します。この際にPerson
エンティティにcompany
属性を定義する必要はありません。
定義できたらまずはPerson
エンティティを選択した状態で「Relationships」の「+」をクリックし、以下のように入力します。「Relationship」はlowercase記法で入力する必要があります。
Relationship | Destination | Inverse |
---|---|---|
company | Company | 未選択 |
続いてCompany
エンティティを選択し同様に「Relationships」の「+」をクリックし以下のように入力します。
Relationship | Destination | Inverse |
---|---|---|
person | Person | company |
これでエンティティ同士の一対一での紐付けが完了し、Person
側の「Inverse」も自動でperson
に変更されます。ビルドするとプロパティファイルも自動で以下のように更新されCompany
プロパティが追加されていることを確認できます。
extension Person {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Person> {
return NSFetchRequest<Person>(entityName: "Person")
}
@NSManaged public var age: Int16
@NSManaged public var id: UUID?
@NSManaged public var name: String?
@NSManaged public var company: Company?
}
Inverse:相互リレーション
「Inverse」では相互リレーション(逆関係)の設定を行なっています。相互リレーションとは片側のエンティティを追加や削除した場合に相互リレーション関係のエンティティが自動で更新されるようにする仕組みです。
これを設定しておくことでデータを操作したことによる齟齬を減らせることができるので、適切なInverse先を指定しておくことをお勧めします。
一対多リレーションを実装する
今回ではPerson→Company
は一対一ですが、Company→Person
は一対多の関係にしたいのでもう少し設定していきます。
一対多リレーションを実装するにはCompany
エンティティを選択し追加した「Relationships」を選択した状態で右側のインスペクタエリアから「To Many」を選択します。
これで一対多リレーションの実装は完了なので一度ビルドするとプロパティファイルが更新されNSSet(Set)
型でPerson
を保持するプロパティが追加されていることを確認できます。
extension Company {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Company> {
return NSFetchRequest<Company>(entityName: "Company")
}
@NSManaged public var id: UUID?
@NSManaged public var location: String?
@NSManaged public var name: String?
@NSManaged public var person: NSSet?
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。