我刚刚开始使用swift4为ios编写应用程序,但是我遇到了2个问题,我在调用Soap Web服务,成功了,
并且我可以在输出中打印结果(具有xml格式的字符串),并且我想以此结果来更新一个文本字段的文本,因为此任务在后台运行,所以将以下代码放在completionHandler的闭包中:

@IBOutlet weak var txt1: UITextField!

func httpGet(request: URLRequest)-> String{
    let soapReqXML = "some code..."
    let is_URL: String = "http://xxx.x.x.12/soapservice.asmx"
    let url = URL.init(string: is_URL)
    let my_Request = NSMutableURLRequest(url: url!)
    let configuration = URLSessionConfiguration.default
    let session = URLSession(configuration: configuration, delegate: self, delegateQueue:OperationQueue.main)

    my_Request.httpMethod = "POST"
    my_Request.httpBody = soapReqXML.data(using: String.Encoding.utf8, allowLossyConversion: false)
    my_Request.addValue("host add...", forHTTPHeaderField: "Host")
    my_Request.addValue("text/xml;charset =utf-8", forHTTPHeaderField: "Content-Type")
    my_Request.addValue(String(soapReqXML.count), forHTTPHeaderField: "Content-Length")
    my_Request.addValue("http://mservice.my.xx/SNA...", forHTTPHeaderField: "SOAPAction")

    var responseData : Data = Data()
    var _re : String = "000"
    let task = session.dataTask(with: my_Request as URLRequest, completionHandler: {data, response, error -> Void in
        if error == nil {
            responseData = data!
            _re = self.stringFromXML(data:responseData);   // calling stringFromXML to convert data into string
            print("the result is :"+_re) // working here, I can see the good result in the output
            //execute from the main thread to update txt1
            DispatchQueue.main.async(execute:{
                 self.txt1.text = re // first problem, the error is :Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
                 self.txt1.text = "text" // I even change into "text", same error happened here
            })
        }
    })
    task.resume()
    return _re       // second problem, the return is always 000
}


我的第一个问题是:如果我在ipad模拟器中调用该函数,则在调试中将其写为:txt1 =(UITextField!)nil,
 第二个问题是,收益始终是000(初始值)

有人可以帮我检查一下吗?谢谢!

最佳答案

您可以看到输出,因此re不是nil,因此txt1可能为nil。在“接口”构建器中检查txt1是否与UITextField连接。

第二个问题很明显。 dataTask在后台运行,因此func httpGet不会等待dataTask完成,然后继续运行代码“ return _re”。代替此函数,它以并行方式执行dataTask和task.resume()之后的所有代码(返回_re)。因此re的初始值保持不变,因为dataTask需要一些时间来完成执行。

您应该使用完成处理程序:

func httpGet(request: URLRequest, completion: @escaping (String) -> ()) {
    let soapReqXML = "some code..."
    let is_URL = "http://xxx.x.x.12/soapservice.asmx"
    let url = URL(string: is_URL)
    let my_Request = NSMutableURLRequest(url: url!)
    let configuration = URLSessionConfiguration.default
    let session = URLSession(configuration: configuration, delegate: self, delegateQueue: .main)

    my_Request.httpMethod = "POST"
    my_Request.httpBody = soapReqXML.data(using: .utf8, allowLossyConversion: false)
    my_Request.addValue("host add...", forHTTPHeaderField: "Host")
    my_Request.addValue("text/xml;charset =utf-8", forHTTPHeaderField: "Content-Type")
    my_Request.addValue(String(soapReqXML.count), forHTTPHeaderField: "Content-Length")
    my_Request.addValue("http://mservice.my.xx/SNA...", forHTTPHeaderField: "SOAPAction")

    session.dataTask(with: my_Request as URLRequest, completionHandler: { data, response, error in
        if error == nil {
            let result = self.stringFromXML(data: data!)
            DispatchQueue.main.async {
                self.txt1.text = result
            }
            completion(result)
        }
    }).resume()
}


用法:

httpGet(request: request) { result in
    print(result)
}

09-06 09:54