Aprende a usar REDUX en SwiftUI
Aprende a usar REDUX en SwiftUI

🧩 Arquitectura REDUX en SWIFTUI en Español

Aprender la arquitectura REDUX en SwiftUI es muy fácil, lo único que tenemos que saber son sus componentes: vista, actions, store, reduce, state hasta cómo se conectan y comunican entre ellos. Redux es una aquitectura unidireccional que escucha cambios en un state. Tutorial SWIFTUI

SwiftBeta

Tabla de contenido


👇 SÍGUEME PARA APRENDER SWIFTUI, SWIFT, XCODE, etc 👇
Aprende REDUX en SWIFTUI
Aprende REDUX en SWIFTUI

Hoy en SwiftBeta vamos a ver la arquitectura Redux. Vamos a explicar todos sus componentes: State, Action, Store, Reducer, etc. Y vamos a crear una app muy sencilla para entender mejor esta arquitectura, veremos por qué es una buena opción para crear nuestras apps con SwiftUI.

pero antes de todo...

¿Qué es Redux?

Componentes REDUX en SwiftUI
  • Es una arquitectura unidireccional (esto significa que la información viaja en un único sentido). Es decir, "algo" pasa en la vista que hace que se ejecute cierta lógica de nuestra app, esta acción hace que tengamos un cambio que se ve reflejado otra vez en la vista.
  • Tenemos un único modelo de toda la app, es decir, tenemos una struct donde vamos mutando (actualizamos) la información que se mostrará en diferentes partes de nuestra app. Esto es mi útil, ya que solo habrá una única fuente de la verdad en toda la app. En el post de hoy crearemos este componente con una struct llamada AppState .
    Por ejemplo, podemos tener en el AppState información de si un user está logeado, un array, tener el token OAuth, etc.
  • Para poder mutar el AppState necesitamos tener acciones en nuestra app, estas acciones son las que empiezan el flujo de redux, en el post de hoy las agruparemos en un enum llamado AppAction (habrá tantos cases como acciones tengamos).
    Un ejemplo, estamos en una vista y el user hace tap en un Button, este Button lanzaría una acción (de nuestro enum AppAction). Pero, ¿dónde se enviaría esta acción? Lo vemos en el siguiente punto.
  • Las AppActions son enviadas a un componente llamado Store (dentro de este componente también tenemos el AppState).
    La acción recibida se envía junto el AppState a una función llamada Reducer. Y dentro de esta función se realiza una tarea que hace mutar el AppState. El único componente que puede modificar el AppState es el Reducer.
  • El Reducer es una función que acepta AppActions y el AppState, depende la acción se ejecuta una lógica o otra. Y esta lógica normalmente acaba mutando el AppState.
  • Cualquier cambio en el AppState hará que se renderice de nuevo la vista con la nueva información.

Redux en Código

Lo primero de todo que vamos hacer es crear un proyecto en Xcode. El objetivo será mostrar un array de Strings en una List en SwiftUI, y al pulsar el botón añadiremos más elemento al array. Al haber un cambio en el array, automáticamente se renderizará (se volverá a dibujas la vista para mostrar los elementos que ya había, más los nuevos elementos.).

AppState

El primero componente que vamos a crear es el AppState. Como hemos dicho, el estado será un array de strings. Creamos el siguiente código:

struct AppState {
    var names: [String] = []
}
Redux: AppState en SwiftUI

AppAction

El segundo componente será un enum donde cada case será una acción.

enum AppAction {
    case loadNames
}
Redux: AppAction en SwiftUI

Reducers

Ahora que ya tenemos el AppState y las AppActions (de momento solo tenemos loadNames) necesitamos el componente Reducer para saber qué AppActions realizar, según está acción se hace una lógica y finalmente actualizamos el AppState. En nuestro caso queremos que cuando llegue la acción loadNames, actualizar el array de names del AppState, pues vamos a ello:

func appReducer(action: AppAction, state: inout AppState) {
    switch action {
    case .loadNames:
        state.names.append(contentsOf: ["Aprende Swift", "Aprende Xcode"])
    }
}
Redux: Reducers en SwiftUI

AppStore

El último componente es el AppStore, este componente es el encargado de pasarle al reducer una AppAction para que mute el AppState. Vamos a verlo:

class AppStore: ObservableObject {
    @Published private(set) var appState: AppState
    private let reducer: (AppAction, inout AppState) -> Void
    
    init(initialState: AppState, reducer: @escaping (AppAction, inout AppState) -> Void) {
        self.appState = initialState
        self.reducer = reducer
    }
    
    func reduce(action: AppAction) {
        reducer(action, &appState)
    }
}
Redux: AppStore en SwiftUI

Hemos creado el AppState con el siguiente nivel de protección:

private(set) var appState: AppState

Esto es para que pueda ser accesible desde fuera de la clase pero que no se pueda setear ningún valor (para que nadie asigne valores nuevos desde fuera de esta clase, como decíamos antes, el único que puede mutar el AppState es el Reducer).

Ahora solo nos queda crear la vista en SwiftUI y probar que nuestros componentes de Redux funcionan. Vamos a crear la vista con el listado de strings:

struct ContentView: View {
    
    @StateObject var store: AppStore = AppStore(initialState: AppState(), reducer: appReducer)
    
    var body: some View {
        NavigationView {
            List {
                ForEach(store.appState.names, id: \.self) { name in
                    Text(name)
                }
            }
            .toolbar {
                Button("Tap me!") {
                    store.reduce(action: .loadNames)
                }
            }
        }
    }
}
Redux: View en SwiftUI

Los pasos que hemos seguido son:

  1. Crear la propiedad @StateObject de tipo AppStore. Como parámetros le hemos pasado una instancia de AppState y le hemos pasado el reducer que queremos usar dentro del Store.
  2. Al crear la List en SwiftUI, le pasamos como data la propiedad names del AppState. Y estos strings los mostramos dentro de un Text. Cualquier cambio en esta propiedad hará que se renderice de nuevo la List, mostrando los nuevos elementos del array de names.
  3. Hemos creado un Button, y este Button lanza una acción que se envía al AppStore.

Si probamos nuestra app, vemos como todo está conectado. Se muestra la información en el List y al pulsar el botón se añaden los elementos que tenemos en nuestra función appReducer.


Conclusión

Hoy lo que hemos visto en SwiftBeta ha sido una introducción a la arquitectura REDUX en SWIFTUI. Hemos ido paso por paso para saber qué componentes usar y cómo se conectan entre ellos.