ios - SwiftUI 中的“任务以错误 [-999] 完成”
问题描述
我正在尝试使用组合到https://myLink.com URL 发出 HTTP GET 请求(这是一个假 URL,我使用的是一个真正的 API 链接,它可以工作,但我不能发布它) ,但是当我调用该函数时,出现以下错误:
任务 <18F5A03A-96DF-4309-B263-B6B0CB275779>.<1> 以错误结束 [-999] 错误域=NSURLErrorDomain 代码=-999 “已取消” UserInfo={NSErrorFailingURLStringKey= https://myLink.com , NSLocalizedDescription=cancelled , NSErrorFailingURLKey= https://myLink.com }
这是我的代码:
import SwiftUI
import Foundation
import Combine
struct ContentView: View {
var body: some View {
Button(action: {
loadPatients()
})
{
Text("Load Patients")
}
}
}
//MARK: - Your object to retrieve from JSON
struct Doctor: Codable, Identifiable {
let id = UUID()
let patients: [Patients]
}
struct Patients: Codable {
let id: String
let name: String
let phone: String
}
class Network {
// Handle your request errors
enum Error: LocalizedError {
case invalidResponse
case addressUnreachable(URL)
var errorDescription: String? {
switch self {
case .invalidResponse:
return "The server responded with garbage."
case .addressUnreachable(let url):
return "\(url.absoluteString) is unreachable."
}
}
}
// Add your url
let urlRequest = URL(string: "https://coronavirus-med.herokuapp.com/api/v1/doctor/getPatients/bogdand")!
// Networking on concurrent queue
let networkQueue = DispatchQueue(label: "Networking",
qos: .default,
attributes: .concurrent)
// Combine network call (This replace your previous code)
func downloadPatients() -> AnyPublisher<Doctor, Error> {
URLSession.shared
.dataTaskPublisher(for: urlRequest)
.receive(on: networkQueue)
.map(\.data)
.decode(type: Doctor.self, decoder: JSONDecoder())
.mapError { (error) -> Network.Error in
switch error {
case is URLError:
return Error.addressUnreachable(self.urlRequest)
default:
return Error.invalidResponse
}
}
.eraseToAnyPublisher()
}
}
let networkRequest = Network()
//MARK: - Call this function where you want to make your call
func loadPatients() {
_ = networkRequest.downloadPatients()
.sink(
receiveCompletion: {
print("Received Completion: \($0)") },
receiveValue: { doctor in
// doctor is your response and [0].name is your first patient name
print(doctor.patients[0].name) }
)
}
我在 StackOverflow 上找到了另一个问题来解决这个错误,但答案只是说明了错误的含义,而不是如何解决它。他们说这意味着在另一个完成之前提出了一个请求,但是在这个之前我没有提出任何请求,我什至尝试在一个新的空项目中运行它,但它仍然给我同样的错误。
我在 iOS 13.2 和 Xcode 11.2 上,我更新到 iOS 13.4 和 Xcode 11.4,仍然是同样的错误。
这是 JSON 响应:
{
"code": 200,
"status": "success",
"patients": [
{
"_id": "5e77c7bbc7cbd30024f3eadb",
"name": "Bogdan Patient",
"username": "bogdanp",
"phone": "0732958473"
},
{
"_id": "5e77c982a2736a0024e895fa",
"name": "Robert Patient",
"username": "robertp",
"phone": "0739284756"
}
]
}
解决方案
要从网络调用中获取结果,您需要以这种方式更改内容视图:
struct ContentView: View {
let networkRequest = Network()
@State var cancelable: AnyCancellable? = nil
var body: some View {
Button(action: {
self.loadPatients()
})
{
Text("Load Patients")
}
}
//MARK: - Call this function where you want to make your call
func loadPatients() {
cancelable = networkRequest.downloadPatients()
.sink(
receiveCompletion: {
print("Received Completion: \($0)") },
receiveValue: { doctor in
// doctor is your response and [0].name is your first patient name
print(doctor.patients[0].name) }
)
}
}
您应该将网络调用存储在AnyCancellable
. 在视图中使用它时,您需要使用 @State 变量,以确保它在生成视图主体后仍然存在。
推荐阅读
- r - 如何在 geom_point 点图中仅显示前 10 个类别和值?
- google-compute-engine - 了解 Google Compute Engine 的实例/cpu/利用率
- python - 更改 Builder 方法
- javafx - How to display day from selected date using javafx?
- android - Error :- Android resource linking failed, how fix this?
- vim - 如何以不同于其内容的方式突出显示代码块的标签?
- python - 如何在 matplotlib 中操作 xticks 与数据框图相同
- rest - InfluxDB http calls sending credentials (username & password) in URL as query params
- reactjs - 无法使用 Redux,Sagas 访问第二个组件中的第一个组件状态
- ios - UI 按钮图像替换标题。但我希望同时显示文本、图像和标题