0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftDataで1:多(one to many relationship)のモデル作ったよ。子要素が更新されない問題が発生したけど、なぜか解決したよ!

Posted at

はじめに

レーダーチャートを作成・管理できるアプリを作成しました。
「amime(読み方:あみめ)」です。
このアプリでは例えば「居酒屋」というグループが親になり、その子として実際のお店「磯丸水産」や「鳥貴族」などの子の評価をそれぞれ設定し、レーダーチャートで表示することができます。

この記事では1:多のモデル定義とその問題点について記載してあります。
実際にアプリを操作してみると、よりイメージを掴みやすいと思うので、是非ダウンロードしてみてください!

1:多のモデル定義

import SwiftUI
import SwiftData

@Model
final class Template: Identifiable { // ←←← 居酒屋
    @Attribute(.unique) var id: UUID
    var title: String
    var category: [String]
    @Relationship(deleteRule: .cascade, inverse: \Chart.template) var charts: [Chart]

    init(title: String, category: [String], charts: [Chart] = []) {
        self.id = UUID()
        self.title = title
        self.category = category
        self.charts = charts
    }

    init(id: UUID, title: String, category: [String], charts: [Chart] = []) {
        self.id = id
        self.title = title
        self.category = category
        self.charts = charts
    }
}

@Model
final class Chart: Identifiable, Hashable { // ←←← 磯丸水産、鳥貴族
    var template: Template
    var title: String
    var data: [String : Double]
    
    init(template: Template, title: String, data: [String : Double]) {
        self.template = template
        self.title = title
        self.data = data
    }
    
    // Hashableの準拠に必要なメソッド
    static func == (lhs: Chart, rhs: Chart) -> Bool {
        return lhs.title == rhs.title && lhs.data == rhs.data
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
        hasher.combine(data)
    }
}

こちらがソースコードになります。
@Relationshipで親子関係を定義できます。

でも、ちょっと待った!
実はこのソースコードだと、子要素を追加した際、画面の再描画がされないんです!

問題点

実は、上記ソースコードだと、子要素を追加してもリストに表示されないんです。
でもアプリを再起動するとリストに表示されるので、データの永続化はできているけど、データの再取得がされていないんです!

解決策

@Model
final class Chart: Identifiable, Hashable {
-   var template: Template
+   var template: Template?
    var title: String
    var data: [String : Double]
    
    init(template: Template, title: String, data: [String : Double]) {
        self.template = template
        self.title = title
        self.data = data
    }
    
    // Hashableの準拠に必要なメソッド
    static func == (lhs: Chart, rhs: Chart) -> Bool {
        return lhs.title == rhs.title && lhs.data == rhs.data
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
        hasher.combine(data)
    }
}

これで解決するんです!
でも、何故かは分かりません!
誰か教えてください!

解決策を見つけたサイト:https://stackoverflow.com/questions/78528965/swiftdata-does-not-retrieve-my-inverse-one-to-many-relationship

さいごに

SwiftDataを利用して1:多の関係性を表現することができました。
この記事が誰かの役に立つことを願っています。

おわり

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?