我刚刚开始使用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)
}