等到所有元素都从SOAP请求中解析出来

时间:2016-05-18 18:47:44

标签: ios swift soap nsurlsession

我目前正在尝试在Swift中实现一个发送返回多个元素的查询的功能。我的查询正在运行,但似乎程序不会等待所有元素(或任何,有时)被解析 - 通常使我的标签为空。如何让程序在继续运行之前等待响应完全完成。

我目前的设置是:

sendQuery(查询)
//执行下一个更新标签的功能

sendQuery是一个设置SOAP请求并启动NSURLSession的函数,然后由XML解析器解析响应,并根据currentElement的内容设置字符串值。

我之前没有使用swift的经验,所以我不确定我应该查看的方向。

编辑:带有完成处理程序的SOAP会话请求如下所示:

func sendQuery()
{
 //setup request params

    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        let parser = NSXMLParser(data: data!)
        parser.delegate = self
        if parser.parse() {
            print(self.currentElementName)
        }
        if error != nil
        {
            print("Error: " + error!.description)
        }
    })

    task.resume()
}

EDIT2:

我已将所有内容更改为以下内容: 这是我的主要viewController:

NetConn.getItemInfo(query, withCompletionClosure: {(itemInfo: [String]) in
                    self.itemInfo = itemInfo
                })

虽然这是在一个单独的NetworkConnections文件中:

func getroomInfo(query: String, withCompletionClosure completionClosure: (roomInfo: [String])->())// -> [String]
{
    //Setup SOAP request information
    session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
        let parser = NSXMLParser(data: data!)
        parser.delegate = self
        if parser.parse() {
            print(self.currentElementName)
        }
        if (error != nil)
        {
            print("Error: " + error!.description)
        }
        completionClosure(roomInfo: self.roomInfo)
    }).resume()

}

这确实等到批处理响应完成后,但是 - 我发现如果我在调用后立即尝试打印信息,它仍然没有改变。它似乎是一个线程正在接受调用并运行它,而原始线程一直在主代码块中运行。我怎样才能防止这种情况发生?

.... edit3:我相信添加

dispatch_async(dispatch_get_main_queue(), { () -> Void in
                //ui stuff
            })

进入主视图控制器调用中的完成处理程序将解决此问题。

1 个答案:

答案 0 :(得分:0)

你永远不应该等待,而是你需要重新构造代码以使用一个完成块,即使用闭包实现的完成处理程序,例如这个(伪代码不可编译的代码,我不记得顶部的闭包语法我的脑袋)

sendQueryWithCompletionHandler: { (data, response, error) in
  // this is where the completion handler code goes
})

这是一种方法,另一种方法可能是使用sendQuery()方法的完成闭包来代替在数据可用时广播通知以及为该广播列出的调用代码。 哪个更合适取决于整体设计和要求。

您需要了解代码的异步执行。

(块是objective-c术语,关闭是Swift术语,用于相同的概念)