Swift - 在继续之前等待“dataTaskWithRequest”响应

Posted

技术标签:

【中文标题】Swift - 在继续之前等待“dataTaskWithRequest”响应【英文标题】:Swift - Wait for "dataTaskWithRequest" response before proceeding 【发布时间】:2016-06-09 12:12:17 【问题描述】:

我知道这个问题之前已经被问过几十次了,但不幸的是,我对 Swift 的了解不够,无法根据我的问题调整这些答案。

基本上,我有一个函数可以将 POST 请求发送到服务器上的 php 脚本,但接收响应似乎比我的脚本使用结果需要更长的时间。它发送一个数字变量并接收一个作为响应,因此我还将它从“any_object”转换为“NSNumber”。 据我了解,我需要实现一个完成处理程序,但我似乎无法弄清楚如何让它与下面的代码一起使用。

var dataResult: Int = 0
var dataReceived: NSNumber?

    func remoteRand() 
        let dataToSend = 1
        let myUrl = NSURL(string: "http://localhost/scripts/phpScript.php")
        let request = NSMutableURLRequest(URL: myUrl!)
        request.HTTPMethod = "POST"
        let postString = "dataToSend =\(dataToSend)"
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) 
            data, response, error in

            dispatch_async(dispatch_get_main_queue()) 

                if (error != nil) 
                    self.displayAlertMessage((error?.localizedDescription)!)
                    return
                
                do 
                    let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary

                    if let parseJSON = json 
                        let dataReceived = parseJSON["dataValue"]
                        self.dataResult = (dataReceived as! NSNumber).integerValue
                        print("\(self.dataResult) is server response")
                    
                 catch  print(error)
            
        
        task.resume()
        processResult()
    

    func processResult() 
        print(dataResult)
    

我得到的结果是:

0
1 is server response

如何让它在继续执行下一个函数之前等待响应,或者在确认完成后触发下一个函数?

提前致谢!

【问题讨论】:

【参考方案1】:

任务在与其被调用的线程不同的线程上完成,这是设计使然,因此网络请求不会停止在主线程上的执行。因此,您的代码块被异步发送,并且在网络请求完成之前调用 processResult。您可以将调用放在 do 块中,也可以在可以调用的方法中添加闭包。

func remoteRand(completion: (response: Int) ->()) 

// your code
// process JSON
// get value
completion(dataReceived) 
// is passed back, just like the dataTaskWithRequest method to your caller where you can set the property on self, etc.

在某处使用它:

remoteRand  [weak self] (response) in 
    self?.dataResult = response

【讨论】:

感谢您的快速响应。你说的很有意义,我认为我已经正确地实现了你的解决方案,但是在调用 remoteRand() 函数的其他函数中出现错误,因为它需要一个参数。 “在调用错误中缺少参数 #1 的参数”。它似乎不接受我传递的任何东西。 去掉你调用它的地方再输入一遍,Xcode会自动补全你可以使用的参数的pattern,如上图。 在阅读了您的最后一条评论后,我按照您所说的做了,然后我有一个瞬间意识到,我认为这一切都说得通,并且我想通了。我正在相应地获取响应数据,但我仍然遇到在我需要响应后收到响应的相同问题。我想发布我尝试过的内容,但现在快凌晨 3 点了,我需要上床睡觉。如果有任何方法可以将您的代码发布到我的上下文中,我们将不胜感激。当我下次有机会时,我会检查一下,看看我有多接近。为你的耐心喝彩:) 当然,这需要一些时间,但我稍后会为您更新我的答案。 嗨@thefredelement,我只是想知道您是否有机会帮我看一下该代码。干杯伙伴。

以上是关于Swift - 在继续之前等待“dataTaskWithRequest”响应的主要内容,如果未能解决你的问题,请参考以下文章

如何在执行函数之前等待 Swift 中的变量? (迅速)

在执行代码之前等待 Swift 动画完成

节点在继续之前等待异步功能

JavaScript(异步)如何确定在继续之前要“等待”啥?

NSURLSession 响应字符串完成块 - Swift

在执行代码之前等待用户关闭模态视图(Swift 2.0)