SwiftUI-不允许发布后台线程-在不更新ui的代码上

SwiftUI-不允许发布后台线程-在不更新ui的代码上,swiftui,thread-safety,runtime-error,Swiftui,Thread Safety,Runtime Error,swiftui新手,不理解为什么第一个代码中的JSONDecoder()行会抛出 [SwiftUI]不允许从后台线程发布更改;确保在模型更新时从主线程(通过诸如receive(on:)之类的操作符)发布值 这对我来说并不是在更新用户界面,为什么会出现这种情况 我尝试在L.fetchData(from:request){result in中的do catch周围包装一个主队列,但这没有帮助 DispatchQueue.main.async { [weak self] in 这是登录协议,同样

swiftui新手,不理解为什么第一个代码中的JSONDecoder()行会抛出

[SwiftUI]不允许从后台线程发布更改;确保在模型更新时从主线程(通过诸如receive(on:)之类的操作符)发布值

这对我来说并不是在更新用户界面,为什么会出现这种情况

我尝试在
L.fetchData(from:request){result in
中的
do catch
周围包装一个主队列,但这没有帮助

DispatchQueue.main.async { [weak self] in 
这是登录协议,同样没有任何ui工作:

import Foundation
import SwiftUI

struct Login: Endpoint {
    var url: URL?
    init(url: URL?) {
        self.url = url
    }
}

protocol Endpoint {
    var url: URL? { get set }
    init(url: URL?)
}

extension Endpoint {
    func getRequestUrl() -> URLRequest {
        guard let requestUrl = url else { fatalError() }
        // Prepare URL Request Object
        return URLRequest(url: requestUrl)
    }
    
    func getRequest(requestType:String="POST", token:String, email:String="", password:String="") -> URLRequest {
        var request = self.getRequestUrl()
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
        
        if ( "" != email && "" != password && requestType == "POST") {
            let parameters:[String:String?] =  [
                "email": email,
                "password": password
            ]
            
            // Run the request
            do {
                // pass dictionary to nsdata object and set it as request body
                request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
            } catch let error {
                print(error.localizedDescription)
            }
        }
        return request;
    }
    
    func fetchData(from request: URLRequest, completion: @escaping (Result<Data, NetworkError>) -> Void) {
        
         URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                completion(.success(data))
           } else if error != nil {
                // any sort of network failure
                completion(.failure(.requestFailed))
           } else {
                // this ought not to be possible, yet here we are
                completion(.failure(.unknown))
           }
        }.resume()
    }
}

extension URLSession {
    func dataTask(with request: URLRequest, completionHandler: @escaping (Result<(Data, HTTPURLResponse), Error>) -> Void) -> URLSessionDataTask {
        return dataTask(with: request, completionHandler: { (data, urlResponse, error) in
            if let error = error {
                completionHandler(.failure(error))
            } else if let data = data, let urlResponse = urlResponse as? HTTPURLResponse {
                completionHandler(.success((data, urlResponse)))
            }
        })
    }
}
<代码>导入基础 导入快捷键 结构登录:端点{ var-url:url? 初始化(url:url?){ self.url=url } } 协议端点{ var url:url?{get set} 初始化(url:url?) } 扩展端点{ func getRequestUrl()->URLRequest{ guard let requestUrl=url else{fatalError()} //准备URL请求对象 返回url请求(url:requestUrl) } func getRequest(requestType:String=“POST”,token:String,email:String=“”,password:String=“”)->URLRequest{ var request=self.getRequestUrl() request.httpMethod=“POST” request.setValue(“application/json”,forHTTPHeaderField:“Content Type”) request.addValue(“承载者\(令牌)”,用于HttpHeaderField:“授权”) 如果(“!=email&&”!=password&&requestType==“POST”){ let参数:[字符串:字符串?]=[ “电子邮件”:电子邮件, “密码”:密码 ] //运行请求 做{ //将字典传递给nsdata对象并将其设置为请求正文 request.httpBody=try JSONSerialization.data(带jsonObject:参数,选项:。预打印) }捕捉错误{ 打印(错误。本地化描述) } } 返回请求; } func fetchData(从请求:URLRequest,完成:@escaping(Result)->Void){ URLSession.shared.dataTask(with:request){data,response,中的错误 如果let data=data{ 完成(.success(数据)) }否则,如果错误!=nil{ //任何类型的网络故障 完成(.failure(.requestFailed)) }否则{ //这不应该是可能的,但我们现在在这里 完成(.failure(.unknown)) } }1.简历() } } 扩展URL会话{ func dataTask(带请求:URLRequest,completionHandler:@escaping(Result)->Void)->URLSessionDataTask{ 在中返回dataTask(带有:request,completionHandler:{(数据,urlResponse,error) 如果let error=error{ completionHandler(.failure(error)) }否则,如果让data=data,则让urresponse=urresponse作为?httpurresponse{ completionHandler(.success((数据,urlResponse))) } }) } }
你知道如何解决这个问题吗?

把它包装起来,代替作业

        catch {
            DispatchQueue.main.async {
             self.error = error.localizedDescription
            }
        }
    case .failure(let error):
       DispatchQueue.main.async {
          self.error = error.localizedDescription
       }
    }

什么是
self.error
?@Published var error:String=”“谢谢@Asperi,这就成功了。我想知道为什么现在会出现这种情况,因为我已经运行这样的代码好几个星期了。是不是因为self.error在视图上绑定的太不经意了,虽然它不是直接的ui更新,但它是更新ui的绑定?
        catch {
            DispatchQueue.main.async {
             self.error = error.localizedDescription
            }
        }
    case .failure(let error):
       DispatchQueue.main.async {
          self.error = error.localizedDescription
       }
    }