¿Qué es SwiftUI?

'SwiftUI' es el nuevo framework de Apple para la creación de vistas que viene a sustituir al antiguo 'UIKit'. Este framework está diseñado para aprovechar todo el potencial de 'Swift', ya que ha sido creado desde cero teniendo en cuenta todo lo que este lenguaje nos proporciona. Se trata de un framework exclusivo de 'Swift', por lo que no puede ser usado en 'Objective-c'. No obstante, hay mecanismos para poder presentar las vistas desde 'Objective-c' en caso de ser necesario.

Este framework es un punto de inflexión dentro de la programación para entornos Apple, donde cada vez está todo más unificado. Pone de manifiesto la nueva dirección que tomarán los desarrollos durante los próximos años, dejando clara la evolución a las últimas tendencias del mundo del desarrollo gracias a la potencia del lenguaje y a la flexibilidad de las nuevas APIs.

 

Programación declarativa

El framework usa una sintaxis declarativa (en lugar de imperativa como 'UIKit'). Esto quiere decir que nuestra aplicación responderá a estados y dependiendo del estado en cuestión nuestra aplicación sabrá qué tarea debe realizar o qué vista se debería mostrar.

Para ponernos en situación, imaginemos que tenemos un formulario con los campos 'name' y 'surname' y un botón 'Send' que no podemos pulsar hasta tener los dos datos anteriores rellenados. Con 'SwiftUI' el botón 'Send' dependería del estado del contenido de los dos campos de texto anteriores para activar o desactivar el botón, sin necesidad de escribir más código.

A continuación veréis el código que implementa este control que acabamos de definir:

struct ContentView: View {
    @State var name: String = ""
    @State var surname: String = ""
    
    var body: some View {
        VStack(spacing: 10) {
            TextField("Name", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            TextField("Surname", text: $surname)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            Button("Send") {
                print("Done!")
            }.disabled(name.isEmpty || surname.isEmpty)
        }.padding()
    }
}

Con este código cada vez que se realice un cambio en alguna de las variables de estado ('@State') el programa recalcula todo aquello que tenga dependencias de estas variables, lo que permite que el botón 'Send' aparezca activado o desactivado. Las variables de estado 'name' y 'surname' están enlazadas a su vez a campos de texto, lo que provoca que cuando el usuario escriba en ellos se inicie el flujo de cambio de estado.

 

Reutilización y orientación a componentes

La propia sintaxis del framework nos guía hacia una manera diferente de plantear los desarrollos. Anteriormente teníamos pantallas donde encapsulábamos diferentes vistas en celdas, ya que el 80% de las pantallas en una app de iOS son tablas. Unas celdas que íbamos reutilizando conforme se fueran necesitando.

En el momento en el que la pantalla no fuera una tabla ya no se podía reutilizar estas celdas, y lo mismo ocurría si teníamos celdas para un 'UITableView'  o 'UICollectionView'. 

También se diseñaban componentes en cada pantalla, ya que 'UIKit' no facilitaba las cosas para la creación de estos componentes por separado (Pensad en el típico 'UILabel' arriba y 'UITextField' debajo para un formulario de login, por ejemplo).

Y qué decir de la creación de estilos para darle formato a cada elemento visual. Para esto nunca se ha facilitado ningún estándar y cada equipo de desarrollo ha seguido su propio camino. En nuestro caso, por ejemplo, creábamos extensiones por cada tipo de elemento visual y se elaboraban las funciones que aplicaban los estílos. 'SwiftUI' soluciona todos estos problemas rápidamente a través de un protocolo: 'View'.

El protocolo 'View' da la capacidad a quien lo implementa de poder mostrarse en pantalla. ¿Qué quiere decir esto?

Pues que cualquier cosa que se muestre en pantalla implementará este protocolo independientemente del nivel que ocupe (pantalla completa, embebido en una celda o cualquier otro lugar), eliminando lo que conocíamos anteriormente como 'UIViewController' como una pantalla o 'UICollectionViewCell' y 'UITableViewCell' como celdas.

Y entonces, ¿qué permite esto?

