Building a to-do list app with SwiftUI and Firebase – Pt 1

[REPRODUCIENDO MÚSICA] PETER FRIESE: Hola a todos. Y bienvenido a
"Firebase Semi-Live", el programa donde lo codificamos en vivo
aquí y lo ves más tarde. En los próximos
episodios, analizaremos algo que me
emociona especialmente: cómo integrar Firebase
con Swift UI. Apple Health lanzó
SwiftUI en WWDC 2019. Y ha cambiado por completo la forma en que
construimos interfaces de usuario. Sin embargo, parece
haber cierta incertidumbre sobre cómo integrar Firebase
en la aplicación SwiftUI. Así que hoy vamos
a arreglar esto. Le mostraré cómo
crear una aplicación de lista de tareas simple con
SwiftUI, combinar Firebase, Firestore,
autenticación de Firebase y firmar con Apple. Guau. Eso es un montón de
cosas para pasar. Será mejor que empecemos. Pero antes de comenzar a
escribir algo de código, echemos un vistazo a
cómo se verá la aplicación al final. Aquellos de ustedes que usan
la aplicación Recordatorios de iOS notarán las similitudes. En la pantalla principal,
verá que tenemos un encabezado y un
botón en la parte inferior.

Y cuando presiono el botón,
agregará una nueva línea aquí para agregar una nueva tarea. Así que hagamos esto. Comencemos con la
implementación de la interfaz de usuario. Agrega la tarea. Y agreguemos otro. Y luego necesitamos
conectarnos a Firebase. Y luego agreguemos otro. Hay un gran signo de interrogación. ¿ Lo que sucede? Y al final, finalmente, el beneficio. Está bien. Entonces, con suerte, al
final de este episodio, habremos terminado de
implementar la interfaz de usuario. Y una cosa que me
gusta señalar, así que si echamos un vistazo a lo que está
pasando en mi pantalla aquí, permítanme mostrar esto. Entonces, lo que estamos viendo
es la consola Firebase. Y echamos un vistazo a
la instancia de Firestore que se ejecuta como back-
end de mi aplicación aquí. Y si analizamos
eso, notará que todos los elementos
que agregué a mi lista de tareas ya aparecieron aquí.

Entonces, como ejemplo,
cambiemos el estado de finalización de este elemento aquí. Y si presta atención al
estado de finalización en la consola,
notará que una vez que lo cambie en mi aplicación, se
actualizará en Firestore. Impresionante. Así que empecemos a
escribir algo de código. Permítanme mostrar
Xcode y luego comenzaremos a escribir la aplicación. Minimicemos esta
ventana, esta también. Y luego comenzaremos
con una nueva aplicación Xcode. Usaremos una
aplicación de vista única. Llamémoslo "
hacerlo tan semi-en vivo en vivo". Y queremos usar
SwiftUI para la interfaz de usuario. Y vamos a colocarlo
en esta carpeta aquí. Está bien. Entonces, lo primero
que verá es que tenemos nuestra
vista de SwiftUI aquí para la vista de contenido. Y este es el inicio normal
para todas nuestras aplicaciones. Pero lo que queremos
hacer primero es definir nuestro modelo de datos. Así que vamos a crear una nueva carpeta
para guardar nuestro modelo de datos. Primero que nada,
una nueva carpeta aquí. Llamémoslo modelo. Y luego déjame agregar un nuevo archivo. Y este va
a ser un archivo Swift. Llamémoslo "tarea" porque
queremos hablar de tareas aquí.

Entonces, en nuestra aplicación,
queremos realizar un seguimiento de las tareas. Y esas tareas tienen una serie de
atributos que son importantes. Por ejemplo,
tendrán un título. Y también tendrán
un estado de finalización. Terminado. Está bien. Entonces, ¿por qué no convertimos esto
en un código Swift adecuado? Entonces, antes que nada, esto
debe ser una estructura. Y luego cerremos esto aquí. Y luego
los convertiremos en propiedades. [INAUDIBLE] título. Y esto va
a ser una cadena. Y el estado completado
será un booleano.

