从soap Web服务结果更新文本字段失败
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从soap Web服务结果更新文本字段失败相关的知识,希望对你有一定的参考价值。
我刚刚开始使用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”。而不是这个func以并行方式执行dataTask和task.resume()之后的所有代码(return _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)
}
第一个问题:
文本字段txt1
是零。如果尚未正确初始化xib或storyboard中的视图或视图控制器,则会发生这种情况。如果您在xib或故事板中有插座(或任何自定义),则只有在使用正确的init函数时才会初始化它们。只需调用默认的init就不会初始化插座。
要从主包中名为MyViewController
的xib初始化类MyViewController.xib
的视图控制器:
let myViewController = MyViewController.init(nibName:"MyViewController", bundle:Bundle.main)
要初始化一个MyViewController
类的视图控制器,它位于主包中的myVC
中并且具有标识符Main.storyboard
:
if let myViewController = UIStoryboard.init(name:"Main",bundle:Bundle.main).instantiateViewController(withIdentifier:"myVC") as? MyViewController{
//use the vc
}
要初始化在主要包中的xib“MyView.xib”中自定义的类MyView
的视图:
if let myView = Bundle.main.loadNibNamed("MyView",owner:self)?.first{
//use your view
}
第二个问题:
在控制进入完成处理程序之前执行行return _re
,其中_re
获取新值,因为网络调用是异步的。因此它返回初始值。如果要异步返回某些数据,则应使用完成处理程序。
func httpGet(request: URLRequest,completionHandler:@escaping (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)
//execute from the main thread to update txt1
DispatchQueue.main.async(execute:{
self.txt1.text = _re
})
completionHandler(_re)
}
})
task.resume()
}
以上是关于从soap Web服务结果更新文本字段失败的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Drupal 视图中显示 Web 服务 (SOAP) JSON 结果
Java 使用 SSL 握手失败连接到 SOAP Web 服务
如何将 WS-Addressing 字段添加到 SOAP 消息
如何在 SENCHA TOUCH 中使用 SOAP Web 服务?