はじめに
前回からの続きでSwiftUIのチュートリアル入門で、[Handling User Input編]になります。
もと記事サイト

Handling user input | Apple Developer Documentation
In the Landmarks app, a user can flag their favorite places, and filter the list to show just their favorites. To create...
Step0
このセッションではObservable Objectを使ってlandmaark dataの変更をViewにバインドさせて反映するための準備をします。
Step1
プロジェクトナビゲーションからModelフォルダーにあるData.swiftを選択します。

Step2
ObservableObject protocolを準拠した新規Modelを作成するためにCombineをインポートします。
import Foundation
import Combine
final class ModelData: ObservableObject {
}
var landmarks: [Landmark] = load("landmarkData.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) from main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}Step3
landmarksの配列を先程宣言したModelData内に移動します。
import Foundation
import Combine
final class ModelData: ObservableObject {
var landmarks: [Landmark] = load("landmarkData.json")
}
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) from main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}Step4
landmarks配列の変更を反映するために@Publishedを付与します。
import Foundation
import Combine
final class ModelData: ObservableObject {
@Published var landmarks: [Landmark] = load("landmarkData.json")
}
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) from main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}まとめ
今回はModelとView間のデータ変更をバインドするための準備でした。@Stateで変数を一つずつ宣言するやり方もありますが、まとめてグループ化したい場合はObservableObjectを準拠させ、@ObservedObjectを使用して変数を宣言します。



コメント