¿ Bien? Entonces, para facilitar nuestro trabajo
, definamos también algunos datos de prueba que
podemos usar mientras construimos la interfaz de usuario. Así que permítanme ocultar esto en
la declaración de depuración aquí. Y si. Y luego, creemos una
colección de datos de prueba. Prueba las tareas de datos, y
será una colección de tareas. Implemente la interfaz de usuario y
digamos que esto es cierto. Conéctate a Firebase. Y esto es falso, porque
esto todavía no lo hemos terminado. Y luego un par
de signos de interrogación. Y tengamos el
elemento de ganancias también. Está bien. Fresco. Así que tenemos algunos
datos de prueba aquí. Tenemos nuestra estructura
para guardar los datos. Genial. Así que sé que este es un
modelo de datos bastante simple. Y es posible que se pregunte cómo
admitir casos de uso avanzados. Por ejemplo, realizar un
seguimiento de la fecha de vencimiento y administrar múltiples listas de tareas. Y tal vez incluso compartir
datos con otros usuarios y cosas por el estilo.

Así que todas estas son grandes ideas. Y definitivamente los analizaremos
en episodios posteriores de la serie. Pero por ahora, concentrémonos
en las cosas simples y solo tratemos las tareas y
si se completaron o no. Bien. ¿ Qué es lo siguiente? Oh, lo sé. Necesitamos la interfaz de usuario. Así que sigamos adelante y
refactoricemos nuestra estructura un poco más. Permítanme mover esos elementos
aquí a un nuevo grupo. Y este va
a ser el grupo de aplicaciones. Y luego hagamos otro
grupo para todas nuestras opiniones. Está bien. Así que déjame subir esto aquí. DE ACUERDO.

Así que tenemos nuestro grupo de aplicaciones,
nuestro grupo de modelos y nuestro grupo de vistas. Y volvamos
a nuestra vista de contenido. Y en lugar de usar
la vista de contenido del nombre, cambiémosle el nombre y usemos
algo más significativo. Así que refactorice el cambio de nombre y
llamémoslo vista de listas de tareas. Presiona enter para cambiar el nombre. Y ahí vamos. Permítanme aumentar un poco la ventana
para que podamos ver más. Y luego echemos un
vistazo a cómo se ve la interfaz de usuario en la vista previa. Entonces, al presionar opción,
comando e ingresar, abriremos la ventana de vista previa. Y actualmente está en pausa,
pero al presionar opción, comando, P, puede reanudarse. Y luego, en un
par de segundos, deberíamos ver cómo
se ve actualmente la interfaz de usuario. Y luego podemos comenzar a
construir la interfaz de usuario. Está bien. Así que actualmente, solo
dice, hola mundo. Y cambiemos eso y
cambiémoslo a una de nuestras tareas. Así que implementar la interfaz de usuario, esa
era una de nuestras tareas.

Excelente. Entonces, además de mostrar
el título de la tarea, también queremos mostrar si
la tarea se completó o no. Y podemos usar una
imagen para hacer eso. Permítanme arrastrar una
vista de imagen del piloto aquí. Entonces, busca una imagen. Y luego arrástrelo y
colóquelo a la izquierda de nuestra etiqueta, así como así. Y verás que el
código fuente ha sido actualizado. Actualmente,
todavía no tenemos un nombre de imagen. Pero podemos usar una imagen del sistema. Y usemos el círculo. Y verás que
tenemos un buen círculo aquí. Y luego, una vez que
se complete la tarea, usaremos una
imagen diferente para indicar que ahora se completó. Está bien. Así que vamos a convertir esta
celda muy simple en una lista. Así que vamos, haga clic
en la pila H y luego seleccione incrustar en las listas. Y luego obtenemos cinco elementos. Y notará que
sigue siendo solo este elemento, pero lo cambiaremos
en un par de segundos. Fresco. Así que tenemos nuestras listas. Tenemos una celda. Ahora también necesitamos un
botón que podamos usar para agregar elementos más adelante.

Entonces, de nuevo, usemos la paleta. Y luego busque el botón,
y luego arrástrelo hacia abajo aquí. Y puedes verlo. En la parte inferior de
la pantalla, dice, agregue el botón a una
nueva pila vertical. Eso es exactamente lo que queremos. Así que déjalo ir. Y verá,
tenemos una pila V, la lista está en la
pila de vistas y el botón también está ahí. Entonces queremos que nuestro botón diga
algo como agregar nueva tarea. Y, obviamente, esto debe
estar en la cadena. Y luego, actualmente
está centrado, eso es algo que debemos arreglar. Pero también queremos tener un lindo
ícono al lado izquierdo. Así que permítanme envolver esto
manualmente en una pila H. Y luego inserte una imagen aquí. Imagen, nombre del sistema, igual,
más, círculo de puntos, relleno de puntos. Esto nos dará un
ícono más en el círculo de relleno. Genial. Y finalmente, cambiemos
la alineación del botón a guía.

