100 Days of SwiftUI(DAY 49(Project10 part 1))

@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)

        }
    }
}