Ya estamos casi en septiembre, y dentro de nada tendremos entre nosotros las nuevas versiones oficiales de iOS 11, macOS High Sierra, Xcode 9, y por supuesto Swift 4.
Swift 4 es la primera versión del lenguaje retro-compatible. Esto quiere decir, que si compilamos una app escrita en Swift 3 con el compilador de Swift 4, no deberíamos encontrarnos con errores.
Swift 4 introduce algunas mejores o añadidos, que vamos a analizar con todo detalle y ejemplos en este artículo.
La clase String
La primera mejora que podemos encontrar, es que las cadenas vuelven a ser tratadas por el lenguaje como colecciones. Es decir, podemos utilizar métodos como count
, append
, o iterar los elementos directamente sobre la variable en cuestión, sin hacer uso de la propiedad characters
que teníamos en Swift 3.
1 2 3 4 5 6 7 8 |
// Swift 3 str.characters.count //Swift 4 str.count |
Además, se introduce una mejora muy interesante para el manejo de cadenas con múltiples líneas. Hasta ahora, para lograr tener varias líneas en una cadena, teníamos que utilizar el carácter \n. Ahora, podemos hacer mucho más legible haciendo uso de “”” (triples dobles comillas).
1 2 3 4 5 6 7 8 9 10 11 |
// Swift 3 let str = "Mi cadena con \n varias lineas" //Swift 4 let str = """ Mi cadena con varias lineas """ |
Por último, tenemos mejoras en cuanto al manejo de caracteres de tipo Unicode. Y es que en Swift 3, no podíamos contar caracteres por ejemplo, si éstos se trataban de tipo Unicode (teclado emoji por ejemplo). Ahora en Swift 4, ya los contempla como caracteres normales.
Protocolo Codable
Llegamos a la mejora que más os va a sorprender, y que más lineas de código nos va a ahorrar.
Hasta ahora, cuando queríamos que una clase propia pudiera ser codificada para ser almacenada en un fichero, teníamos que implementar el protocolo NSCoding
. Además, si nuestro tipo era un struct
, y no una clase, aún nos encontrábamos con más problemas.
Implementar el protocolo NSCoding
, suponía la creación de un montón de código, cuya única función era la codificación y descodificación de propiedades de nuestra entidad.
1 2 3 4 5 6 7 8 9 10 11 12 |
required convenience init?(coder decoder: NSCoder) { guard let title = decoder.decodeObjectForKey("title") as? String else { return nil } self.init(title: title) } func encodeWithCoder(coder: NSCoder) { coder.encodeObject(self.title, forKey: "title") } |
Este código aumentaba exponencialmente cuando nos enfrentábamos a la codificación de clases con muchas propiedades.
En Swift 4, nada de esto es ya necesario, y llega un nuevo protocolo llamado Codable
.
Con este nuevo protocolo, solucionamos dos problemas de un plumazo: podemos usarlo con struct
sin problemas, y no requiere implementar absolutamente nada de código adicional.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
struct Person : Codable { var firstName : String var lastName : String var age : Int var married: Bool } let miguel = Person(firstName: "Miguel", lastName: "Díaz Rubio", age: 36, married: true) let encoder = JSONEncoder() if let encoded = try? encoder.encode(miguel) { if let json = String(data: encoded, encoding: .utf8) { print(json) } } |
Esto haría que se pinte por consola nuestro objeto JSON:
1 2 3 4 |
{"firstName":"Miguel", "age":36, "lastName":"Díaz Rubio", "married":true} |
Esto mismo aplica, por supuesto, a la descodificación, y no solo para el formato JSON, ya que tenemos las clases JSONEncoder
, JSONDecoder
, PropertyListEncoder
y PropertyListDecoder
.
Control de acceso
Si habéis trabajado con el control de acceso en vuestras clases o estructuras, habréis comprobado que existe una problemática a la hora de utilizar propiedades privadas desde las extensiones.
El problema viene porque Swift 3 no entiendo que la extensión sea parte de la implementación de la clase, y por ello no da acceso a dichos elementos. Vamos a verlo con un ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 |
class Person { private firstName : String } extension Person { func drawName () { print(self.firstName) // Esta linea producía un error en Swift 3 } } |
La única forma de solucionar esta situación, era crear la propiedad firstName como fileprivate
en lugar de private
. Con ello, le damos acceso a todo el fichero a dicha propiedad. Esto aunque logra el objetivo de acceder desde la extensión, tiene el inconveniente de que estamos dando visibilidad a más ámbito del que necesitamos.
Swift 4 modifica este comportamiento y permite que las extensiones hagan uso de elementos privados de la clase o estructura.
Rangos unilaterales
Otra novedad que introduce Swift 4, de nuevo orientada a que escribamos menos código, y, por ende, nuestro código sea más legible, es la incorporación de inferencia en el inicio o fin de los rangos.
Imaginemos que tenemos un array como el siguiente:
1 2 3 4 |
var numberArray = ["Uno", "Dos", "Tres", "Cuatro", "Cinco"] |
Si queremos crear un rango con los dos primeros valores, tendríamos que indicar:
1 2 3 4 |
var firstTwoElements = numberArray[0..<2] |
Si queremos crear un rango con los dos últimos valores, tendríamos que indicar:
1 2 3 4 |
var lastTwoElements = numberArray[3...numberArray.count-1] |
Esto en Swift 4, se simplifica, ya que no es necesario indicar el inicio o fin del rango:
1 2 3 4 5 6 7 8 |
// Inicio var firstTwoElements = numberArray[..<2] // Fin var lastTwoElements = numberArray[3...] |
Despedida
Para todos los que damos gracias a Apple por la llegada de Swift al ecosistema de iOS y macOS, es un placer ver como el lenguaje esta evolucionado con grandes zancadas año tras año.
Os recomiendo adaptar vuestras apps a Swift 4, e indicarnos en los comentarios cualquier duda o problema que os surja en el proceso.