목록 보기에 대한 SwiftUI 5.5 API 데이터

목록에 표시할 데이터를 가져오기 위해 API를 호출해야 하는 경우가 많습니다. 여기에서는 SwiftUI를 사용하여 이를 수행하는 방법을 보여줍니다. 애플리케이션의 구조를 설명하기 위해 다음 다이어그램을 살펴보겠습니다.



Todo API 서비스



네트워크 요청을 보내려면 API 서비스를 만들어야 합니다. URLSession을 사용합니다. 여기에 모든 할일 항목을 가져오고 [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
    }

}


Todo 뷰모델



뷰 모델은 차례로 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

    }
}


토도 뷰



마지막으로 할 일 목록 상태 변경에 대해 ViewModel을 감시하는 보기가 있습니다. 할 일 목록이 보기에 표시됩니다. 목록에 보기가 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")

    }
}


좋은 웹페이지 즐겨찾기