如何在 Swift 4 中传递 Encodable 或 Decodable 作为参数?

Rob*_*b13 5 api xcode json ios swift

我正在学习 JSONParsing。我遵循了教程,得到的是这样的:

    guard let url = URL(string: "http://localhost/test-api/public/api/register") else { return }

    var request  = URLRequest(url: url)

    request.httpMethod = "POST"

    let newUser = User.init(name: self.collectionTF[0].text, email: self.collectionTF[1].text, password: self.collectionTF[2].text)

    do {

        let jsonBody = try JSONEncoder().encode(newUser)

        request.httpBody = jsonBody

    } catch { }

    URLSession.shared.dataTask(with: request) { (data, response, error) in

        guard let data = data else { return }

        do {

            let json = try JSONSerialization.jsonObject(with: data) as? [String:Any]

            print(json!)

            DispatchQueue.main.async {

            if json!["status"] as! Int == 200
            {
                GeneralHelper.shared.keepLoggedIn()

                NavigationHelper.shared.moveToHome(fromVC: self)
            }

            }

        } catch { print(error.localizedDescription)}

        }.resume()
Run Code Online (Sandbox Code Playgroud)

好的,这就是我为注册所做的。现在,我想创建一个助手,它将做同样的事情,@escaping因为我们都需要解析JSON作为回报。

因此,我传递endPointas String ,然后尝试传递这个 newUser ,它是 a ,将来它也Encodable可以是 a ,但它会引发错误。有人可以帮忙吗?而且,通过多次调用此函数,这种方式是否更好?DecodableCannot invoke 'encode' with an argument list of type '(Codable)'JSONParsing

编辑:-所以,我现在正在使用networkRequestfunction,这就是我所做的。

 let newData = User.init(name: "Rob", email: "abc@gmail.com", password: "12345678")

ApiHelper.sharedInstance.networkRequest_Post(urlString: "register", header: nil, encodingData: newData) { (response: User, urlRes, error) in
        <#code#> }
Run Code Online (Sandbox Code Playgroud)

现在,它给了我这个错误:Cannot convert value of type '(User, _, _) -> ()' to expected argument type '(_?, HTTPURLResponse?, Error?) -> ()'。有什么帮助吗?

Mah*_*dra 1

您可以通过以下方式使用泛型...

func requestWith<T>(method: HTTPMethod, action: String,  params: Parameters?, for type: T.Type, success: @escaping (AnyObject) -> Void, failure: @escaping (AnyObject) -> Void) where T: Codable {


//do your stuff..your logic goes here..see below example

     guard let serverData = response.data else {
           return
        }

   do {
     let decoder = JSONDecoder()
     let responseData = try decoder.decode(type, from: serverData)
       success(responseData as AnyObject)
    } catch {
      print("Error = \(error.localizedDescription)")
       failure(error.localizedDescription as AnyObject)
   }

}
Run Code Online (Sandbox Code Playgroud)

  • 未指定的“AnyObject”对于通用函数来说是不合适的。更好 `func requestWith&lt;T&gt;(method: HTTPMethod, action: String, params:Parameters?, success: @escaping (T) -&gt; Void, failure: @escaping (Error) -&gt; Void) where T: Codable { ` (2认同)