Entonces, podemos hacer eso haciendo
clic en la pila V, abriendo el inspector de la interfaz de usuario,
que, en esta versión de datos de Xcode, está roto. Pero no te preocupes. Usemos nuestro inspector
en el lado derecho y elijamos la alineación izquierda. Entonces todo queda alineado. Así que agreguemos un
poco de relleno y lo haremos en
el botón mismo. DE ACUERDO. Entonces eso se ve mucho mejor. Fresco. Entonces, otra cosa
que debemos hacer es… actualmente los íconos
son muy, muy pequeños. Y debemos
asegurarnos de que sean un poco más grandes para que
sean buenos objetivos táctiles. Podemos hacerlo
entrando y cambiando la imagen. En primer lugar,
haciéndolo redimensionable.

Y esto obviamente es
un poco demasiado grande. Así que entremos y cambiemos
el marco a, probemos 20 por 20. OK. Vamos a ver. Esto luce bien. Y hagamos lo mismo con nuestra
imagen aquí arriba en las listas. Está bien. Entonces, todas las imágenes tienen
aproximadamente el mismo tamaño, lo cual es bueno porque
están muy bien alineadas. Y finalmente, también
asegurémonos de tener un buen título en la pantalla. Entonces, podemos hacer esto
envolviendo toda la pila V actual en una vista de navegación. Vista de navegación y, a
continuación, aplique sangría a esto. Entonces hay un
espacio vacío ahí arriba, que tomará nuestro título. Y luego necesitaremos
establecer el título en el primero de nuestro hijo, que
es nuestra pila V. Entonces, una navegación
por título es tareas.

Excelente. Está bien. Así que esta es nuestra interfaz de usuario muy simple. Y ahora sigamos adelante y
conéctelo a algunos datos de prueba. Entonces, si recuerda, tenemos nuestra
pequeña y agradable colección de tareas de datos de prueba aquí
en el archivo de tareas. Entonces, lo que queremos hacer ahora es
conectarlo a nuestra vista de lista aquí. Para hacer eso, vamos
a introducir una nueva propiedad aquí. Y antes que nada,
déjame corregir la sangría. DE ACUERDO. Perfecto. Así que introduzcamos una
nueva propiedad aquí, dejar que las tareas sean iguales a las tareas de datos de prueba. Eso es todo, y ahora
podemos seguir adelante. Y en lugar de iterar
sobre solo cinco números aquí, itere sobre la
recopilación real de datos. Así que hagamos esto. Así que estamos iterando sobre las tareas. Y ahora se queja de que la
tarea no es identificable.

Así que vamos a aumentar esto. Entonces dice, el inicializador
requiere que la tarea se ajuste a identificable. Está bien. Esto se debe a que
ListView necesita saber qué elemento es cuál,
de modo que cuando inserte un nuevo elemento,
pueda distinguirlos y los elementos no
comiencen a saltar. Así que vamos a hacer que la
tarea sea identificable. Así que hazlo identificable. ¿ Y cómo podemos hacer eso? Entonces, debido a que
más adelante necesitamos un identificador para conectar nuestra
tarea con Firestore, introduzcamos una ID y
asegurémonos de que, por ahora, contenga un identificador único. Y podemos hacerlo
usando la cláusula UU ID. Y obtenga una ID de UU y
conviértala en una cadena como esta. Está bien. Y debido a que hacemos esto
para todas nuestras tareas, nuestra pequeña colección
aquí abajo asignará automáticamente una identificación única a cada uno
de esos elementos de datos de prueba que tenemos. Así que volvamos a nuestra vista
y ahora los errores de compilación deberían desaparecer.

El compilador está feliz. Y ahora, sigamos adelante
y conectemos todos esos elementos
a los datos de prueba. Entonces, antes que nada, en lugar de
mostrar una cadena estática, cambiemos el nombre de esto a tarea. Y luego podemos usarlo
aquí abajo, título de punto de tarea. Y cuando guardo
esto, la vista debería actualizarse en el lado derecho. Y puede ver que
está extrayendo datos de nuestra recopilación de datos de prueba. Qué lindo. Entonces, antes también conectamos
el estado completo y a un
tipo diferente de imagen. Entonces, tal vez un círculo completo
en lugar de un círculo vacío para el estado completo.

