Swift 5.6 marca un nuevo hito en la evolución del lenguaje, ofreciendo a los desarrolladores herramientas más poderosas y flexibles. En esta publicación, profundizaremos en las características clave de esta versión, como los property wrappers, que permiten agregar lógica personalizada a las propiedades, y los tipos de retorno opacos, que mejoran la modularidad del código.
1. Any como tipo existencial:SE-0335
La palabra clave any sirve para marcar tipos existenciales. Un tipo existencial es un tipo cualquiera que existe en Swift y se conforma con un protocolo.
Los tipos existenciales tiene una sería de ventajas:
- Flexibilidad: Permiten trabajar con valores de diferentes tipos de una manera más genérica.
- Polimorfismo: Facilitan la creación de código polimórfico, es decir, código que puede trabajar con diferentes tipos de datos.
- Colecciones heterogéneas: Puedes crear colecciones que contengan elementos de diferentes tipos, siempre y cuando todos esos tipos conformen al mismo protocolo.
Para más infromación puede consultar este post.
2. Marcadores de positión de tipo (placeholders): SE-0315
Esto permite especificar explícitamente solo algunas partes del tipo de un valor para que el resto pueda completarse por inferencia de tipo.
En la práctica esto significa escribir un guión bajo _ para especificar el tipo de un valor. Por ejemplo:
var results: [_: [Int]] = [
"juan": [],
"samantha": [],
"firulai": [],
]
Los marcadores de posición también pueden representar un opcional, en ese caso escriba _?
Considere los marcadores de posición como un comodín que le permite omitir declaraciones de tipos largas, haciendo que nuestro código sea más flexible.
El desarrollador experimentado Paul Hudson ha descubierto un truco para el operador _: Resulta que si le indicamos el retorno de una función como _ Xcode emitirá un error pero al mismo tiempo le indicará cual puede ser la solución. Esto ahorra tiempo al trabajar con tipos complejos.
Para más información sobre este tema puede consultar este artículo.
3. Permitir diccionarios con claves que no sean del tipo String:Int en un keyedContainer: SE-0320
Se introduce un nuevo protocolo CodingKeyRepresentable que permite que los diccionarios con claves que no sean de un tipo simple como String o Int generen una representación standar del diccionario, en un JSON por ejemplo.
Esto resulta útil si queremos convertir un diccionario en JSON y enviarlo a un servidor. Veamos un ejemplo sencillo:
//En el viejo enfoque se crea una enumeración para las claves del diccionario
enum OldSettings: String, Codable {
case name
case twitter
}
let oldDict: [OldSettings: String] = [.name: "Paul", .twitter: "@twostraws"]
let oldData = try JSONEncoder().encode(oldDict)
print(String(decoding: oldData, as: UTF8.self))
/*
La salida será esta:
["twitter","@twostraws","name","Paul"]
En la decodificación de este JSON Swift sabrá componer correctamente de nuevo el diccionario.
Pero esta representacion JSON no es útil si la enviamos a un servidor.
Por ello hacemos uso del nuevo protocolo:CodingKeyRepresentable
*/
enum NewSettings: String, Codable, CodingKeyRepresentable {
case name
case twitter
}
//Ahora la salida es más útil fuera de Swift:
//{"twitter":"@twostraws","name":"Paul"}
4. Condición de indisponibilidad:SE-0290
Se ha introducido la forma contraria de #available llamada #unavailable. Este permitirá ejecutar algún código si falla la verificación de disponibilidad. Ejemplo:
if #unavailable(iOS 15) {
// Código que se ejcutará en iOS 14 y anteriores
}
//Observe como no es necesario el comodín *, como en #available(iOS 15, *). Sencillamente no tiene sentido su uso.
5. Más Cambios en la concurrencia.
Con la versión de Swift 5.5 se introdujo las bases para el enfoque moderno del modelo de concurrencia en Swift. Con esta nueva versión muchas de esas características se refinan para hacerlas mas seguras y consistentes. Esto sienta las bases para cambios más importantes en el futuro.
El principal cambio viene dado por SE-0337 que proporcionar facilidades para la migración incremental del código antiguo al nuevo modelo de concurrencia con el uso del atributo @preconcurrency.
Este atributo permite importar módulos enteros para indicarles a Swift que ese módulo no implementa el enfoque moderlo. Incluso puede marcar clases, estructuras, propiedades y métodos para ser más selectivos.
Otro cambio se da en los actores. Ahora Swift emite una advertencia cuando se intenta instanciar una propiedad @MainActor usando @StateObject. Por ejemplo:
import SwiftUI
@MainActor class Settings: ObservableObject { }
struct OldContentView: View {
@StateObject private var settings = Settings()
var body: some View {
Text("Hello, world!")
}
}
struct NewContentView: View {
@StateObject private var settings: Settings
init() {
_settings = StateObject(wrappedValue: Settings())
}
var body: some View {
Text("Hello, world!")
}
}
Ejemplo tomado de esta fuente.
Esta advertencia se actualizará a un error en Swift 6.
6. Plugins para Swift Package Manager
Swift 5.6 reune una serie de propuestas para agegar las bases para integrar complementes en el Administrador de Paquetes de Swift (SPM) mediente herramientas de compilación externas.
De momento el soporte para SwiftGen, DocC está validado.
Conclusión:
Swift 5.6 implementa y refina muchas de las características y novedades previas ofreciendo al desarrollador las herramienta para una mayor productividad, un código más limpio y mantenible y la posibilidad de crear aplicaciones mas robustas y escalables. Esto es un claro ejemplo del compromiso de Apple por ofrecer un lenguaje de progamación cada vez más potente e intuitivo.
Gracias por leer este artículo. Feliz codificación.