Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Swift中使用dispatch_async和update UI调用2个不同的api_Swift - Fatal编程技术网

如何在Swift中使用dispatch_async和update UI调用2个不同的api

如何在Swift中使用dispatch_async和update UI调用2个不同的api,swift,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 va

我正在尝试进行后台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")
}
当它执行时,输出基本上是; 用户界面
1
2


我想在两个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() 
让fullUrl=self.apiDomain+“/user\u details/”+字符串(self.user\u id)
让url:NSURL=NSURL(字符串:fullUrl)!
let session=NSURLSession.sharedSession()
let request=NSMutableURLRequest(URL:URL)
request.HTTPMethod=“GET”
request.cachePolicy=NSURLRequestCachePolicy.ReloadIgnoringCacheData
让task=session.dataTaskWithRequest(请求){
(
让数据、让响应、让错误)进入
保护let:NSData=data,let:nsurresponse=response,其中error==nil-else{
打印(错误)
返回
}
var apiCallResult:[字符串:AnyObject]?
让结果=NSString(数据:data!,编码:NSUTF8StringEncoding)
做{
apiCallResult=尝试NSJSONSerialization.JSONObjectWithData(结果!.dataUsingEncoding(NSUTF8StringEncoding)!,选项:[])作为字典
}将let错误捕获为NSError{
打印(错误。本地化描述)
返回
}
设aa=apiCallResult![“数据”]!as!NSDictionary
印刷品(aa)
}
task.resume()
您可以使用。以下是等待同步任务的代码示例:

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

有关更新问题的更多详细信息,请阅读此处。谢谢。如果
getUserData()
getCompanyData()
都不异步工作,那么就没有问题了。就像@vadian暗示的那样,问题是因为“getUserData”和“getCompanyData”也是异步API调用。@EricD。有什么建议吗?我怎么能等他们两个都完成并更新UI呢?我想就是这样吧?self.getUserData()->self.getCompanyData()->self.updateUI()。。。。当我尝试打印时,其中3个应该在同一个调度中,正如您所提到的。但是当我调用函数而不是调用api来获取结果的print时,它会打印block3,然后再打印api调用结果。我认为getUserData()和getCompanyData()需要工作
synchronous
,因为
dispatch\u group\u async
已经支持
asynchronous
。您能再解释一下吗?顺便说一句,谢谢你的“调度组”,它非常有用。我认为你在块1和块2的
dispatch\u group\u async
中调用工作的函数
asynchronous
,因此它会立即标记块1和块2已完成,并通知块3。什么是foo1和foo2?