Entrar a una sesión remota con tmux

Hace poco tuve la necesidad de usar Tmux en un servidor remoto para hacer algunas cosas de administración, y no conocía como usarlo, luego de un poco de investigación aprendí lo básico y aquí algunos comandos para poder usar Tmux si tienen necesidad de hacerlo algún día.

Entrar a una sesión remota

Salir de una sesión remota

Crear una nueva ventana de Tmux

Renombrar una ventana o ponerle nombre

Moverse a una ventana

Con esos comandos básicos ya se puede uno empezar a usar Tmux, próximamente espero poder usarlo más y aprender y porque me está gustando cómo se maneja.

Rotar imagen en Django cuando se guarda en un modelo

Existe un bug con los navegadores que cuando uno toma una foto con el celular de forma frontal y quiere subirlo a un formulario, por ejemplo para tu perfil, la imagen sale volteada

Estuve investigando un poco y es más que nada porque existe información en las imágenes que hace que los navegadores no lo muestran correctamente, un poco más de información pueden encontrarlo en un hilo de Confluence. Así que hay que arreglarlo en el lado del servidor para que podamos ver la imagen correctamente.

Antes que nada, voy a suponer que estamos usando Pillow  como la biblioteca de imágen, ya que es la más usada.

Arreglando el bug

Primero, lo que vamos a hacer es crear una pequeña función que nos ayude a rotar la imagen con ayuda de Pillow.

Si quieres saber por qué esos números, aquí más y mejor información sobre la orientación de EXIF https://www.impulseadventure.com/photo/exif-orientation.html

Esa pequeña función nos puede servir para otros proyectos que estemos haciendo, pero en el caso de Django, necesitamos hacer algunas cosas más para aplicarlo cuando se guarda la imagen.

En este ejemplo, vamos a tener un modelo llamado Profile  que es donde guardaremos nuestra imagen

Una vez que tengamos nuestro modelo necesitamos una forma de usar nuestra función para que procese la imagen una vez que se haya guardado la imagen, para así traer el path como se guardó y no tener errores.

Para eso, vamos a hacer uso de los signals  que tiene django, en especial post_save , ya que tenemos que procesar la imagen una vez que se haya guardado en el sistema de archivos.

Hay que modificar nuestro archivo de models.py  para traer las bibliotecas necesarias

Y ya con este cambio, cuando guardemos una imagen en Django podremos ver la imagen correctamente

Desplegar un servidor NFS en Centos 7

NFS (Network File System) es un protocolo que se utiliza para que tengamos un sistema de archivos distribuidos en una red de computadoras. Con esto, muchas máquinas clientes pueden conectarse a un servidor de archivos y de esa forma poder compartirlo.

Debido a que el compartir archivos es muy común en empresas, el NFS se usa mucho para que archivos importantes estén accesibles para todos o para quienes queramos que tengan acceso.

En esta ocasión desplegaremos un servidor NFS y también configuraremos la parte de cliente para poder crear archivos remotamente.

Instalando el servidor NFS

Primero vamos a instalar el servidor de NFS y configurarlo. Los comandos los corremos como root.

Creamos los directorios en donde se va a compartir la información y darle permisos, por ahora le daremos permisos 777, luego podemos configurarlos para que escriban ciertos usuarios o ciertos grupos.

Debido a que Centos 7 viene con SElinux activado que no deja que NFS comparta archivos, vamos a activar algunas banderas para que podamos compartir

nfs_export_all_ro  con esta opción ya podemos empezar a compartir el servicio, pero para que todos puedan leer y escribir entonces activamos nfs_export_all_rw

Ya que hayamos puesto los comandos arriba mencionados, hay que asegurarnos que efectivamente estén encendidos

Necesitamos agregar las reglas de firewall para que que no nos bloquee el acceso desde el cliente.

Una vez que ya tenemos instalado y con el firewall listo, es necesario habilitar los servicios, si no, no podemos usarlos

Hay que modificar el archivo /etc/exports , aquí es donde pondremos todos los directorios que queremos que estén disponibles para NFS, por lo cual podemos poner desde uno hasta los necesarios, este archivo es importante ya que aquí definimos algunos permisos y protocolos que podemos usar.

Y agregamos la siguiente línea

