swift 3完成处理程序返回字符串

时间:2017-01-27 07:59:56

标签: json swift closures alamofire

我是swift的新手,从函数中获取字符串时遇到问题,我正在尝试使用完成处理程序,但是出了点问题,你能帮帮我吗?

将[String:String]添加到func后,我无法获得rezult,我想获得响应并打印出来。错误:无法将type()的返回表达式转换为返回类型[String:String]

请求:

public func login(userName: String, password: String) -> [String : String]{

let loginrequest = JsonRequests.loginRequest(userName: userName, password: password)
return makeWebServiceCall(urlAddress: URL, requestMethod: .post, params: loginrequest, completion: { (JSON : Any) in

   print("\(JSON)")

})

}


private func makeWebServiceCall (urlAddress: String, requestMethod: HTTPMethod, params:[String:Any], completion: @escaping (_ JSON : Any) -> ()) {


    Alamofire.request(urlAddress, method: requestMethod, parameters: params, encoding: JSONEncoding.default).responseJSON { response in

        switch response.result {
        case .success:
            if let jsonData = response.result.value {
                completion(jsonData)
            }
        case .failure(let error):
            if let data = response.data {
                let json = String(data: data, encoding: String.Encoding.utf8)
                print("Failure Response: \(json)")

            }

通话功能:

let retur = Json()
    let rezultatas = retur.login(userName: "root", password: "admin01")

    print(rezultatas)

错误: enter image description here

2 个答案:

答案 0 :(得分:1)

欢迎来到Swift :)

您正在将同步和异步代码混合在一起。

当您致电login时,您希望它立即返回[String : String]类型的答案。

但是在您的login方法中,您会进行无法立即返回的网络调用...这就是调用Alamofire.request将完成块作为参数的原因。

所以......你需要改变你的login方法:

  1. 不会立即返回任何内容(它不能这样做...登录需要我们进行网络通话记住)
  2. 一旦登录成功,就会调用一个完成块。
  3. 这可以这样做:

    public func login(userName: String, password: String, loginCompletion: @escaping ([String : String]) -> ())
    

    此处我们有一个函数,其userName类型为Stringpassword类型为StringloginCompletion类型为function再次将[String : String]字典作为参数。请注意,该方法不会返回任何内容。

    现在,您几乎可以像以前一样致电makeWebServiceCall

    let loginrequest = JsonRequests.loginRequest(userName: userName, password: password)
    makeWebServiceCall(urlAddress: URL, requestMethod: .post, params: loginrequest, completion: { (JSON : Any) in
       //Now we are ready, the login call has returned some data to you. 
    
       //You have an attribute named JSON of type Any, which you need to convert to [String : String], and then you can call loginCompletion with that, like so:
       loginCompletion(yourConvertedDictionaryHere)
    })
    

    以下是新的login方法的完整性:

    public func login(userName: String, password: String, loginCompletion: @escaping ([String : String]) -> ()) {
        let loginrequest = JsonRequests.loginRequest(userName: userName, password: password)
        makeWebServiceCall(urlAddress: URL, requestMethod: .post, params: loginrequest, completion: { (JSON : Any) in
           //Now we are ready, the login call has returned some data to you. 
    
           //You have an attribute named JSON of type Any, which you need to convert to [String : String], and then you can call loginCompletion with that, like so:
           loginCompletion(yourConvertedDictionaryHere)
        })
    }
    

    然后你就像这样调用你的login方法:

    retur.login(userName: "root", password: "admin01") { stringDictionary: [String : String] in
        //here you have your stringDictionary which you can use as pleased
    }
    

    希望对你有所帮助。

答案 1 :(得分:0)

制作一个像这样的函数定义

private func makeWebServiceCall (urlAddress: String, requestMethod: String, params:[String:Any], completion: @escaping (_ JSON : Any) -> ()) {

completion("Make a service call")

}

让函数像这样调用

makeWebServiceCall(urlAddress: "", requestMethod: "", params: ["Key" : "value"], completion: { (JSON : Any) in

            print("\(JSON)")

        })

由于简单,我更改了参数的DataType。您也可以在completion("Make a service call")中传递任何类型的数据。 希望这对你有帮助。