Swift UI CoreDataのサンプルプロジェクトを解説
表題の通りダルいが解説
ContentsView構造体定義からbody変数
@Environment(\.managedObjectContext) private var viewContext
ローカル変数viewContextの定義だと思う@Environment(\.managedObjectContext)というのは「マネージドオブジェクト」というやつらしい。
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
animation: .default)
private var items: FetchedResults<Item>
同様な読み方をすると次はこのローカル変数itemsの定義。@FetchRequestという接頭辞にsortDescriptorsとanimationオプションが付いてるんだろう
var body: some View {
次。
(Root)
∟ ContentsView
| ∟ body
| ∟ addItem
| ∟ deleteItems
∟ itemFormatter
∟ ContentsView_Preview
someというのは「何か」らしい。Viewみたいなもののサブクラス。。じゃなくて構造体
NavigationView {
List {
ForEach(items) { item in
NavigationLink {
Text("Item at \(item.timestamp!, formatter: itemFormatter)")
} label: {
Text(item.timestamp!, formatter: itemFormatter)
}
}
.onDelete(perform: deleteItems)
}
次。この辺までitemsをforeachしてる要素は全部NavigationLinkで作るようだ(NavigationLinkは画面遷移する時に使うやつ)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
Text("Select an item")
次。メソッドチェーンでtoolbarをつなげている。
この中にToolbarItemが2固定義されておりこれが画面右上のボタン2つ(+,Edit)
Text("Select an item")
これはどこにあるかわからん
addItemとdeleteItemsメソッド
次。
(Root)
∟ ContentsView
| ∟ body
| ∟ addItem
| ∟ deleteItems
∟ itemFormatter
∟ ContentsView_Preview
body変数は上記でおしまいです。body変数と同じレベルにある表題2つのメソッドについてです。まずaddItem
let newItem = Item(context: viewContext)
newItem.timestamp = Date()
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
1行目でItemオブジェクト作成。
▼Itemオブジェクトの元になってる定義
Itemオブジェクトってのはあらかじめ勝手に作成しといてくれていたCoreDataのオブジェクト。
newItem.timestamp = Date()
次。作ったオブジェクトに値設定
try viewContext.save()
次。セーブ。
次delete
offsets.map { items[$0] }.forEach(viewContext.delete)
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
これはメソッドの説明をしたい
▼onDeleteメソッド
@inlinable public func onDelete(perform action: ((IndexSet) -> Void)?) -> some DynamicViewContent
▼deleteItems
private func deleteItems(offsets: IndexSet) {
▼deleteItemsの呼び出し元
ForEach(items) {
略
}
.onDelete(perform: deleteItems)
deleteItemsメソッドをonDeleteに渡している。onDeleteの引数の定義は以下である。
action: ((IndexSet) -> Void)?
まず?なので指定しなくても良さそう。
指定するならIndexSet型の変数を受け取るメソッドを定義できるらしい。
そしてこの変数は選択された行を受け取るらしい。
offsets.map { items[$0] }.forEach(viewContext.delete)
では、中の処理だが、これ。
$0にoffsets:IndexSetのそれぞれが入ってくる
▼参考:https://developer.apple.com/documentation/foundation/indexset
そしてitemsはローカル変数であるitemsの選んだ(引数として渡された)要素のそれぞれに対し(forEach)
viewContext.delete
するらしい。
itemFormatter変数とContentView_Previews構造体
(Root)
∟ ContentsView
| ∟ body
| ∟ addItem
| ∟ deleteItems
∟ itemFormatter
∟ ContentsView_Preview
最後だがまず最後のContentView_Previews構造体に関しては最初に作られるやつだからよくわからんけどおけ
itemFormatter: DateFormatter
まずスコープがContentView構造体と同じレベル。
ContentView内で画面表示用に使う日付見た目整形用構造体。以上。
所感
なぜSwiftUIを調べているかだが、storyboardでiOSプロジェクトを複数人で作ると(バージョン管理しながら)storyboardの変更履歴がカオスなことになるらしい。
そして世の中にはそれが理由のためかstoryboardを使わずにコードビハインドのViewControllerに全部書く人がいたりそういうプロジェクトを見たことがある。これはそれを考慮したためかもしれない。
個人的にはビューとコードビハインドという作りが好きであるが(UIはIQ1でGUIで組み立てられるし)そういう問題があるならそちらに対応した方が良いのかもしれないという思いもあることが動機である。
あとコード量もすごい減るらしいし。
時代に対応していくのはダルいが、いざ会社でiOSアプリ作ってと言われて工数だけ渡されたら技術選定として上記storyboardがカオスになることを鑑みるとこのようなコードでUIを組み立てられる技術を選ぶかもしれなくそうなった時にやはり知っていないと詰むし何より楽するために仕方なく調べているわけである。
なお他にマルチプラットフォームで HTML/CSSでUIを組めるのもSwiftUIの代わりに良いかもしれないがあれはあれでビルドにバカ時間かかるしホットデプロイみたいな感じでサクサクできる面もあるが結局テストで実機用にビルドしなければいけないあたりなかなかキツイなぁとも思う。
次
今出してるアプリをSwiftUIで置き換えるというのが王道か。
この記事が気に入ったらサポートをしてみませんか?