Donde

  • /data -> Es el directorio a compartir
  • xxx.xxx.xx.xx/24 -> Es la ip de la maquina con la mascara de subred
  • rw -> Son permisos de escritura
  • sync -> Todos los cambios en el sistema de archivos correspondiente se vacían inmediatamente al disco; Se esperan las respectivas operaciones de escritura
  • no_root_squash -> De forma predeterminada, cualquier solicitud de archivo realizada por el usuario root en la máquina cliente es tratada como por el usuario nobody en el servidor. Si se selecciona no_root_squash, el root en la máquina cliente tendrá el mismo nivel de acceso a los archivos del sistema como root en el servidor.

Una vez que hayamos hecho nuestros cambios hay que exportarlos

Por último reiniciamos los servicios para que tomen efecto los cambios que hicimos

Ya con esto tenemos configurado el servidor de NFS ahora falta hacer la parte del cliente pero eso es más fácil.

Configurar el cliente NFS

Ya que estemos en el cliente desde donde queremos accesar a nuestro servidor NFS tenemos que instalar también las utilidades de NFS

Y activar los servicios

Hay que crear un directorio que es el que vamos a montar en nuestro servidor

Ya con esto, podemos montar nuestro directorio

Vamos a ver si realmente se montó

Si aparece el punto de montaje, ¡felicidades!, ya tienes un servidor NFS listo.

Para no montar el NFS cada vez que reiniciemos la máquina, podemos modificar fstab  para que se automonte

Ya con esto tenemos configurado tanto cliente como servidor, como te darás cuenta aún falta configurar permisos o también generar carpetas para grupos de usuarios, pero este tutorial te servirá para iniciar tu servidor NFS.

En un siguiente tutorial, vamos a utilizar kerberos para agregarle seguridad a nuestra instalación y que esté mejor protegido nuestros archivos.

Instalar Django con Ubuntu, Ngnix, Postgres y Gunicorn

1. Introducción

Desplegar un sitio en producción es un sufrimiento, incluso servicios que “simplifican” el deployment como Heroku hacen un poco menos pesado el atrejeo pero aún así sigue siendo un sufrimiento, más en casos como Django que no es tan sencillo como con PHP y Apache.

Mi intento con este artículo no es solo escribir una guía comprensiva, si no que también me servirá para tener de referencia rápida de cómo hacerlo. Esta guía lo haré conforme los pasos que hice, por lo tanto talvez no sea la mejor pero trataré de que sea muy sencilla de seguir.

2. Recursos

Como tuve que investigar cómo hacerlo, más que nada esta es un compendio de conocimientos regados por internet, aquí solamente pondré lo necesario para llevar a producción un sitio hecho en Django.

Muchas de estas páginas son en caso de que quieras adentrarte más luego de haber instalado tu proyectos y algunos tutoriales que te servirán para tener en claro algunas cosas que a lo mejor no digo aquí, como instalar el servidor Ubuntu.

2.1. Docs

2.2. Tutoriales

3. Generalidades

Debido a que poner todo exactamente aquí podría hacer de esta guía muy larga, y a lo mejor la mayoría de ustedes ya lo saben, aquí habrá algunas cosas que asumo que ya conoces.

3.1. General

Esta guía asume que tienes un conocmiento básico de Linux y que trabajas con la terminal. Cosas como ejecutar un comando, listar el contenido de una carpeta, usar un editor en la terminal ya sea Vim o el que más te guste, además de crear carpetas. Algunos comandos aquí listados serán más complicados que los que acabo de decir.

3.2. Stack

En la guía voy a Utilizar Ubuntu 16.04 LTS , aunque igualmente puedes utlizar cualquier distro de Linux, con los cambios necesarios.

La versión de Python será la 3.6.2. La versión de Django será 1.11 y utilizaremos la versión de Python 3. El sistema de versión de controles será Git.

El stack para el sitio será la base de datos PosgreSQL, el servidor Nginx, y como nuestro servidor WSGI será Gunicorn. La base de datos, el servidor, los archivos estáticos se asumen que serán instalados en el mismo servidor.

3.3. Proyecto Django

Asumo que tu proyecto ya fue probado localmente y está listo para instalarlo en producción. Algunas guías se enfocan a instalar un proyecto inicial, sin nada más que lo que creas al utilizar el comando para generar el sitio con Django, otras lo hacen con el famoso tutorial de Polls, en mi caso esta guía pretende instalar un proyecto, aunque sencillo, pero tiene algunas cosas que se ven en un proyecto normal.

3.4. Layout

