【SwiftUI】今どきの データモデル (Model data) のマクロ記述 📝

ネットで参考になりそうなコード記述を探すと、

新旧入り乱れてる感じがしたので、

まず読んでおいたほうがいいような気がした。

👉 Platforms State of the Union (ASL) - WWDC23 - Videos - Apple Developer hatena-bookmark

公式ドキュメントにもしっかり説明があるようなので、ざっくり古いかもしれない記述を整理しておく。


Managing user interface state | Apple Developer Documentation
👉 https://developer.apple.com/documentation/swiftui/managing-user-interface-state

Managing model data in your app | Apple Developer Documentation
👉 https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app

Migrating from the Observable Object protocol to the Observable macro | Apple Developer Documentation
👉 https://developer.apple.com/documentation/swiftui/migrating-from-the-observable-object-protocol-to-the-observable-macro

 

📝 まとめ


: ObservableObject   →   @Observable
@Published           →   不要
@StateObject         →   @State
.environmentObject() →   .environment()
@EnvironmentObject   →   @Environment
@ObservedObject      →   不要 or @Bindable

→ 「@Published*Object があれば古い。」

SwiftData を使うにしても、まずは SwiftUI のみの記述の変遷の知識もいるよな ?

先人たちの作ったネットリソースや AI系コードサジェスチョンを効率的に利用するためにも。

次は SwiftData です。


【Xcode】Refactor - Rename ができない - Rename failed ✏️

これ。

どうやら、


~/Library/Developer/Xcode/DerivedData

を消せば良いそうです。

👉 【Xcode】Auto-Completion がおかしい 不具合の理由 → DerivedData hatena-bookmark
👉 Xcodeでリファクタリングに失敗するRename failed #Swift - Qiita hatena-bookmark

 

✏️ Behavors に登録しておく

すぐに忘れて毎回調べているので忘れないように登録しておきます。

まず、スクリプトファイルを作成しておいて、


#!/usr/bin/env bash

rm -rf ~/Library/Developer/Xcode/DerivedData
afplay /System/Library/Sounds/Glass.aiff

左上メニュー Xcode から Behavior に追加。

実行してから音がなるまで結構時間がかかるので、

結構な量のファイルが削除されていることが分かります。

 

✏️ まとめ

あと、

消した DerivedData は再び自動で作成される

Clean Build Folder では DerivedData は消えません

とのことです。


【SwiftUI】View プロパティの記述

これ、みんなフツーに書いてるけど。

これだけ。


struct ToggleView: View {
  @State var isOn = true

  var body: some View {
    Toggle(isOn ? "ON" : "OFF", isOn: $isOn)
  }
}

スゴイよね、SwiftUI。

 

📱 プロパティの記述

これよ。


@State var isOn = true

プロパティの記述をざっくり考えると、


[@State] [public|private] {let|var} isOn[: Bool] [= true]

となり、数十通りあるのに!

いくつか書き出して試してみます。


let isOn: Bool
let isOn: Bool = true
var isOn: Bool 
var isOn: Bool = true
private let isOn: Bool
private let isOn: Bool = true
private var isOn: Bool 
private var isOn: Bool = true
@State let isOn: Bool
@State let isOn: Bool = true
@State var isOn: Bool 
@State var isOn: Bool = true 
@State private let isOn: Bool
@State private let isOn: Bool = true
@State private var isOn: Bool 
@State private var isOn: Bool = true

 

📱 結果


// Cannot find '$isOn' in scope

let isOn: Bool
let isOn: Bool = true
var isOn: Bool 
var isOn: Bool = true
private let isOn: Bool
private let isOn: Bool = true
private var isOn: Bool 
private var isOn: Bool = true

→ Toggle() の2番目の引数 $isOn が見つからない。


// Property wrapper can only be applied to a 'var'

@State let isOn: Bool
@State let isOn: Bool = true
@State private let isOn: Bool
@State private let isOn: Bool = true

→ @State には var しか使えない。


// Missing argument for parameter 'isOn' in call

@State var isOn: Bool

→ isOn の中身がない。


// Missing argument for parameter 'isOn' in call
// 'ToggleView' initializer is inaccessible due to 'private' protection level

@State private var isOn: Bool

→ isOn の中身がない。
→ private なのでイニシャライザーがアクセスできません。


// OK

@State var isOn: Bool = true
@State private var isOn: Bool = true

→ OK

 

📱 まとめ

Property wrapper は var 。

中身が変わるからかな。