如何使用dispatch_async调用2个不同的api并在Swift中更新UI

时间:2016-01-06 14:40:46

标签: swift

我正在尝试进行后台api调用并在返回结果时更新UI,我查看了GCD文档。
下面的逻辑有问题吗?

    // get data from server
    let priority = DISPATCH_QUEUE_PRIORITY_BACKGROUND
    dispatch_async(dispatch_get_global_queue(priority, 0)) {
       self.getUserData() // update self.data1 global variable
       self.getCompanyData() // update self.data2 global variable

        dispatch_async(dispatch_get_main_queue()) {
                self.updateUI() //update UI using self.data1 and self.data2 global variable
        }

    }


func getUserData(){
... api1 call
... print("1")

}

func getCompanyData(){
... api2 call
... print("2")
}

func updateUI(){
... print("UI")
}

执行时,输出基本上是; UI
1
2个


api两个api调用完成后我想调用updateUI函数。


下面的一个api调用函数;

let fullUrl = self.apiDomain + "/user_details/" + String(self.user_id)
    let url:NSURL = NSURL(string: fullUrl)!
    let session = NSURLSession.sharedSession()
    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "GET"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

    let task = session.dataTaskWithRequest(request) {
        (
        let data, let response, let error) in
        guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
            print(error)
            return
        }

            var apiCallResult: [String:AnyObject]?
            let result = NSString(data: data!, encoding: NSUTF8StringEncoding)
            do {
                apiCallResult = try NSJSONSerialization.JSONObjectWithData(result!.dataUsingEncoding(NSUTF8StringEncoding)!, options: []) as? Dictionary<String, AnyObject>
            } catch let error as NSError {
                print(error.localizedDescription)
                return
            }

            let aa = apiCallResult!["data"]! as! NSDictionary
            print(aa)

    }

    task.resume() 

1 个答案:

答案 0 :(得分:4)

您可以使用dispatch groups。以下是等待同步任务的代码示例:

let group = dispatch_group_create()

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { () -> Void in
    print("Block1")
    NSThread.sleepForTimeInterval(1.0)
    print("Block1 End")
}

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { () -> Void in
    print("Block2")
    NSThread.sleepForTimeInterval(1.0)
    print("Block2 End")
}

dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { () -> Void in
    print("Block3")
}

并且可以产生这样的输出:

Block1
Block2
Block1 End
Block2 End
Block3

如果您使用dispatch groupsmultiple asynchronous tasks上等待,则需要使用dispatch_group_enterdispatch_group_leavedispatch_group_wait。这是代码示例。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in
    let group = dispatch_group_create()

    print("Block1")
    dispatch_group_enter(group)
    foo1.sendAsynchronousRequest() {
        print("Block1 End")
        dispatch_group_leave(group)
    }

    print("Block2")
    dispatch_group_enter(group)
    foo2.sendAsynchronousRequest() {
        print("Block1 End")
        dispatch_group_leave(group)
    }

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        print("Block3")
    })
} 

请阅读此处了解更多详情http://www.raywenderlich.com/79150/grand-central-dispatch-tutorial-swift-part-2