执行网络调用并继续 - 异步任务

perform network call and proceed - asynchronous task

一年前才开始学习Swift,请耐心等待:)

我正在通过网络调用下载 JSON 数据,一旦我成功收到这些行,我就会继续清除我的 coreData 实体中的行,并将这些新行重写到 coredata..

我很难理解这个异步过程..

我了解到我必须使用完成处理程序,但我仍然无法按照我需要的方式使用它..特别是当我需要在执行完这 3 个步骤后继续时..

按钮操作的第一次调用:

@IBAction func updateButtonPressed(_ sender: Any) {

    self.myCoreData.update() {(success) in // calls my update method
        print(success!) 
        textField.text = success! // not possible bc not in the Mainthread
}
textField.text = "blabla" // gets executed before the result is available

方法:

func update(completion: @escaping (String?) -> Void) { //parent method which calls sub methods
    var returnValue = ""
    Step1getJson {_ in.      // step 1
        self.Step2Delete {   // step 2
            self.Step3Save { // step 3
                returnValue = "return Value: \(self.step1Result)"
                completion(returnValue)
            }
        }
    }
}

func Step1getJson(completion: @escaping (Bool) -> ()) {
    var success = false
    if let url = URL(string: "https:foo") {
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
                do {
                    let parsedJSON = try JSONDecoder().decode([RemoteWire].self, from: data)
                    print("-- Successfully received \(parsedJSON.count) datarows ")
                    self.JSON = parsedJSON
                    self.step1Result = "-- Successfully received \(parsedJSON.count) datarows "
                    success = true

                } catch {
                    print(error)
                }
            completion(success)
        }.resume()
    }
}

func Step2Delete(completion: () -> Void) {
...delete entity rows
completion()
}

func Step3Save(completion: () -> Void) {
.. save new JSON rows to coreData
completion()
}

到目前为止一切正常,网络下载完成后第 2 步和第 3 步被成功调用..

但是在我的 updateButtonPressed 函数中执行了这些步骤后,我该如何继续? 如果我尝试将这些结果写入完成块内的任何 UI 元素、textField 或其他任何元素,我会收到一条错误消息,指出这必须在主线程中发生,如果我在完成块外执行这些行太早执行,还没有结果。

我觉得我对此有理解上的问题,希望你们能帮助我并指导我正确的方向。

由于 swift 仅允许从主线程对 UI 元素进行任何更改或更新,因此您需要调用主线程来更新 UI。 替换下面的代码

@IBAction func updateButtonPressed(_ sender: Any) {

     self.myCoreData.update() {(success) in // calls my update method
        print(success!) 
        textField.text = success! // not possible bc not in the Mainthread
     }
}

使用新代码

@IBAction func updateButtonPressed(_ sender: Any) {

    self.myCoreData.update() {(success) in // calls my update method
        print(success!)
        DispatchQueue.main.async {
            textField.text = success! // Now possible because it is in main thread
        }
    }
    
}