Refactoricemos
un poco la celda. Entonces, lo que tenemos que hacer es
extraer esos dos elementos aquí, la imagen y
el texto, en una vista separada. Para hacer esto más fácil,
permítanme continuar y convertir esto en
una pila H nuevamente. Porque entonces podemos
simplemente extraerlo. Lo siento. DE ACUERDO. Por lo tanto, corrija la
sangría y luego haga clic con el comando en la pila H. Y extraiga la vista secundaria. Y
lo llamaremos celda de tarea. Excelente. Así que tenemos un par
de errores de compilación aquí que debemos corregir. Entonces, la razón por la que el
compilador se queja es que aquí abajo,
en nuestra nueva estructura, no está del todo
seguro qué significa tarea. Porque la tarea es
desconocida aquí abajo.

Entonces podemos arreglar eso
insertando una nueva propiedad aquí, llámela tarea. Eso debería arreglar los
errores de compilación aquí abajo. Pero obviamente, tenemos un
nuevo error de compilación aquí. Así que tenemos que decirle que inyecte
esta variable en la celda de ahí abajo. Y vamos a compilar de nuevo. Está bien. Compilación exitosa. Genial. Ahora, podemos ir
a nuestra celda de tareas y asegurarnos de que
mostramos el ícono correcto para el estado completado. Entonces queremos mostrar
un círculo lleno cuando se complete la tarea. Y un círculo sin llenar
cuando no está completo. Entonces, actualmente, parece que
no se completaron todas las tareas, lo que claramente está mal. Así que usemos una
declaración if ternaria aquí. Así que el punto de la tarea se completó. Y, si está completo,
queremos usar relleno de punto de círculo de punto de marca de verificación.

Y si no está completo,
usaremos círculo. DE ACUERDO. Veamos cómo se ve eso. Y reanudar o una vista previa. Está bien. Entonces funciona. Mostramos la tarea de implementación de la interfaz de usuario
como, esto se completó. Porque en nuestros datos de prueba que
establecimos, se completó. Y todos los demás elementos
no están completos. Así que esto se ve muy, muy bonito. Y eso es todo para nuestra interfaz de usuario básica. Antes de continuar,
echemos un vistazo rápido a nuestra arquitectura. Así que permítanme abrir mi
aplicación de vista previa. Y echemos un vistazo a
nuestro diagrama de arquitectura. Así que pueden ver eso
aquí arriba, tenemos nuestras opiniones.

Y cada vista individual
usa un modelo de vista. Y, a su vez, el
modelo de vista configura la vista. Entonces, dependiendo del
estado del modelo de vista, la vista se verá diferente. Entonces, por ejemplo, si recordamos
o si miramos hacia atrás en nuestra interfaz de usuario, puede ver que
el ícono de marca de verificación solo está allí porque el
modelo de vista para este elemento de tarea específico dijo que el
estado completado es verdadero. Entonces, en este sentido, el
modelo de vista configura la vista. Entonces, ¿de dónde
obtienen los datos los modelos de vista? Entonces, en última instancia,
querremos conectarnos a Firebase y Firestore. Pero necesitamos una
pequeña cláusula de ayuda para que esto sea más
manejable y nos ayude a construir una mejor arquitectura. Así que vamos a
usar un repositorio. Y el repositorio
realmente está ahí para que sea más fácil
conectarse a Firebase. Entonces, lo que hará es
abrir una conexión de Firebase, una conexión de Firestore,
extraerá datos y escuchará las actualizaciones.

Y también tomará
solicitudes del modelo de vista para agregar nuevos elementos a
Firebase cuando el usuario agregue nuevos elementos a su vista. Y puedes ver esto en
el diagrama de arquitectura. Que el repositorio interno
trabaje con el almacenamiento, que en nuestro caso es Firestore,
para almacenar y recuperar datos. Y a su vez, devolverá
elementos del modelo, que son propiedad del modelo de vista. Bien. Entonces, comencemos y sigamos adelante
e implementemos el modelo de vista para nuestra vista de celda de tareas. Así que primero creemos un nuevo
grupo aquí para nuestros modelos de vista.

Y arrástrelo hacia abajo un poco. Y luego crearemos
una nueva clase, un nuevo archivo. Y llamémoslo
modelo de vista de celda de tareas. Está bien. Así que va a ser un
modelo de vista de celda de tarea de clase. Y tiene que ser
un objeto observable. Esto es para que SwiftUI
pueda observar cualquier cambio que hagamos en las
propiedades de este modelo de vista. Y también tiene que
ser identificable. Porque queremos que ListView
use esos modelos de vista de celdas de tareas. Y como vimos antes, es
importante tener elementos que sean identificables. DE ACUERDO. Entonces, cada uno de esos
modelos de vista de celdas de tareas tendrá una referencia a una tarea. pues una tarea. Pero no es suficiente que
solo tengamos una referencia.