El proyecto asume la siguiente estructura.


No voy a pedir que cambies la estructura de tu proyecto, solamente lo pongo aquí por pura referencia.

Lo más importante es el PROJECT ROOT, CONFIGURATION ROOT y que te des cuenta que los settings de nuestro proyecto están como paquetes, de esta forma será más fácil la configuración.

3.5. Variables del virtualenv y virtualenvwrapper

La guía asume que usamos virtualen y virtualenvwrapper, tanto en local como en produccón.

Configuración sensible como la secret key, la contraseña de la base de datos, etc, será guardado en variables de ambiente, las cuales podemos configurar en los archivos postactivate  y predeactivate  que podemos encontrar en la carpeta de nuestros ambientes virtuales, si has seguido el tutorial que hice, debería estar en /home/yourname/.virtualenvs , los archivos que necesitamos están en

postactivate debería lucir como este


Y el archivo predeactivate debería contener:

Para que Django pueda acceder a estos valores, debemos sustituir los datos en el archivo de settings, por ejemplo:

4. Instalación

Ya que tenemos claro qué vamos a usar y cómo, es hora de ponernos manos a la obra para la instalación de nuestro proyecto, desde cero.

4.1. Crea la instancia de tu servidor en Linode

He usado Linode desde hace unos 5 años y nunca me ha dado problemas, actualmente los precios están muy accesibles y tienen memorias SSD.

Los pasos necesarios los encontrarás en el Getting Started de Linode. Si no tienes Linode y quieres probarlo te agradecería que lo hicieras mediante mi código de referencia 🙂

Igualmente otro muy bueno es DigitalOcean.

Como referencia, mis settings del servidor son

  • Hardware: Intel(R) Xeon(R) CPU E5-2680 2 Cores 2GB RAM
  • Región: Dallas
  • No extras
  • Distribución: Ubuntu Linux 16.04 LTS x64

Si vas a usar Ubuntu con memoria RAM menor a 1 GB, se recomienda la versión de 32 bits.

4.2. Compra un dominio (opcional)

Si quieres que sea más fácil encontrar tu sitio web en internet, es recomendable que compres un dominio, hay varios lugares donde puedes comprarlos, entre ellos están Godaddy y Namecheap, elige el que más te guste.

4.2.1 Configura tus DNS

Una vez que tengas tu domino, la mejor forma de usarlo es configurar los DNS en Linode, son rápidos y además son efectivos, no me han dado problemas, para hacer esto recomiendo leer la guía de Hosting a WebSite, en donde al partir de Adding DNS Records podrás configurarlos.

4.3. Configuración inicial del servidor

En este punto debes configurar tu servidor, de tal formas que tengas actualizado Ubuntu y crees las llaves SSH, simplemente sigue las instrucciones del Getting Started y también la guía de Securing Your Server.

Con estas dos guías tendrás la configuración básica del servidor.

4.4. Instalando cosas

Ya que tienes tu servidor listo, es hora de empezar a instalar lo que vamos a necesitar. Asumimos que Python 3 es el intérprete utilizado.

Recuerda que estos comandos se harán en la terminal de tu servidor Linux.

4.4.1. pip

4.4.2. PostgreSQL

4.4.3. Nginx

4.4.4 git

4.4.5 virtualenv

4.4.6. virtualenvwrapper

Luego de haberlo instalado, configura tu archivo .zshrc  o .bashrc

4.5. Configurar PostgreSQL

Ahora es tiempo de configurar la base de datos. Primero, necesitamos cambiar al usuario postgres

Hay que crear la base de datos. Recuerda que el nombre de la base de datos es el mismo que el que tienes en tus settings.

Creamos un nuevo usuario, éste debe coincidir con los settings de tu base de datos, al crear el usuario te pedirá contraseña, que es la que vas a utilizar en tu base de datos.

Vamos a entrar al shell de PostgreSQL y dar los privilegios al usuario

Finalmente, regresa a tu usuario normal

4.6. Crear un ambiente virtual

Lo siguiente será crear nuestro ambiente virtual para trabajar con Python 3

Ahora es tiempo de poner las variables de los ambientes virtuales como mencioné arriba.

4.7. Clonar el proyecto

