Home » Análisis » Swift 4, así es la nueva versión del lenguaje
Swift 4

Swift 4, así es la nueva versión del lenguaje

Quedan pocas semanas, el próximo 5 de junio veremos de forma oficial, el lanzamiento de la primera beta de la nueva versión del lenguaje de programación de Apple. Pero mientras, como es un producto de código abierto, podemos bajar y probar sus versiones preliminares (pequeños fallos, mediante) y ver en qué va a consistir.

Instalando Swift 4

Para poder probarlo, no necesitamos esperar a Xcode 9 Beta, podemos usar nuestra actual versión 8.3.2 sin ningún problema. Solo tenemos que ir a la web de Swift y descargar la versión correspondiente que en este caso es Swift 4.0 Development. Solo pulsamos aquí y descargamos la versión para Xcode. Se descargará un archivo PKG que instalamos con doble click y nada más.

Swift 4 Toolchain

Una vez instalado, abrimos Xcode y un nuevo Playground. En él, vamos a Xcode, Preferences, Toolchain y allí veremos que tenemos la cadena de Xcode 8.3.2 (o la versión que tengamos instalada) y la nueva de Swift 4 que acabamos de instalar. Simplemente elegimos esta nueva y automáticamente ya podemos trabajar con Swift 4 y probar sus nuevas funciones que pasamos a comentar a continuación.

Swift 4, nuevas funciones

Para este artículo he tomado como base un Playground que ha creado Ole Begemann, desarrollador y colaborador del medio objc.io y co-autor del libro editado por objc, Advanced Swift. En su página web, oleb.net ha realizado un interesante libro Playground que nos permite echar un vistazo con ejemplos a algunas de las nuevas funciones que tendremos en Swift 4 y que vamos a pasar a explicar. El playground podéis bajarlo desde su repositorio en GitHub directamente pulsando aquí, aunque no funcionará si no hemos hecho previamente la instalación que hemos comentado de Swift 4.

Os avisamos que podemos encontrarnos comportamientos raros, como que de error pero a pesar de todo se ejecute cada página del Playground. Son cosas extrañas. Si hace cosas muy raras, mejor cerramos y volvemos a abrir.

No obstante, no vamos a ceñirnos a sus ejemplos concretos, si no que daremos los nuestros propios en algunos casos para que queden más claras las nuevas funcionalidades y explicaremos mejor los cambios. Usaremos el Playground simplemente como base y documento de trabajo. Además, no vamos a ver todo lo que cuenta sino solo aquello que realmente son cosas que nos permitirán mejorar nuestro trabajo en el día y que estén en una fase que pueda probarse o entenderse en su concepto aunque aún no funcione.

Rangos de un solo lado

Sabemos que en Swift podemos crear un rango cerrado, por ejemplo de valores enteros, simplemente haciendo 4...9 y tendremos un rango que recorre del 4 al 9. E incluso, si lo ponemos entre paréntesis, podemos acceder a él con las funciones genéricas de colección de programación funcional como (4...9).map { $0 }.

Pero en Swift 4 tenemos una incorporación interesante: rangos de un solo lado. Si ponemos 1... tendremos un rango infinito de valores desde 1 hasta el total de elementos que tenga el tipo usado (un número entero en este caso). Podemos poner los valores del rango tanto a la izquierda como la derecha, pero solo los rangos a la izquierda están conformados como secuencia.

Lo más interesante que podemos hacer con ellos, por ejemplo, es acceder a todos los elementos de un array desde una posición hasta el final, como en uno de los ejemplos del Playground.

Esto también nos sirve para igualación de patrones, como en un switch, donde podemos tener un case equivalente a que el valor que estamos validando sea menor, mayor, menor o igual o mayor o igual.

Usando los rangos parciales o completos, 1... sería igual o mayor que 1 pero 1 ..< sería mayor que 1, sin incluir el 1. De igual forma ...0 sería menor o igual que 0 y ..< 0 sería menor de 0.

Literales multi-línea