Necesitamos
asegurarnos de que esto se publique para que se
pueda escuchar cualquier cambio en la tarea. Entonces, usemos la
anotación publicada para hacer de esto un editor. Está bien. Entonces necesitamos otra
propiedad que nos ayude a hacer esto identificable. Y esta va a ser la ID
y va a ser una cadena. Y luego, también queremos
mantener el nombre del ícono que vamos a usar para
indicar el estado de finalización. Así que, de nuevo, va a ser
una propiedad publicada, una variable publicada, un
nombre de icono de fecha de finalización. Y esta es la cadena. Y hagamos de esto
una cadena vacía. Y también, hagamos la ID
y la cadena vacía también. Esto nos ayudará
con el inicializador como puede ver en un minuto. Está bien. Entonces, en el inicializador,
vamos a hacer un par de cosas. Entonces, antes que nada, el
inicializador tomará la tarea. Y luego queremos
operar en la tarea. Entonces, antes que nada, asegurémonos
de hacer un seguimiento de la tarea. Así que asignémoslo
a nuestra propiedad aquí. Y luego, avancemos y
ejecutemos una operación de mapa en la tarea.

Y lo que queremos hacer
es transformar la tarea en una cadena. Y la cadena
nos dirá qué icono usar. Así que usemos la
firma de transformación aquí. Y tendremos
una tarea por ingresar. Y luego vamos
a mirar la tarea, y si está
completa, vamos a devolver marca de verificación,
punto, círculo, punto, relleno. Y si no es así, vamos
a regresar al círculo. Probablemente esto le resulte
muy familiar, porque es exactamente lo que
hemos estado haciendo en la interfaz de usuario.

Pero estamos extrayendo esto
en el modelo de vista ahora. Está bien. Entonces, lo siguiente
que debemos hacer es asignar el
resultado de la operación de mapa a esta propiedad aquí arriba. Y en combinación, podemos hacer esto
usando el operador de asignación. Y vamos a asignar
esto a una propiedad de uno mismo. Y será el
nombre del ícono de estado de finalización. Y finalmente, necesitamos
realizar un seguimiento de nuestros suscriptores y asignarlos
a un cancelable. Así que vamos a configurar esto aquí. Privados o cancelables es un
nuevo conjunto de cualquier cancelable. Y para usar eso,
necesitamos importar combine. Está bien. Y ahora podemos guardar esto en
esta colección de cancelables. Fresco. Entonces, una vez más, estamos
mapeando la tarea. Y luego, dependiendo
de su etapa, devolveremos el
nombre del ícono, lo almacenaremos en esta
propiedad, y esto es para fines de administración de memoria
aquí abajo.

Bien, eso es lo primero que
tenemos que hacer. Y luego, la otra
cosa que debemos hacer es hacer un
seguimiento de la identificación. Y esto se va a
ver muy similar. Entonces, punto tarea punto mapa y
tenemos una tarea por venir. Y devolveremos
el ID de la tarea y luego
lo asignaremos a la propiedad ID. Y luego guardemos esto
en cancelables. Fresco. Así que ese es nuestro
modelo de vista de celda de tareas. Entonces, con un modelo de vista hacia abajo,
necesitamos otro modelo de vista.

Entonces, quizás se pregunte, ¿por qué
necesitamos dos modelos de vista? La razón es que
en realidad tenemos dos puntos de vista diferentes. Así que tenemos
ListView en sí, y tenemos la vista de celda. Entonces, este modelo de vista que
hemos creado actualmente es para la celda. Y ahora también necesitamos tener un
modelo de vista para la lista. Así que vamos a crear una nueva clase y
llamarla modelo de vista de lista de tareas. Y vamos a impartir combinar. Y va a ser una clase,
así como un modelo de vista de lista de tareas.

Y es un objeto observable. No es necesario
que sea identificable, porque básicamente es el
envoltorio de todos los elementos que vamos a
mostrar en la lista. Pero tiene una propiedad
para mantener todos esos modelos de vista de celdas de tareas. Entonces, los modelos de vista de celdas de tareas son una
matriz de modelos de vista de celdas de tareas. Y creemos una
matriz vacía cuando inicialicemos. También necesitamos los cancelables. Está bien. Y luego, aquí está
nuestro inicializador. Y en el inicializador,
por ahora, seguiremos operando
con los datos de prueba y convertiremos todas esas
tareas de prueba en pequeños modelos de vista de celdas de tareas. Y esto es
bastante sencillo. Por lo tanto, los modelos de vista de celdas de tareas
equivalen a pruebas de tareas de datos y mapas de puntos.

