Domina en Swift el encadenamiento de opcionales para acceder con seguridad a métodos, propiedades y subíndices. Verás cómo usar if let y el operador de interrogación para recorrer estructuras anidadas sin crashear por nil, incluso cuando encadenas muchos niveles.
¿Cómo funciona el optional chaining en profundidad?
El optional chaining permite preguntar, paso a paso, si cada eslabón existe antes de seguir. En un caso como edgar → residencia → dirección → calle, cada salto añade un “?”. Si alguno es nil, toda la evaluación se corta con seguridad.
Cada nivel opcional añade incertidumbre y más posibilidades de que falle la cadena.
Con if let, solo entras en el bloque si todas las piezas existen.
Ventaja: lo haces en una línea. Desventaja: si algo falla, toca depurar dónde se rompió.
¿Qué exige if let en cadenas de opcionales?
El patrón clásico recupera la calle solo si todo existe: persona, residencia, dirección y calle.
iflet edgarStreet = edgar.residence?.address?.street {print("La casa de Edgar está en la calle \(edgarStreet)")}else{print("No sé dónde vive Edgar")}
Si “se alinean las estrellas”, obtienes el valor no nulo y lo usas.
Si cualquiera es nil, entras en el else y evitas errores.
¿Cómo configurar la dirección de Edgar con optional chaining?
Primero puedes asignar la dirección usando el acceso opcional; luego, leer campos como el identificador del edificio.
// Asignar la dirección de forma segura.edgar.residence?.address =createAddress(street:"Calle de Plachi", number:13)// Recuperar el identificador del edificio.iflet buildingIdentifier = edgar.residence?.address?.buildingIdentifier {print("Edgar vive en \(buildingIdentifier)")}else{print("No sé dónde vive Edgar")}
La asignación usa “?." porque la residencia es opcional.
El identificador puede componerse de número y nombre de calle, si ambos existen.
¿Cómo comprobar prefijos con métodos opcionales?
Un método encadenado sobre un valor opcional también requiere “?” para evaluarse de forma segura. Si el identificador del edificio existe, puedes verificar su prefijo.
if edgar.residence?.address?.buildingIdentifier?.hasPrefix("13")==true{print("Edgar vive en el número trece")}else{print("Edgar no vive en el número trece")}
El método hasPrefix devuelve un Bool, pero al llamarlo sobre un opcional, el resultado es opcional; por eso comparamos con == true.
Si no usas la variable intermedia, puedes emplear “_” para evitar la advertencia del compilador.
¿Qué habilidades y conceptos refuerzas al practicar?
Practicar estos patrones te prepara para modelos complejos recibidos de librerías o servidores, donde casi todo llega como opcional y puedes encadenar siete u ocho niveles.
Uso correcto de optional chaining con propiedades, métodos y subíndices.
Patrones con if let para bindings seguros.
Manejo de nil y cortes tempranos de evaluación.
Lectura y composición de datos como buildingIdentifier.
Control de flujo con else y mensajes de print claros.
Depuración: localizar en qué eslabón se rompe la cadena cuando no pasa la condición.
Modelado de relaciones: persona, residencia, dirección y campos opcionales.
¿Quieres que revisemos un caso tuyo con múltiples opcionales y lo optimicemos juntos? Cuéntalo en los comentarios y traemos el ejemplo a código paso a paso.
Como aporte existe también el "coalescing operator", el cual puede ser útil para combinarlo con el "chaining multiple", El operador es ?? y se puede utilizar de la siguiente manera:
En caso de que la evaluación de la izquierda sea NIL se asigna el valor de la derecha. ✌
Siento que este tema se usa mucho cuando se leen APIs de servidores, asi como lo mencionas de ejemplo
Excelente clase, realmente este concepto es muy usado en todos los lenguajes solo que aca se puede ver el por que el uso de la variable optional que no se usa en otros lenguajes y que puede ser muy problematico cuando cualquier elemento es nulo generando que las aplicaciones fallen de forma muy facil.
Bien por Edgar!!!
tengo una pregunta esto no es hacer mas grande el código de lo que necesitamos ?
classCliente{varnombre:Stringvarpresupuesto:Doublevarresicencia:Residence?init(nombre:String,presupuesto:Double){ self.nombre= nombre
self.presupuesto= presupuesto
} func restarPresupuesto(valor:Double){ self.presupuesto-= valor
}}classRepartidor{varnombre:Stringvarvehiculo:Vehiculoinit(nombre:String,vehiculo:Vehiculo){ self.nombre= nombre
self.vehiculo= vehiculo
}}classVehiculo{varmarca:Stringvarmodelo:Stringvaranio:String?varplaca:String?init(marca:String,modelo:String){ self.marca= marca
self.modelo= modelo
}}classArticulo{varnombre:Stringvarprecio:Doublevarstock:Int?init(nombre:String,precio:Double){ self.nombre= nombre
self.precio= precio
}}classPedido{varcliente:Clientevarrepartidor:Repartidor?vararticulos:[Articulo]?=[Articulo]()vardireccionEnvio:String?{ get {vardireccionPersona:Stringiflet direccion = cliente.resicencia?.address?.street { direccionPersona = direccion
return direccionPersona
}else{return nil
}}}vartotalPedido:Double?init(cliente:Cliente){ self.cliente= cliente
} func agregarArticulosAlPedido(articulo:Articulo){ self.articulos?.append(articulo)} func obtenerTotal()->Double{iflet articulos = self.articulos{var totales =0.00 articulos.forEach{(art:Articulo)in totales += art.precio}return totales
}else{return0.00}} func RealizarPedido(){ guard let totalPedido = totalPedido,let direccionEnvio = self.direccionEnvioelse{print("No se ha podido realizar el pedido, agregue productos")return}print("Se va a enviar \(self.articulos!.count) a \(self.cliente.nombre) en la direccion \(direccionEnvio) con un total de \(totalPedido)") cliente.restarPresupuesto(valor: totalPedido)} func AsignarRepartidor(repartidor:Repartidor){ self.repartidor= repartidor
}}let cliente1 =Cliente(nombre:"Jonathan",presupuesto:500.20)cliente1.resicenciavar residenciaCliente1 =Residence()residenciaCliente1.rooms.append(Room(name:"Cuarto master"))residenciaCliente1.address=Address()residenciaCliente1.address?.buildingName ="Torres de la costa"residenciaCliente1.address?.buildingNumber ="202"residenciaCliente1.address?.street ="bosques de la costa"cliente1.resicencia= residenciaCliente1
var zapatoNautico =Articulo(nombre:"ZapatoNautico",precio:20.00)var camisaPolo =Articulo(nombre:"Camisa polo blanca",precio:20.00)var telefono =Articulo(nombre:"iPhone 11",precio:700.00)var pedido1 =Pedido(cliente: cliente1)pedido1.agregarArticulosAlPedido(articulo: zapatoNautico)pedido1.agregarArticulosAlPedido(articulo: camisaPolo)pedido1.agregarArticulosAlPedido(articulo: telefono)pedido1.articulospedido1.totalPedido= pedido1.obtenerTotal()pedido1.totalPedidopedido1.direccionEnviopedido1.RealizarPedido()```
eso se me parece a un patron factory :D
Entiendo que es un tema importante, pero me parece que podría estar en cualquiera de los otros cursos y no en este de POO. Aun asi bien explicado
Concuerdo contigo
Creo que uno de los cursos mas rudos es el de Funciones con Swift ese lo voy a tener que volver a ver ja ja ja!, pero este lo último se me hizo bastante sencillo. Supongo que vengo de Kotlin y null safety es muy parecido a este concepto.