我如何 return 从 API 到我的 Swift 应用程序的所有响应

How can I return all the response from API to my Swift app

我正在学习 swift 我在这里看到了一个示例 https://matteomanferdini.com/network-requests-rest-apis-ios-swift/ 我正在尝试更改代码以获得适合我的东西。

这是原始代码的样子

struct Wrapper<T: Decodable>: Decodable {
    let items: [T]?
}


protocol NetworkRequest: AnyObject {
    associatedtype ModelType
    func decode(_ data: Data) -> ModelType?
    func load(withCompletion completion: @escaping (ModelType?) -> Void)
}

extension NetworkRequest {
    fileprivate func load(_ url: URLRequest, withCompletion completion: @escaping (ModelType?) -> Void) {
        let session = URLSession(configuration: .default, delegate: nil, delegateQueue: .main)
        let task = session.dataTask(with: url, completionHandler: { [weak self] (data: Data?, response: URLResponse?, error: Error?) -> Void in

            if let error = error {
                print("Error: \(error)")
            }

            guard let data = data else {
                completion(nil)
                return
            }

            completion(self?.decode(data))
        })
        task.resume()
    }
}

class APIRequest<Resource: APIResource> {
    let resource: Resource

    init(resource: Resource) {
        self.resource = resource
    }
}

extension APIRequest: NetworkRequest {
    func decode(_ data: Data) -> [Resource.ModelType]? {
        let wrapper = try? JSONDecoder().decode(Wrapper<Resource.ModelType>.self, from: data)
        return wrapper?.items
    }

    func load(withCompletion completion: @escaping ([Resource.ModelType]?) -> Void) {
        load(resource.request, withCompletion: completion)
    }
}

但我需要将结构 Wrapper 更改为

struct Wrapper<T: Decodable>: Decodable {
    let items: [T]?
    let response: Bool?
    let message: String?
}

和returnitemsresponsemessage不仅items

在这种情况下,您根本不需要协议,因为您想要获取根对象。

够了

struct Wrapper<T: Decodable>: Decodable {
    let items: [T]
    let response: Bool
    let message: String
}

class NetworkRequest {
    func load<T : Decodable>(_ request: URLRequest, withCompletion completion: @escaping (Result<Wrapper<T>,Error>) -> Void) {
        let session = URLSession(configuration: .default, delegate: nil, delegateQueue: .main)
        let task = session.dataTask(with: request) { data, _, error in
            if let error = error {
                completion(.failure(error))
            } else {
                completion( Result {try JSONDecoder().decode(Wrapper<T>.self, from: data!)})
            }
        }
        task.resume()
    }
}

完成处理程序 returns 一个 Result 对象,成功时是包装器对象,失败时是 所有 错误。

在包装器结构中声明所有非可选属性以获取错误消息并仅将那些真正可以是可选的更改为 nil

我这样改代码

class NetworkRequest<Resource: APIResource> {

    let resource: Resource

    init(resource: Resource) {
        self.resource = resource
    }

    func load(withCompletion completion: @escaping (Result<Wrapper<Resource.ModelType>,Error>) -> Void) {
        let session = URLSession(configuration: .default, delegate: nil, delegateQueue: .main)
        let task = session.dataTask(with: self.resource.request) { data, _, error in
            if let error = error {
                completion(.failure(error))
            } else {
                completion( Result {try JSONDecoder().decode(Wrapper<Resource.ModelType>.self, from: data!)})
            }
        }
        task.resume()
    }
}

struct LoginResource: APIResource {
    typealias ModelType = Token
    let methodPath = "/users/login/"
    let method = "post"
    var params: [String: Any]?

    init(username: String, password: String) {
        self.params = ["username":username, "password": password]
    }
}

在我看来:

func login() {
        if user == "" || password == "" {
            self.title_alert = "Info"
            message_alert = "Test Alert"
            show_alert = true
            return
        }

        let loginRequest = NetworkRequest(resource: LoginResource(username:user,password:password))
        loginRequest.load { result in
            switch result {
                case .failure(let error):
                    print(error)
                case .success(let data):
                    print(data)
            }
        }

    }

我不知道这是否是最好的方法,但有效谢谢@vadian