  • Presentar un 'Text', por ejemplo, cuando hacemos un 'push' (no tenemos que encapsularlo en un 'UIViewController' ni similar). Por tanto, como implementa el protocolo 'View', este puede ser presentado en pantalla sin más.
  • Las celdas de los 'List' (lo que conocemos como 'UITableView' en 'UIKit') podrá ser cualquier cosa que implemente el protocolo 'View'. ¡Incluso una pantalla completa si quisiéramos!
  • La creación de componentes es tan sencilla como declarar un 'struct' que implemente el protocolo 'View' y montar las vistas que queramos. Por ello, para reutilizarla solo tendremos que "inicializar" el componente. Por ejemplo, en el caso de 'UILabel' arriba y 'UITextField' debajo para un login o formulario sería así:
struct LabelWithTextField: View {
    let text: String
    let placeholder: String
    @Binding var value: String
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(text)
                .font(.caption)
            TextField(placeholder, text: $value)
            Rectangle()
                .fill(Color.blue)
                .frame(height: 1)
        }
    }
}

 

Con este código hemos creado el componente 'LabelWithTextField' y para usarlo simplemente tendremos que "inicializarlo" en la vista que queramos:

struct ContentView: View {
    @State var value: String = ""
    
    var body: some View {
        VStack {
            LabelWithTextField(text: "What's your name?", placeholder: "Write here", value: $value)
        }
    }
}

 

iOS 13 versión mínima

Pero no todo es tan perfecto como nos gustaría. El principal impedimento de 'SwiftUI' es que solo se puede usar si nuestra app da soporte a iOS 13 en adelante, lo que limita mucho su uso para proyectos en los que se quiere llegar al mayor número de usuarios posibles. Si nuestro proyecto va dirigido a este público, o va a ser un proyecto de larga duración, es muy recomendable realizar el desarrollo con 'SwiftUI', ya que de lo contrario supondrá nuevos sobrecostes y gasto de tiempo en un futuro muy cercano.

 

 ... y sigue evolucionando

Al tener solo un año de vida es evidente que aún tiene mucho margen de mejora, y es algo que Apple irá solventando año tras año incluyendo nuevos componentes, que serán esenciales para el desarrollo (como los 'LazyVStack' y los 'LazyHStack', entre otros), y que no se podrán usar hasta que la versión mínima suba a iOS 14.

Esto seguirá siendo así durante algunos años hasta que Apple finalice la migración de todo 'UIKit' a 'SwiftUI'. Por tanto, los desarrolladores nos tendremos que acostumbrar a tener un componente que realiza justo lo que queremos, pero que para usarlo deberemos aumentar la versión mínima.

 

Nuevos frameworks solo disponibles para programar con SwiftUI'

De la misma forma que pasó con el propio 'Swift' años después de su lanzamiento, ya existen frameworks que nos obligan a usar 'SwiftUI' tras un año de su salida.

Estamos hablando del framework 'WidgetKit' para el desarrollo de los nuevos Widgets que nos proporciona iOS 14. Sin duda, este es un ejemplo de la evolución del framework que podemos esperar.

Durante los próximos años será normal ver desarrollos en los que coexistan tanto 'UIKit' como 'SwiftUI', ya sea por la migración al nuevo framework o por la utilización de componentes específicos a partir de versiones compatibles de iOS con 'SwiftUI'.

 

El futuro es SwiftUI

No cabe duda que Apple está apostando fuerte por 'SwiftUI', pero como siempre ocurre con los cambios en los desarrollos (ya pasó con el propio 'Swift') las primeras versiones son lanzadas para que la comunidad pueda experimentar con ellas y proporcionen feedback con el objetivo de acabar de completarlas.

Aunque este no es el mismo caso que lo ocurrido con el lanzamiento de 'Swift' (ya que ese cambio suponía un salto mucho mayor), si quieres comenzar a usar 'SwiftUI' en la versión de iOS 13 vas a echar de menos algunos componentes básicos. No obstante, podrás solventar esta ausencia creando tus propios componentes basados en 'SwiftUI' o implementándolos directamente desde el componente de 'UIKit' a través del protocolo UIViewRepresentable. De cualquier modo, si tu desarrollo va a tener iOS 13 como versión mínima, te recomendamos que lo realices con este framework sí o sí.

 

Esperamos que os haya resultado interesante 

 

Posts relacionados

View: el protocolo base de SwiftUI

View: el protocolo base de SwiftUI

Post sobre Core ML e integración de Machine Learning en aplicaciones iOS

Core ML: Integrando Machine Learning en...

Comentarios
Pepe Escabias
18 Sep 2020

Es interesante que las vistas, al ser structs puedan implementar el protocolo “Codable” y así recibir ya vistas hechas directamente desde backend. Es decir, la jerarquía de vistas se podrá descodificar directamente del JSON. Algo parecido de creación propia usaba Spotify.

Muy buen artículo Rafa. Un abrazo!