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
225 views
in Technique[技术] by (71.8m points)

ios - Include a return handler in async call in Swift

I'm experimenting with async calls but I'm a little lost. The print(json) in the viewDidLoad outputs an empty dictionary, but the one within the function prints correctly. This is unsurprising; it gets to that print before the async is completed. I can't figure out how to fix it; I tried putting the return within the completion handler, but I got an error that Unexpected non-void return value in void function. I tried changing the completion handler to expect a return value, but either that's not the right approach or I was doing it wrong.

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let json = getJson("https://maps.googleapis.com/maps/api/geocode/json?address=WashingtonDC&sensor=false")
        print(json)
    }

    func getJson(url: String) -> AnyObject {
        var json:AnyObject = [:]
        let urlPath = NSURL(string: url)
        let urlRequest = NSURLRequest(URL: urlPath!)
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: config)
        let task = session.dataTaskWithRequest(urlRequest, completionHandler: {
            (data, response, error) in
            if error != nil {
                print("Error")
            } else {
                do {
                    json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
                    print(json)
                } catch {
                    print("json error")
                }

            }
        })
        task.resume()
        return json
    }
}
See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

You will need to have a completion handler based interface to your async API.

func getJson(url: String, completion : (success: Bool, json: AnyObject? ) ->Void ) -> Void {
        var json:AnyObject = [:]
        let urlPath = NSURL(string: url)
        let urlRequest = NSURLRequest(URL: urlPath!)
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: config)
        let task = session.dataTaskWithRequest(urlRequest, completionHandler: {
            (data, response, error) in
            if error != nil {
                print("Error")
            } else {
                do {
                    json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
                    print(json)
//Call the completion handler here:
completion(success : true, json :json )
                  } catch {
                    print("json error")
completion(success : false, json :nil )

                }

            }
        })
        task.resume()
    }
}

Now you call call this API as follows-

 override func viewDidLoad() {
        super.viewDidLoad()
       getJson("https://maps.googleapis.com/maps/api/geocode/json?address=WashingtonDC&sensor=false") { (success, json) -> Void in 
        if success {
          if let json = json {
            print(json)
         }
        }
     }
  }

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

...