Ups. Eso fue un poco rápido. Déjame hacerlo de esta manera. Está bien. Entonces, para cada tarea que
obtengamos, básicamente devolveremos un modelo de vista de celda de tareas. Y simplemente enviaremos
la tarea actual. Fresco. Así que tenemos nuestros
dos modelos de vista. Y ahora lo que debemos hacer es
vincularlos a la interfaz de usuario. Así que volvamos
a nuestra vista de lista. Y lo que necesitamos es una referencia
a nuestro modelo de vista de lista de tareas. Así que hagamos esto. Es un
nuevo modelo de vista de lista de tareas variable. Y vamos a instanciar esto. Y luego, para que
podamos vincular la interfaz de usuario, debe ser un
objeto observado. Esto permitirá que SwiftUI
escuche las actualizaciones que esto va a producir. Está bien. Así que falta un argumento para la
tarea de parámetros en el núcleo. Oh sí. Yo se porque. Porque esta es la clase equivocada.

Así que las listas de tareas ven el modelo. Ese es el correcto. DE ACUERDO. Así que ahora, en lugar de iterar
sobre esta colección de tareas que tenemos,
accederemos a nuestro modelo de vista e iteraremos sobre la
colección de tareas en ese modelo de vista. DE ACUERDO. Vamos a hacerlo. Así que el modelo de vista de lista de tareas.

Y necesitamos iterar sobre los
modelos de vista de celdas de tareas allí. Entonces, el compilador todavía se
queja un poco. Así que hagamos un
poco de limpieza aquí. En primer lugar, este
será el modelo de vista de celda de tareas. Y luego, necesitamos refactorizar
la celda de tareas también aquí abajo. De nuevo, vamos a
usar un objeto observado. Y esta vez,
llamémoslo modelo de vista de celda de tareas. Y es un
modelo de vista de celda de tareas. Está bien. Y luego, eliminemos
esto, porque ya no lo necesitamos. Y luego arreglemos los
errores de compilación aquí abajo. Entonces, antes que nada, acceda a
la tarea aquí abajo.

Y luego cambia esto ahí abajo. DE ACUERDO. Así que esto debería estar bien. Y luego aquí arriba,
vamos a acceder a esta variable en nuestra lista. Fresco. Así que esto se ve bien. A ver si compila. Se ve bien hasta ahora. Compilación exitosa. DE ACUERDO. Entonces, ejecutemos la
aplicación y veamos si todo funciona como antes. Y en lugar de ejecutar
la aplicación, usemos
la vista previa aquí abajo. Porque podemos usar
este pequeño botón de ejecución para ejecutar la aplicación. Y veamos. Toma un pequeño momento. Oh, probablemente necesito reanudar. Ambos lo lograron. DE ACUERDO. Esta funcionando. Entonces, en caso de que
no me creas, vamos a ejecutarlo también
en el simulador. Compilación, lanzamiento. Consigamos el simulador. Está bien. Aquí vamos. Así que refactorizamos nuestra interfaz de usuario para
usar una arquitectura de modelo de vista.

Y esto hace que
las cosas sean mucho más limpias y conducirá a un
código mucho más limpio, especialmente en las vistas,
como verá más adelante. Y es mucho más fácil
conectarse a diferentes tipos de back-ends, lo que
todos hacemos en el momento. Entonces, hay un par de
cosas que aún no funcionan en nuestra aplicación. Y tenemos que arreglarlos. Entonces, por ejemplo, no podemos agregar
nuevos elementos a nuestras listas. Y no podemos editar los
elementos de la lista. Y no podemos marcar
elementos como hechos. Así que esto es algo que
vamos a ver a continuación. Está bien. Así que volvamos al código. Entonces, lo primero
que debemos hacer es refactorizar
un poco los elementos de nuestra lista. Y lo primero
que voy a hacer es convertir esta
lista aquí en un for-each. Y esto se debe a que
en realidad queremos iterar sobre todos los
elementos de nuestra colección.

