问题描述
swiftui的新手,不理解为什么第一个代码中的JSONDecoder()行会抛出
[SwiftUI]不允许从后台线程发布更改;确保在模型更新时从主线程(通过诸如receive(on :)之类的运算符)发布值。
这对我来说不是更新ui,所以为什么显示?
do {
// pass the request type,bearer token,and email / password ( which are sent as POST body params )
let request = L.getRequest(requestType:"POST",token: token,email: self.username,password: self.psw)
L.fetchData(from: request) { result in
switch result {
case .success(let data):
// covert the binary data to a swift dictionary
do {
let response = try JSONDecoder().decode(WpJson.self,from: data)
for (key,title) in response.allowedReadings {
let vimeoId = Int( key )!
let vimeoUri = self.buildVimeoUri(vimeoId: key)
self.addReadingEntity(vimeoUri: vimeoUri,vimeoId: vimeoId,title: title)
}
self.writetoKeychain(jwt:response.jwt,displayName: response.displayName)
readings = self.fetchReadings()
}
catch {
self.error = error.localizedDescription
}
case .failure(let error):
self.error = error.localizedDescription
}
}
}
我尝试在do-catch
中的L.fetchData(from: request) { result in
周围包裹一个主队列,但这没有帮助
dispatchQueue.main.async { [weak self] in
这是Login协议,再次没有任何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)))
}
})
}
}
您对如何解决此问题有任何想法吗?
解决方法
将其包装在任务处
catch {
DispatchQueue.main.async {
self.error = error.localizedDescription
}
}
case .failure(let error):
DispatchQueue.main.async {
self.error = error.localizedDescription
}
}