@Publishedプロパティのコード化可能な適合性の追加
Adding Codable conformance for @Published properties
@Publishedに準拠するにCodableは、追加の作業が必要になります。
これを修正するには、Codable適合性を自分で実装する必要があります。
最初のステップはCodingKeys、に準拠する列挙型を作成し、CodingKeyアーカイブおよびアーカイブ解除するすべてのプロパティをリストすること。
カスタム初期化子
import SwiftUI
//class User: ObservableObject, Codable {
// var name = "Paul Hudson"
//}
class User: ObservableObject, Codable {
@Published var name = "Paul Hudson"
enum CodingKeys: CodingKey {
case name
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
}
}
URLSessionとSwiftUIを使用したCodableデータの送受信
Sending and receiving Codable data with URLSession and SwiftUI
iOSには、インターネットからデータを送受信するための組み込みツールが用意されています。Codableサポートと組み合わせると、SwiftオブジェクトをJSONに変換して送信し、JSONを受信して、Swiftオブジェクトに変換して戻すことができます。さらに良いことに、リクエストが完了すると、そのデータをSwiftUIビューのプロパティにすぐに割り当てて、ユーザーインターフェイスを更新することができます。
AppleのiTunes APIから音楽JSONデータの例をロードして、すべてをSwiftUIで表示できListます。
テイラースウィフトのすべての曲のリストを送信するようにiTunes APIに要求し、それを使用JSONDecoderしてそれらの結果をResultインスタンスの配列に変換します。
import SwiftUI
struct Response: Codable {
var results: [Result]
}
struct Result: Codable {
var trackId: Int
var trackName: String
var collectionName: String
}
//----------------------
struct ContentView: View {
@State private var results = [Result]()
func loadData() {
guard let url = URL(string: "https://itunes.apple.com/search?term=taylor+swift&entity=song") else {
print("Invalid URL")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
// step 4
if let data = data {
if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
// we have good data – go back to the main thread
DispatchQueue.main.async {
// update our UI
self.results = decodedResponse.results
}
// everything is good, so we can exit
return
}
}
// if we're still here it means there was a problem
print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
}.resume()
}
var body: some View {
List(results, id: \.trackId) { item in
VStack(alignment: .leading) {
Text(item.trackName)
.font(.headline)
Text(item.collectionName)
}
}
.onAppear(perform: loadData)
}
}
フォームの検証と無効化
Validating and disabling forms
disabled()
import SwiftUI
struct ContentView: View {
@State private var username = ""
@State private var email = ""
var disableForm: Bool {
username.count < 5 || email.count < 5
}
var body: some View {
Form {
Section {
TextField("Username", text: $username)
TextField("Email", text: $email)
}
Section {
Button("Create account") {
print("Creating account…")
}
}
//.disabled(username.isEmpty || email.isEmpty)
.disabled(disableForm)
}
}
}