【问题标题】:"Task finished with error [-999]" in SwiftUISwiftUI 中的“任务以错误 [-999] 完成”
【发布时间】:2020-03-26 14:22:08
【问题描述】:

我正在尝试使用 Combine 向https://myLink.com URL 发出 HTTP GET 请求(这是一个假 URL,我使用的是一个真正的 API 链接,它可以工作,但我不能发布它),但是当我调用该函数时,出现以下错误:

任务 。 以错误结束 [-999] 错误域=NSURLErrorDomain 代码=-999 “取消” UserInfo={NSErrorFailingURLStringKey=https://myLink.com, NSLocalizedDescription=取消, 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"
        }
    ]
}

【问题讨论】:

    标签: ios swift httprequest swiftui


    【解决方案1】:

    要从网络调用中获取结果,您需要以这种方式更改内容视图:

    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 变量,以确保它在生成视图主体后仍然存在。

    【讨论】:

    • 感谢您的回答,它帮助了我,现在我不再收到该错误,但现在它说:收到完成:失败(appname.Network.Error.invalidResponse)。这是它在调试控制台中打印的内容,但在 API 中记录了带有状态代码 200 的请求响应,因此它应该可以工作。
    • 如果您打印响应错误,您会得到:typeMismatch(Swift.Array&lt;Any&gt;, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "patients", intValue: nil)], debugDescription: "Expected to decode Array&lt;Any&gt; but found a dictionary instead.", underlyingError: nil)) 您的响应数据无法解码为您定义的结构
    • 结构应该如何?我编辑了问题并在那里添加了 JSON 响应。
    • 您能否提出一个单独的问题,以便我粘贴我的代码并为您解释一下?在评论中代码样式不能正常工作
    猜你喜欢
    • 2021-10-24
    • 1970-01-01
    • 2018-12-04
    • 2021-07-29
    • 1970-01-01
    • 2015-11-14
    • 2021-10-26
    • 1970-01-01
    • 2016-03-20
    相关资源
    最近更新 更多