Delegates en Swift: como declarar y usar un protocolo para manejar eventos externos

Comparte esta entrada

Share on facebook
Share on linkedin
Share on twitter
Share on email

En este artículo aprenderemos a partir de un ejemplo básico, como utilizar un protocolo en Swift para manejar eventos enviados desde una clase externa. Aprenderemos como declarar un protocolo y, como definir el delegado del protocolo dentro de la clase que va a manejar sus eventos. En este ejemplo en particular, implementaremos una función externa que se encarga de descargar información de manera asíncrona y una vez completada la descarga, llama al protocolo para comunicarle como el resultado de esta.

Para empezar hemos de crear una Single View Application en lenguaje Swift.

En este ejemplo vamos a realizar una petición no segura HTTP, por lo que, si estamos utilizando iOS9 o versiones posteriores, necesitaremos autorizar estas peticiones modificando el fichero info.plist. Para ello hacemos click derecho en el fichero, seleccionamos Open As, seleccionamos Source code y añadimos las siguientes lineas para permitir el uso del protocolo HTTP para nuestra app:

<key>NSAppTransportSecurity</key>
<dict>
      <key>NSAllowsArbitraryLoads</key>
      <true/>
</dict>

Declaración del protocolo

Continuemos ahora creando un nuevo fichero Swift. Aquí es donde vamos a definir los métodos que contendrá nuestro protocolo.

Un protocolo se declara según el siguiente formato:

@objc protocol nombre_del_protocolo {
      func funcion_del_protocolo(data: AnyObject)
      optional func funcion_opcional_del_protocolo()
 }

Podemos definir las funciones que van a ser manejadas por el delegado y los parámetros de estas. También podemos utilizar la palabra reservada optional, indicando que la función en cuestión no tiene porque ser implementada obligatoriamente.

 El protocolo que vamos a definir en nuestro ejemplo se ocupara de manejar los eventos resultado después de realizar una descarga, por ello tendrá la siguiente forma:

 @objc protocol DataResultDelegate {
       func success(data: NSData)
       optional func error()
}

Definición de la función de descarga

Para continuar vamos a definir la función que se encargará de realizar la descarga y llamar al protocolo una vez completada.

Creamos un nuevo fichero Swift de la misma forma que hicimos anteriormente. En el es donde definiremos e implementaremos la función encargada de realizar la petición HTTP asíncrona y descargar la información. Como parámetros le pasaremos el enlace de donde realizar la petición y el protocolo que manejara los eventos resultado de la petición.

func downloadFromUrl(stringURL: String, handler: DataResultDelegate) {
   //Inicializamos parámetros de la petición
   let url = NSURL(string: stringURL)!
   let session = NSURLSession.sharedSession()
   let request = NSMutableURLRequest(URL: url)
   request.timeoutInterval = 8
   
   //Definimos comportamiento para el resultado de la petición
   let asyncDownloadTask = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
       guard let data = data else {
           if let errorCallback = handler.error {
               errorCallback()
           }
           return
       }
       handler.success(data)
   }
   //Realizamos la petición
   asyncDownloadTask.resume()
}

Implementación del delegado

Por último hemos de definir e implementar la clase delegada que va a manejar los eventos del protocolo.

Para ello seleccionamos el fichero ViewController.swift y definimos la clase ViewController como implementación del protocolo DataResultDelegate:

class ViewController: UIViewController, DataResultDelegate {

Al no tener implementados aún las funciones declaradas en el protocolo nos saltará un error:

Type ‘ViewController’ does not conform to protocol ‘DataResultDelegate’”. Para ajustar la clase al protocolo hemos de definir la implementación para las funciones declaradas.

   func success(data: NSData) {
       let strData = NSString(data: data, encoding: NSUTF8StringEncoding)
       print(strData)
}
   func error() {
       print("error")
}

Para terminar, si queremos probar el funcionamiento del ejemplo solo tenemos que llamar a la función downloadFromUrl y comprobar como realmente nuestro delegado recibe los eventos resultado de la descarga:

   override func viewDidLoad() {
       super.viewDidLoad()
       let httpFuncions = HTTPFunctions()
       httpFuncions.downloadFromUrl("link", handler: self)
   }

Suscríbete a nuestra newsletter

Más para explorar

Conexiona integra Z-Wave en el iPlace
software

iPlace ahora trabaja con Z-Wave.

Conexiona ha integrado el protocolo de comunicación inalámbrica Z-Wave en nuestro sistema IoT de automatización y control iPlace.

Mindtech logo
Uncategorized

Conexiona estará en Mindtech 2019.

Conexiona apuesta por MindTech 2019, Metal Industry and Technologies International Trade Fair, que se celebrará los días 10, 11 y 12 de septiembre en el Recinto Ferial de Vigo.

Da el paso

No esperes a que la competencia te adelante sin que te des cuenta.

Los datos facilitados a través de este formulario serán tratados por Conexiona Telecom, S.L CIF B32350795 domicilio en Edificio Tecnopole I, Parque Tecnológico de Galicia, San Cibrao das Viñas. 32911 – Ourense, de acuerdo a lo establecido en nuestra política de privacidad con la finalidad de poder enviarle información sobre nuestros productos/servicios. Los datos recabados por este formulario no se cederán a terceros salvo por obligación legal. Le recordamos que usted tiene derecho al acceso, rectificación, limitación de tratamiento, supresión, portabilidad y oposición al tratamiento de sus datos dirigiendo su petición a la dirección postal indicada o al correo electrónico [email protected] Igualmente puede dirigirse a nosotros para cualquier aclaración adicional. En caso de no aceptación sus datos no serán tratados.