🎉

SwiftData×SwiftUIでCircleモデルを構築&一覧表示まで実装

に公開

✍️ 今日の学習ログ

  • データモデル設計Circle に必要な属性を整理
  • SwiftData実装@Model 属性でローカル永続化
  • ModelContainer設定:アプリ起動時に永続ストアを登録
  • @Query + List表示:データを自動フェッチして一覧化
  • Preview対応:プレビュー用に inMemory コンテナを注入

🔍 目次

  1. データモデル設計
  2. SwiftDataで@Model実装
  3. ModelContainerのセットアップ
  4. @Queryで一覧取得&List表示
  5. Preview対応のコツ
  6. 今日の気づき・次のステップ

1. データモデル設計

まずは「サークル紹介アプリで管理したい情報」を洗い出し。
MVPとして最低限必要なのは以下の6項目に絞りました。

プロパティ 説明
name String サークル名
isIntercollegiate Bool インカレ(true)/学内(false)
genre String ジャンル(スポーツ/文化系など)
introduction String 紹介文
imageURL String 画像URL
likeCount Int いいね数

2. SwiftDataで@Model実装

上記を踏まえて、Circle.swift@Model クラスを定義。

import Foundation
import SwiftData

@Model
class Circle {
    var name: String
    var isIntercollegiate: Bool
    var genre: String
    var introduction: String
    var imageURL: String
    var likeCount: Int
    var createdAt: Date

    init(
        name: String,
        isIntercollegiate: Bool,
        genre: String,
        introduction: String,
        imageURL: String,
        likeCount: Int = 0,
        createdAt: Date = .now
    ) {
        self.name = name
        self.isIntercollegiate = isIntercollegiate
        self.genre = genre
        self.introduction = introduction
        self.imageURL = imageURL
        self.likeCount = likeCount
        self.createdAt = createdAt
    }
}
  • @Modelclass の組み合わせで、CRUD操作がほぼボイラープレート不要に
  • createdAt を持たせることで後からソートやデバッグに活用可

3. ModelContainerのセットアップ

アプリ起動時に SwiftData の管理対象モデルを指定します。

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(for: [Circle.self])
    }
}
  • for: [Circle.self] で永続化対象を登録
  • 複数モデルが増えたら配列に追加するだけでOK

4. @Queryで一覧取得&List表示

View 側では @Query を使って自動でデータをフェッチし、List で表示。

struct ContentView: View {
    @Environment(\.modelContext) private var context
    @Query private var circles: [Circle]

    var body: some View {
        NavigationView {
            List {
                ForEach(circles) { circle in
                    VStack(alignment: .leading) {
                        Text(circle.name)
                            .font(.headline)
                        Text(circle.genre)
                            .font(.subheadline)
                        Text(circle.introduction)
                            .font(.caption)
                            .foregroundColor(.gray)
                    }
                }
            }
            .navigationTitle("サークル一覧")
            .toolbar {
                Button("モック追加") {
                    let mock = Circle(
                        name: "テニスサークルAO",
                        isIntercollegiate: true,
                        genre: "スポーツ",
                        introduction: "初心者歓迎!週2で活動してます!",
                        imageURL: "https://example.com/image.jpg"
                    )
                    context.insert(mock)
                }
            }
        }
    }
}
  • @QueryCircle の全レコードを自動取得
  • context.insert(...) でモックデータを永続化

5. Preview対応のコツ

プレビューで SwiftData を動かすには、inMemoryコンテナを注入します。

#Preview {
    ContentView()
        .modelContainer(for: Circle.self, inMemory: true)
}
  • inMemory: true で実機保存を使わず、プレビュー内だけのテストストアに
  • これがないと @Query が動かずにクラッシュ or 空配列になります

6. 今日の気づき・次のステップ

  • 気づき

    • @Model × SwiftData はボイラープレートが激減して快適
    • @Query の自動更新で手動フェッチいらず
    • Preview用の inMemory 設定を忘れると地獄を見る
  • 次のステップ

    1. Userモデル を SwiftDataで実装
    2. Applicationモデル(入部申請)を追加
    3. サークル詳細画面+申請ボタンの組み込み

✨ 今日の実装で「データ設計→保存→一覧表示」まで一気に繋がりました!
次は申請機能も盛り込んで、マッチング要素に踏み込んでいきます💪

Discussion