Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
137 views
in Technique[技术] by (71.8m points)

json - swift 3 completion handler to return string

I am new at swift and got problem with getting string from function, I am trying to use completion handler, but something is wrong, could you help me?

After adding [String : String] to func, I cant get rezult, I want to get response and print it. Error: Cannot convert return expresion of type () to return type [String : String]

Requests:

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)")

            }

Calling function:

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

    print(rezultatas)

Errors: enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Welcome to Swift :)

You are mixing synchronous and asynchronous code together.

When you call login you expect it to return an answer straight away of type [String : String].

But in your login method you then do a network call which can not return straight away...which is why the call to Alamofire.requesttakes a completion block as a parameter.

So...you need to change your login method so it:

  1. does not return anything straight away (it can not do so...logging in requires us doing a network call remember)
  2. takes a completion block to invoke once login has succeeded.

This can be done like so:

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

Here we have a function that takes a userName of type String, a password of type String and a loginCompletion of type function that again takes a [String : String] dictionary as a parameter. Notice that the method does not return anything.

Now you can call your makeWebServiceCall almost as before:

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)
})

Here is the new login method in its completeness:

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)
    })
}

And then you call your login method like so:

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

Hope that helps you.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...