SwiftUI:onAppear 方法不更新状态

时间:2021-06-12 18:22:26

标签: ios swift swiftui

我是 SwiftUI 的初学者。我在获取一些数据和更新我的状态时遇到问题。我该怎么做?

import SwiftUI

struct ContentView: View {
   @State var todos : TodoListViewModel
        var body: some View {
            NavigationView {
                TodoList(todos: todos)
            }.onAppear(){
                DispatchQueue.main.async {
                    getTodos()
                }
                print(todos.todolist)
            }
       
        }
    
    func getTodos(){
        let url = URL(string:"https://xxx.xxx.xxx/xxx/xx/xxxx")!
        
        TodoWebService().fetchTodos(url: url) { (todoList) in
            self.todos = TodoListViewModel(todolist: todoList!)
            print(todos.todolist)
        }
       
    }
   
}

它只显示我传递给 ContentView 的内容

@main
struct SwiftUITodoAppApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView(todos: TodoListViewModel(todolist: [Todo(id: 1, title: "Title", description: "Description")]))
        }
    }
}

我的 TodoWebService 正在运行。我可以成功打印数据

TodoWebService.swift

import Foundation

class TodoWebService {
    func fetchTodos(url:URL,completion: @escaping ([Todo]?) -> ()){
        URLSession.shared.dataTask(with: url) { (data,response,error) in
            if let error = error {
                print(error.localizedDescription)
                completion(nil)
            } else if let data = data {
               let todoList = try? JSONDecoder().decode([Todo].self, from: data)
                completion(todoList)
            }
        }.resume()
    }
}

TodoListViewModel.swift

struct TodoListViewModel{
    var todolist : [Todo]
    
    func numberOfRows() -> Int {
        return self.todolist.count
    }
    
    func todoAtIndex(_ index:Int) -> TodoViewModel {
        let todo = self.todolist[index]
        return TodoViewModel(todo: todo)
    }
}

1 个答案:

答案 0 :(得分:0)

我通过将 ase 更改为 @State

来解决

TodoListViewModel

@ObservedObject

内容视图

class TodoListViewModel : ObservableObject{
   @Published var todolist = [Todo]()
   
    init() {
        getAllTodos()
       }

    
    func numberOfRows() -> Int {
        return self.todolist.count
    }
    
    func todoAtIndex(_ index:Int) -> TodoViewModel {
        let todo = self.todolist[index]
        return TodoViewModel(todo: todo)
    }
    
    func getAllTodos(){
        let url = URL(string:"https://xxx.xxx.xxx/xxx/xxx/xxx")!

         
        URLSession.shared.dataTaskPublisher(for: url)
                    .map { $0.data }
                    .decode(type: [Todo].self, decoder: JSONDecoder())
                    .replaceError(with: [])
                    .eraseToAnyPublisher()
                    .receive(on: DispatchQueue.main)
                    .assign(to: &$todolist)
    }
}
相关问题