我是Swift的新手。按下按钮时,我的视图控制器调用Web服务类的方法。该方法依次调用dataTask(),并提供完成处理程序:
let task = session.dataTask(with: request as URLRequest) { data, response, error in
guard error == nil && data != nil else {
print(error ?? "")
return
}
// print(JSON(data:data!))
print ("data : ", data ?? "-- no data --")
print ("response : ", response ?? "-- no response --")
print ("error : ", error ?? "-- no error --")
完成处理程序需要更新视图控制器的GUI。但是,处理程序似乎只采用三个标准参数。如何将视图控制器引用传递给它?处理程序无法执行self.someTextView.update(.....)来更新GUI,因为它位于Web服务类中,而不是在视图控制器中。
有什么想法吗?感谢。
答案 0 :(得分:1)
正如dataTask(with:completionHandler:)中提到的那样:
此完成处理程序采用以下参数:
data
服务器返回的数据。
response
提供响应元数据的对象,例如HTTP标头和 状态代码。如果您正在发出HTTP或HTTPS请求,则返回 object实际上是一个HTTPURLResponse对象。
error
一个错误对象,指示请求失败的原因,如果是,则为nil 请求成功。
这意味着 - 显然 - 它与UIViewController无关。
所以,如果你想包含" ViewController"对于这样一个进程,你可以实现自己的包装器来完成这样的任务,例如,你可以创建一个带有完成参数的函数 - 一个转义关闭 - ,如下所示:
func request(completion: @escaping () -> ()) {
let task = session.dataTask(with: request as URLRequest) { data, response, error in
guard error == nil && data != nil else {
print(error ?? "")
return
}
// print(JSON(data:data!))
print ("data : ", data ?? "-- no data --")
print ("response : ", response ?? "-- no response --")
print ("error : ", error ?? "-- no error --")
// now you could call the "completion" parameter:
completion()
}
}
在视图控制器中,您可以将其命名为:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
request {
// now you could update your textview:
self.someTextView.update(.....)
}
}
}
您可以声明request
的签名以满足您的需求......
答案 1 :(得分:0)
您可以发布本地通知,该通知命中方法,并在UIViewController类中声明该方法。
以下是代码:
在Web服务类中:在完成处理程序中:
NotificationCenter.default.post(名称: Notification.Name(“Notification_NAME_HERE”),object:nil,userInfo: 无)
在UIViewController类中:在viewDidLoad中:
NotificationCenter.default.addObserver(self,selector: #selector(notificationHandler(notification :)),name:Notification.Name(Notification_NAME_HERE),object:nil)
将一个notificationHandler方法添加到UIViewController类中:
func notificationHandler(通知:通知) { //在这里更新ui }
此方法将由Completion Handler命中,同时您可以将UI或任何您想要的内容更新到UIViewController类中。
我认为这会对你有所帮助。
答案 2 :(得分:0)
不确定,但是如何使用捕获值呢? 有点像...
...code...
var somevar = 3
....whateverblock { [unowned somevar], (default parameters of the blcok) in
somevar = 4
...code...
}
我没有测试过,所以不确定它是否会起作用。