Swift

时间:2017-09-06 10:02:19

标签: swift parameters completionhandler

我是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服务类中,而不是在视图控制器中。

有什么想法吗?感谢。

3 个答案:

答案 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...
}

我没有测试过,所以不确定它是否会起作用。