Esto es interesante: si usamos una triple comilla como elemento delimitador de una cadena, podremos tener una cadena multi-línea que almacene igualmente los saltos de línea.

Lo interesante aquí es que cada salto de línea se convierte en un carácter de escape \n de salto de línea y además, controla el uso de espacios, de forma que la siguiente línea siempre empezará en el primer carácter que no sea un espacio, en la línea inferior. Obviamente, cuando encuentre un nuevo """ será cuando se cierre esta cadena multi-línea.

En cuanto a las cadenas, el tipo String (como ya comentamos en su momento) vuelve a ser una colección como lo fue en Swift 1, pero en este caso aun no está terminada bien la implementación y ya la veremos en profundidad en su momento pues requerirá un artículo solo para esto. Pero en principio Swift 4 ya soporta Unicode 9 o incorpora un nuevo tipo Substring que se conforma igualmente con el protocolo StringProtocol que engloba todos los posibles subtipos de las cadenas.

Keypath

Este es uno de los elementos que vienen heredados de Objective-C y Cocoa. Uno de esos que eran objeto de errores a diestro y siniestro como lo era, por ejemplo, el uso de los selectores. ¿Por qué? Porque se representan por cadenas, donde si no escribimos bien el nombre de la propiedad a la que queremos acceder, tendremos un error de cierre de aplicación asegurado.

En Swift 3 se introdujo una notación que permitía hacer uso del símbolo # para capturar estos keypath, al igual que sucedía con los selectores. De esta forma se podía llamar, por ejemplo, en la creación de un NSSortDescriptor para Core Data, usando la siguiente nomenclatura:

Pero ahora en Swift 4 se introduce una forma más elegante si cabe, usando simplemente una barra invertida como la que usamos en la interpolación de las cadenas. De esta forma, el keypath quedaría de la siguiente forma:

De esta interesante forma, ni siquiera hay que repetir la palabra clave keyPath en forma alguna.

Serialización de tipos en Swift

En Swift 4 podremos serializar cualquier tipo, no solo clases a través del famoso NSCoding. Para ello, tenemos un nuevo protocolo llamado Codable al que conformar aquel tipo que queramos poder serializar. Por ejemplo, si tenemos un struct, basta conformarlo con este protocolo (que no requiere la inclusión de elemento alguno). La serialización se realiza con la ayuda de JSON y podemos incluso hacerlo contra un array de tipos conformados. El motivo es simple: si creamos un array de tipos conformados a un protocolo, este será también de dicho protocolo y podrá hacer un casting seguro a él, del que se encarga el propio sistema.

Tras esto, bastará que hagamos el write correspondiente a la carpeta documentos o donde queramos (yo lo cifraría antes), para que este dato quede grabado. Luego para recuperarlo, nada más fácil que usar la operación inversa, una vez recuperado el tipo Data.

No obstante, aunque la implementación está definida, en estos momentos no funciona por algún tipo de bug. Pero vamos, que será solucionado y así es como podremos serializar cualquier tipo de dato dentro de Swift de forma nativa: a través de estos codificadores y descodificadores de JSON, siempre y cuando nuestro tipo este conformado al protocolo Codable.

Cambios en diccionarios y conjuntos

Ahora se pueden hacer cosas interesantes, como crear un diccionario a partir de una secuencia de valores.

Haciendo uso de los rangos abiertos que generan secuencias infinitas, podemos usar la función zip para crear valores de índice auto-incremental que se correspondan con el total de valores del array nombres que hemos creado.

Otro gran cambio es que los diccionarios y conjuntos a los que les apliquemos las funciones genéricas de colecciones en programación funcional como map o filter, ahora devolverán el tipo original (el diccionario o el conjunto) y no un array.

Y por último algo muy interesante es la posibilidad de agrupar arrays en diccionarios a partir de un valor de agrupación que definamos, usando un nuevo método grouping de inicialización del diccionario.

En este caso, el closure está definiendo cuál es el valor de agrupación, ya que el parámetro abreviado para este caso $0 es de tipo String, el mismo tipo de cada elemento del array que va a agrupar. Al poner $0.first! estamos usando la nueva propiedad de los tipos cadenas de ser colección y guardando su primer carácter. Si pusiera en su lugar $0.last! tendría una agrupación por el último carácter en lugar del primero. Por lo tanto, lo que ha de devolver ese closure es el valor dentro del $0 (cada elemento del array) que va a usarse para la agrupación. El resultado es un diccionario con la clave igual al dato de agrupación (el que ha devuelto el closure) y el dato igual a cada uno de los valores del array tratado. Algo muy útil, sin duda.

Otros pequeños cambios

Algunos pequeños cambios incorporados muy interesantes podemos resumirlos en los siguientes puntos:

  • Existe un método swapAt que nos permitirá intercambiar los valores de dos posiciones en un array mutable. Bastará decir array.swapAt(5,3) para que los valores de las posiciones 5 y 3 de un array se intercambien uno por el otro.
  • Los subscripts ahora pueden ser usados con tipos genéricos pudiendo definir un subscript<T> que además devuelva tipos también genéricos.
  • También en los subscript podemos hacer algo parecido a lo que es el operador de coalescencia nula en las opcionales. De esta forma, para obtener un valor de un subscript que no sea opcional, podemos indicar un valor por defecto. Sería así: let valor = dict[4, default: "No hay"].
  • Se han solucionado algunos errores de conversión entre tipos numéricos que tienen que ver con NSNumber y tipos numéricos de C.
  • Ahora podemos declarar tipos que no solo sean de un tipo en concreto, sino que en su declaración se conformen a un protocolo determinado (como sí podíamos hacer en Objective-C). De esta forma, ahora podemos declarar: let tabla: UITableView & UITableViewDataSource. Haciendo esto, habremos declarado un tipo UITableView en tabla, que a su vez también estará conformado con el protocolo UITableViewDataSource.

Incorporaciones, mejoras, poco cambio

Esa es la esencia de Swift 4. Mejoras, muchas mejoras, incorporaciones para hacer mejor nuestro trabajo pero muy poco cambio que haga a nuestro código incompatible. Con Xcode 9 podremos usar Swift 3.1 o Swift 4 indistintamente para un proyecto (por ahora, no podremos tener ambos en un mismo proyecto) pero Swift 4 no tiene tantos cambios y en menos de un día y gracias al asistente de migración lo tendremos todo funcionando.

Lo hemos comentado muchas veces: todos los lenguajes evolucionan, cambian y requieren cambios de una versión a otra. También sucede con el propio Cocoa. Pero Objective-C, en su carente evolución en el transcurso de los años (aunque también la ha tenido) nos ha malacostumbrado. Java, Kotlin o cualquier otro lenguaje vivo cambia, nos obliga a adaptar el código y no pasa nada.

Lo importante ahora es pensar cuándo llegaremos a la resilencia del lenguaje, a esa estabilidad ABI que nos permita, con una versión binaria estable y no cambiante, poder usar la versión que queramos del lenguaje en cualquier momento y que el binario siempre sea el mismo. Ese es el objetivo y queda muy poco para ello. Mientras, seguiremos informando de los cambios puntualmente. Un saludo y Good Apple Coding.

Acerca de Julio César Fernández

Analista, consultor y periodista tecnológico, desarrollador, empresario, productor audiovisual, actor de doblaje e ingeniero de vídeo y audio.

Otras recomendaciones

Swift4 (I)

Swift 4 (I), compatibilidad y otras mejoras

Revisamos Swift 4 ahora que hemos podido ver su lanzamiento oficial junto a Xcode 9, pieza fundamental. Además explicamos su proyección de compatibilidad y la estabilidad del lenguaje de cara al futuro inmediato. ¿Tengo que migrar? ¿No? ¿Qué supone? ¿Funciona Swift 3 en Xcode 9? Todas las preguntas que se pueden hacer sobre compatibilidad de Swift 4 y Xcode 9, resueltas y explicadas junto a otros importantes cambios en el lenguaje.