Y luego, también queremos
agregar un nuevo elemento específico. Y este va a ser nuestro
elemento editor, por así decirlo. Y es por eso que necesitamos
desarmar la lista. Entonces, antes que nada,
reemplacemos esto con un bucle for-each. Y el resto puede permanecer igual. Y luego incruste
esto en una lista. Así que vamos a sangrar esto. Fresco. Por lo tanto, también debemos
declarar una bandera que nos ayude a ocultar y
mostrar esta celda muy específica a pedido cuando el usuario presione
este botón en la nueva tarea aquí abajo. Así que sigamos adelante y agreguemos
esto como un estado aquí. Por lo tanto, indique o congele
y agregue un nuevo elemento. Y digamos que es
falso por el momento.

Así que queremos ocultarlo inicialmente. Y luego, además
de esto para cada bucle, mostraremos una
celda de tarea, dependiendo de si un presente en un
nuevo elemento es verdadero o falso. Así que hagamos un poco de
condicional aquí. Si presente en el nuevo
elemento es verdadero, entonces desea mostrar una nueva celda de tareas. Y requiere un nuevo
modelo de vista de celda de tareas. Y eso significa que necesitamos
crear un modelo de vista de celda de tarea ficticio aquí mismo. Así que vamos a hacer eso. Y luego necesitamos
crear una tarea ficticia también. Y tiene un título vacío. Y el
estado de finalización es falso.

Bien. Así que esta es nuestra celda adicional. Actualmente, no se
muestra. Y queremos cambiar eso. Entonces, cada vez que el usuario
presiona el botón aquí, queremos mostrar u ocultar esta
celda adicional allí. Y puede hacer esto alternando
el presente en el booleano de nuevo elemento . DE ACUERDO. Echemos un vistazo si eso funciona. Ejecute rápidamente la aplicación. DE ACUERDO. Cuando presiono el botón,
mostrará u ocultará un nuevo elemento. Y actualmente, eso
no hace nada, porque todavía estamos usando un
texto en lugar de un campo de texto. Así que esto es algo que
tenemos que cambiar ahora. DE ACUERDO. Así que entremos en nuestra celda de tareas. Y luego convierta este texto
aquí en un campo de texto.

Así que permítanme eliminarlo
en el campo de texto. Y luego debe ajustarse
al título de la tarea. Y también podemos proporcionar
un texto de marcador de posición. Entonces ingrese el
título de la tarea, eso es lo que queremos mostrar si no
hay nada allí. Y luego, queremos vincular el
valor de texto del campo de texto a nuestro título de la
tarea en nuestro modelo de vista. Ese es el
modelo de vista de la celda de tareas.

Y luego la tarea y el título. DE ACUERDO. Intentemos esto de nuevo. DE ACUERDO. Agregar un nuevo elemento. Para que pueda ver el lugar donde
ingresa todo el texto del título de la tarea . Y cuando hago clic
aquí, puedo empezar a escribir. Y también puedo aprovechar
cualquiera de los otros elementos , porque estamos usando la
misma celda para esta celda del editor y también para cualquier tarea existente que
mostramos en nuestra lista. Que es exactamente lo que queremos. Porque queremos
permitir que los usuarios simplemente toquen la lista y luego
cambien los elementos sin tener que
activar el modo de edición o lo que sea. Así que esto es exactamente lo que queremos. Está bien. Entonces, lo siguiente
que debemos hacer es
escuchar los cambios que hacen los usuarios
para que podamos tomar esos cambios
del modelo de vista de celda y volver a colocarlos en la
estructura de datos subyacente. Entonces, lo primero
que debemos hacer es agregar un
pequeño controlador de devolución de llamada. Porque queremos escuchar
el evento uncommit en el campo de texto. Y cada vez que
se activa, queremos volver a llamar a nuestra
vista que luego puede tomar la tarea que hemos
creado y enviarla de vuelta a la
estructura de datos subyacente.

DE ACUERDO. Entonces, antes que nada, agreguemos
una nueva variable aquí. Se llama en compromiso. Y lo que queremos hacer es
enviar una tarea. Y obviamente
no devuelve nada. Entonces, si hacemos eso, el
compilador se quejará. Y dirá que
aquí falta un argumento. Y
aquí abajo falta un argumento. Lo cual está bien,
porque aquí, de hecho, queremos
manejar la devolución de llamada. Pero aquí arriba, no
queremos hacer eso. Porque ya
tenemos un elemento. No necesitamos agregarlo
a nuestra colección. Y SwiftUI y
combine se asegurarán de que cualquier cambio
que hagamos en un elemento existente se refleje en la
estructura de datos subyacente.

