リストビューへのSwiftui 5.5 APIデータ


何度も、リストで表示するデータを取得するAPI呼び出しをする必要があります.ここでは、Swiftuiでそれを行う方法を示します.アプリケーションの構造を説明するには、次の図を参照してください.


藤堂apiservice
ネットワークリクエストを送信するAPIサービスを作成する必要があります.urlsessionを使います.ここでは、すべてのtodo項目を取得し、[ todoitem ]にそれらを逆シリアル化する方法があります
struct TodoItem: Identifiable, Codable {
    let id: Int
    let title: String
    let completed: Bool
}

enum APIError: Error{
    case invalidUrl, requestError, decodingError, statusNotOk
}

let BASE_URL: String = "https://jsonplaceholder.typicode.com"

struct APIService {

    func getTodos() async throws -> [TodoItem] {

        guard let url = URL(string:  "\(BASE_URL)/todos") else{
            throw APIError.invalidUrl
        }

        guard let (data, response) = try? await URLSession.shared.data(from: url) else{
            throw APIError.requestError
        }

        guard let response = response as? HTTPURLResponse, response.statusCode == 200 else{
            throw APIError.statusNotOk
        }

        guard let result = try? JSONDecoder().decode([TodoItem].self, from: data) else {
            throw APIError.decodingError
        }

        return result
    }

}

藤堂ビューモデル
次に、Viewモデルは、APIサービスを使用して、発行するToDoSを取得します
@MainActor
class TodoViewModel: ObservableObject {

    @Published var todos: [TodoItem] = []
    @Published var errorMessage = ""
    @Published var hasError = false


    func getTodos() async {
        guard let data = try?  await  APIService().getTodos() else {
            self.todos = []
            self.hasError = true
            self.errorMessage  = "Server Error"
            return
        }

        self.todos = data

    }
}

藤堂ビュー
最後に、任意のToDoリストの状態変化のViewModelを監視するビューがあります.ToDoリストは、ビューに表示されます.リストでは、ビューがAPI呼び出しを行います.
struct TodoList: View {
    @StateObject var vm = TodoViewModel()

    var body: some View {
        List{
            ForEach(vm.todos){todo in
                HStack{
                    Image(systemName: todo.completed ? "checkmark.circle": "circle")
                        .foregroundColor(todo.completed ? .green : .red)
                    Text("\(todo.title)")
                }
            }
        }
        .task {
            await vm.getTodos()
        }
        .listStyle(PlainListStyle())
        .navigationTitle("Todos")

    }
}