Es hora de clonar nuestro proyecto, crearemos un directorio en nuestra carpeta `home, para que encontremos más fácil nuestros paths.

En tu terminal escribe

Reemplazando la url con la tuya.

4.8. Instalando los requerimientos de tu proyecto

Tendremos que instalar los requerimientos de nuestro proyecto. Si tienes el archivo requirements.txt  (que deberías), es muy fácil instalarlos. Asegúrate de estar en el ambiente virtual de tu proyecto

4.8.1. Activa el ambiente virtual

4.8.2. Instala los requerimientos

4.8.3. Instalar Gunicorn

Si gunicorn no está en los requerimientos, tenemos que instalarlo

4.8.4. Migrate

Si ya tienes la configuración de tu base de datos y además has hecho tus pruebas en local, es hora de sincronizarlo con Django.

4.8.5. Crear el superusuario de Django

En caso de que lo necesites, crea el superusuario

Sigue las instrucciones que te van apareciendo.

4.8.6. Collecstatic

Cuando hacemos un collectstatic, Django copia todos los archivos en la carpeta de static que tenemos configurado y los copia al STATIC_ROOT, estos son los archivos estáticos que usará Nginx.

Contesta que si, y Django se encargará del resto

4.9. Configurar Nginx

Esta sección asume que tenemos configurado Django de la siguiente forma

STATIC_ROOT  es el directorio en donde se copiaron los archivos estáticos, de acuerdo a la configuración será en /home/yourname/web/yourproject/yourproject/public/static/

Para configurar Nginx, un bloque debe ser creado. La meta de la configuración de Nginx será servir todos los archivos estáticos con Nginx y dejar los otros request a Gunicorn (y Django)

Crea un nuevo archivo de configuración

El nombre del archivo no importa, pero es mejor tener consistencia con el nombre de tu proyecto. Dentro del archivo, escribe lo siguiente


Has las sustituciones si es necesario:

  • Después de server_name, usa el nombre de tu proyecto o dominio
  • El path en alias debe coincidir con el path de tus archivos estáticos generados con collectstatic , para estar seguros, ve hacia el directorio de tus archivos estáticos y escribe dentro de la carpeta static pwd , copia y pega el path
  • El puerto en proxy_pass  debe ser el puerto que intentas usar con Gunicorn, no cambies la IP
  • El path después de location debe coincidir con tu STATIC_URL de tu configuración

Es hora de activar nuestro sitio, debemos poner un enlace simbólico a la carpeta de sites-enabled

Elimina el archivo default que no vamos a necesitar

Finalmente, es hora de activar nuestro nuevo sitio

4.10. Iniciar Gunicorn

Una vez que tenemos configurado Ngnix, es hora de inciar Gunicorn, nuestro servidor HTTP de producción.

En la terminal, ten activado tu ambiente virtual

Fíjate que el puerto sea el mismo que configuraste en Ngnix.

Ahora ve a tu dominio o a la IP de tu sitio, y tu sitio, esperemos, aparecerá. Si tu sitio aparece ¡felicidades!, prácticamente tienes todo listo. Mata Gunicorn con CTRL-C  para prepararte para crear el daemon y que Gunicorn trabaje en el background.

Primero, es necesario que hagamos una carpeta donde podamos ver los logs de Gunicorn por si algo sale mal. Lo haré en la carpeta web, afuera del directorio del repositorio.

Ahora es tiempo de iniciar gunicorn como un demonio

La documentación de gunicorn recomienda poner los workers en “in the 2-4 x $(NUM_CORES) range.”

Puedes ponerlo en un script para reutilizarlo.

5. Mantenimiento

Algunos consejos útiles para mantener tu servidor corriendo

5.1. Parar gunicorn

Reiniciar gunicorn puede ser necesario luego de hacer un pull de tu repositorio. Si quieres pararlo simplemente usa

Esto matará el proceso llamado gunicorn

5.2. collectstatic

Siempre que hagas algún cambio en los estáticos de tus sitios, debes correr el collectstatic para que puedan ser vistos los nuevos cambios.

6. Conclusión

En este punto, tu sitio debería estar en el servidor de producción. Espero que esta guía te haya ayudado un poco a hacer el deployment de tu aplicación, ya que es uno de los puntos más engorrosos cuando trabajamos con Django.

Si tienes algún problema recomiendo que vayas paso a paso, y que te fijes bien en la configuración que doy y lo compares con l a que tienes. Si aún tienes problemas, puedes escribir y con gusto te ayudaré en lo que pueda.

Si ves algún error en la guía, me gustaría que lo dijeras para irlo mejorando. Espero dentro de poco sacar un video con los mismos pasos para que sea un poco más visual.

Map, Filter y Reduce en Swift

Swift es un gran lenguaje, y unas de las cosas que me gusta de Swift es que puedes programar funcionalmente aún si el lenguaje no es 100% funcional. Muchas de las características de Swift se parecen a otros lenguajes como Elixir y F#.

Una de las características es que las funciones son tratadas como tipos, pueden aceptar funciones como parámetros y retornar funciones. A menudo a las funciones que toman como parámetros otras funciones son llamadas funciones de orden superior.

En este artículo vamos a enfocarnos en tres funciones que vienen en la biblioteca de Swift y que son muy poderosas cuando queremos manejar Arreglos.

Map

Imaginemos que tenemos un arreglo de números enteros y a todos los elementos queremos elevarlo al cuadrado.

Generalmente haríamos una función con un bucle como el siguiente

La función map resuelve el problema de transformar los elementos de un arreglo pasándoles una función. Esta función itera sobre cada elemento y a cada elemento les aplica la función que nosotros pasemos como parámetro, esto nos ahorra usar mucho los for…in y además de que es más elegante. map retorna un arreglo de la misma longitud que el arreglo al cual le aplicamos la función.

El código anterior quedaría así

En este caso pasamos la función como un closure { x in x * x } , donde x  es cada elemento del arreglo pasado como parámetro de la closure, y x * x  es el cuerpo de la función, de esa forma pudimos transformar los elementos del arreglo sin crear ningún bucle.

Filter

Al igual que map, filter es una función que itera sobre los arreglos, como su nombre lo indica, filtra los elementos de un arreglo de acuerdo a la función que nosotros le pasemos.

filter retorna un arreglo con los elementos filtrados del arreglo original, pudiendo ser de igual longitud, menor o vacío.

Supongamos que tenemos un arreglo que representa los nombres de imágenes con diferentes extensiones y queremos obtener solo los jpg.

Ahora usemos la función filter.

Al igual que map, no tuvimos que crear ni un for-in, ni tampoco tuvimos que agregar el elemento que estamos filtrando, solamente pasamos nuestro closure y filter hace todo por nosotros.

Cabe destacar que Swift infiere el tipo de la variable gracias al arreglo original, por eso podemos aplicar hasSuffix  a cada elemento porque Swift sabe que es un tipo String .

Reduce

Al contrario que map y filter, reduce nos retorna un solo valor, que es la combinación de los elementos del arreglo al cual le aplicamos la función.

Prosigamos con el ejemplo de los números, si queremos sumar todos los elementos de un arreglo, haríamos algo como esto

Cuando usamos reduce, no solamente tenemos que pasar una función, si no también un acumulador, que es el valor inicial de nuestro contador, si es trabajo con enteros generalmente es 0, si son cadenas se pasa una cadena vacía. Depende de lo que quieras hacer.

Ahora el ejemplo con reduce

En este caso, pasamos como valor inicial  , ese valor se pasa como parámetro al closure, al cual le pusimos como nombre acc ; x  es cada elemento del arreglo, y el cuerpo de nuestro closure es la suma del acumulador y cada elemento del arreglo.

Como ves, esta función es un poco más elaborada, pero una vez que le entiendas, puedes hacer muchas cosas interesantes.

Nota: Estas tres funciones todavía puede reducirse aún más gracias a la sintaxis de los closures, el reto es que intentes cambiarlo a su expresión más reducida.

Combinando todo

Ahora que ya sabemos el uso de estas funciones, vamos a crear un pequeño programa donde usaremos las tres al mismo tiempo.

Listo, tenemos nuestro programa funcionando y filtrando las ciudades, sin necesidad de usar bucles, además que gracias al acumulador usado como cadena, podemos imprimir nuestras ciudades en un lindo formato.

Espero te haya convencido de que empieces a usar estas funciones en tu programa, verás cómo vas a ir haciendo un código mucho más elegante y funcional.

Si quieres ver esta entrada, pero con ejemplos con C# puedes visitar este post o si te interesa F# puedes hacerlo en este post.

¿Qué necesito para empezar a programar para iOS?

Hay varias personas que se preguntarán, ¿cómo empiezo a construir apps para iOS?. Así que he decidido crear esta pequeña guía donde podrás saber cómo empezar y qué tener para comenzar a crear tus propias aplicaciones.

Primero que nada, una cosa muy importante es que aprendas Swift, ya que es hacia donde Apple quiere llevar la plataforma, igualmente debes aprender Objective-C, porque hay muchas apps que están escritas en ese lenguaje y puede darse el caso que tengas que mantener apps, actualizarlas o simplemente así te lo piden.

La última versión de Swift cuando escribí esto que es 2017, es la 3.1 por lo cual puedes esperar un lenguaje ya estable y con varias características. Si quieres saber más de Swift, te recomiendo que leas The Swift Programming Language que puedes encontrar en iBooks, sirve mucho como referencia.

Lo básico

Primero empecemos por lo básico, lo esencial si quieres empezar a programar para iOS y que todos tenemos.

1) Mac

Macs

No hay de otra, si quieres crear aplicaciones para iOS tienes que tener una Mac. Olvídate de trucos o crear una Hackintosh, si quieres ser profesional en desarrollar aplicaciones de iOS tienes que conseguirte una Mac. Ahora ya no es tan complicado, he visto lugares donde venden Macs mini no tan caras, incluso conseguir una nueva no tendrás que desembolsar tanto dinero, eso si, asegúrate que puedas actualizar a la última versión de macOS.

2) Xcode

Es la plataforma para programar por defecto. Es oficial y siempre va a tener las últimas novedades del lenguaje en cuanto salga. Es primordial que sepas usarlo bien. Tiene muchas características que te van a ayudar. Aunque existen otras alternativas como AppCode, por ahora, es lo único que necesitarás.

3) Cuenta de desarrollador

Vas a necesitar la cuenta de desarrollador si quieres integrar características como Push Notifications, Seguridad SSL, etc. También la vas a necesitar si quieres probar tus apps en tu dispositivos. Hacer una cuenta de desarrollador de Apple es tan fácil como ir a Apple Developer y registrarte. ¡Es completamente gratis!

Sin embargo, si quieres publicar tus aplicaciones en la AppStore, vas a tener que pagar una licencia de $99 dólares por año.

Extras

Con las tres cosas anteriores ya puedes empezar a hacer experimentos con Swift y iOS, pero también hay otras herramientas muy útiles y que tarde o temprano vas a tener que utilizar si quieres seguir adelante.

1) CocoaPods

No siempre vas a tener que hacer las cosas desde cero, hay mucho código que han escrito otras personas y que van a ser útil para tu aplicación. CocoaPods básicamente es una biblioteca de código en la cual otros desarrolladores suben sus proyectos que pueden ser incluidos en el tuyo, esto facilita algunas cosas y puedes crear apps más rápido. Más información en CocoaPods.org.

2) Git

Git sirve como un respaldo de tu proyecto en donde puedes tener todo un historial de cómo ha evolucionado el código de tu aplicación. Si lo combinas con un repositorio remoto como Github entonces podrán colaborar otras personas y también tener un respaldo mucho mayor.

Aunque el concepto de git puede resultar algo complicado para algunas personas, comenzar a trabajar con él es sencillo y te va ayudar mucho en tu carrera. Un buen recurso para empezar con git es este libro.

3) Stackoverflow

Este es un gran sitio donde puedes buscar ayuda. Muchas de las dudas que tienes generalmente ya otras personas la tuvieron y les han ayudado. Cuando buscas en google un problema, generalmente este sitio está en los primeros resultados.

Hay que aclarar que debemos usarlo con cuidado y no solo copiar y pegar el código, tienes que entender que es lo que estás copiando. Algunas respuestas son muy buenas y aprendes mucho de ellas, este sitio ha salvado trabajos.

4) Videos de la WWDC

La WWDC es la meca de las conferencias de iOS, están impartidas por ingenieros de Apple y muchos de sus socios más cercanos. Aunque es muy difícil conseguir boletos para ir, Apple generalmente saca los videos de sus conferencias muy rápido, si quieres ver cómo va evolucionando el ecosistena, aprender trucos y ver las nuevas características de la plataformas de Apple, sus videos son obligatorios. Solo se pueden ver en safari.

Creo que para empezar está bien, espero que este artículo te ayude a empezar con el desarrollo de aplicaciones de iOS. Si tienes alguna duda o pregunta, siéntete cómodo de preguntarme. Y si te gustó este artículo, voy a seguir escribiendo más sobre Swift y iOS para ayudarte en tu travesía.