Entonces, lo que queremos hacer
es, básicamente, solo proporcionaremos una
implementación predeterminada vacía aquí. Así. Y esto debería corregir el
mensaje de error del compilador aquí. Eso es genial. Lo siguiente
que queremos hacer es capturar el
evento de no confirmación en el campo de texto. Y, de hecho, déjame hacer
un poco más de espacio. Y ocultar la vista previa. Entonces queremos capturar
el evento de no confirmar en el campo de texto. Así que sigamos adelante y
escuchemos para no comprometernos. Y luego, cuando
recibimos esto, queremos llamar a esta devolución de
llamada aquí.

Así que no se comprometa. Y lo que queremos
hacer es enviar la tarea de vuelta. Está bien. Entonces, cada vez que use una
confirmación en el campo de texto, si presionan
el botón Intro, por ejemplo,
recibiremos esta devolución de llamada. Y luego vamos a
tomar la tarea actual, enviarla a nuestra devolución de llamada y
luego podemos capturarla aquí. Está bien. Entonces, para hacer eso, voy a usar
el hecho de que esto básicamente es solo un cierre final. Y luego
obtendremos la tarea aquí. Y luego queremos hacer
algo similar a esto. Así que queremos obtener el modelo de vista de tareas
, o el modelo de vista de lista de tareas , y luego nos gustaría
hacer algo como agregar tareas.

Pero todavía no existe un
método como ese. Así que esto fallará. Está bien. Así que arreglemos esto. Permítanme confirmar esto
para que podamos compilar. Y luego entraremos en
nuestro modelo de vista de lista de tareas e implementaremos un método que
capturará nuestra intención. Así que en la tarea, y
queremos tomar una tarea. Y luego lo agregaremos
a nuestra lista de modelos de vista de celdas de tareas . Sin embargo, primero debemos
convertirlo en un modelo de vista de celda de tareas. Así que hagamos eso. Y el modelo de vista de tareas es igual al
modelo de vista de celdas de tareas de celdas de tareas. Y tomará una
tarea, y luego podemos agregarla a nuestra colección. Y lo agregaremos para que se
agregue al final. Excelente. Así que volvamos. Descomprometer esto. Así que esto funciona bien. Una cosa más que debemos
hacer es que, cuando el usuario presione Intro, insertaremos el
elemento en las listas. Eso significa que la
lista agregará una nueva línea y eso se verá
un poco divertido. Déjame mostrarte lo que esto significa. Así que vamos a ejecutar la aplicación. Así que tenemos nuestras
celdas existentes aquí.

Agregamos uno nuevo. Y voy a pulsar enter. Y, como viste, insertó el
nuevo elemento en la colección. SwiftUI recogió esto,
actualizó ListView y todavía tenemos este
elemento aquí. Y esto se ve un
poco divertido. Así que asegurémonos de
ocultar esta celda aquí abajo cada vez que insertamos una nueva línea. Y eso es
bastante sencillo. Así que digamos, self dot
present a new item dot toggle. Esto significa que cada vez que
agreguemos un nuevo elemento, ocultaremos o editaremos nuestra celda. Echemos un vistazo de nuevo. DE ACUERDO. Permítanme agregar un nuevo elemento. DE ACUERDO. Y verás, solo
tenemos el nuevo elemento. La celda del editor desapareció. Y cuando agregue un nuevo elemento,
volverá a aparecer, tal como se esperaba. Eso funciona muy bien. Lo que todavía no funciona es
actualizar el estado completado. Así que hagamos esto también. Y esto es un poco más, es más fácil. Así que entremos en
nuestra celda aquí abajo. Y luego queremos asegurarnos de
que cada vez que el usuario toque la imagen,
cambiaremos el estado completado de la tarea subyacente.

Así que sigamos adelante y
agreguemos un gesto de toque. Y luego obtenga nuestro
modelo de vista de celda de tareas, obtenga la tarea, obtenga el estado completado
y luego simplemente cambie. Está bien. Ejecutemos la
aplicación una vez más. Y luego, puedo continuar
y alternar el estado completado de los elementos. Hermoso. Y eso es todo por hoy, amigos. Espero que hayas disfrutado
este breve video sobre cómo crear una
lista de tareas simple usando SwiftUI. En el próximo episodio,
le mostraré cómo conectar esta
aplicación a Firebase y cómo almacenar los
datos de la tarea en Cloud Firestore.

Gracias por mirar, y
te veré en el próximo. [REPRODUCIENDO MÚSICA].