SwiftTutoriales

Firebase, instalación con Swift Package Manager y uso en SwiftUI con iOS 14 y Xcode 12

Di adiós a CocoaPods y entra en el mundo mágico de Swift Package Manager

Lo confesamos: en Apple Coding somos enemigos acérrimos del famoso CocoaPods. No nos gusta nada. Hemos sufrido tanto con él y hemos encontrado muchas extrañezas con los años. Lo sentimos por aquellos que les guste: nosotros lo hemos usado por exigencias de clientes o APIs que solo aportaban esa forma de instalar casi desde su lanzamiento en 2011, y las pesadillas han sido muchas y terroríficas.

¡Di CocoaPods otra vez!

Por este motivo, hace un tiempo hicimos un tutorial que os gustó bastante, sobre cómo instalar una de las APIs más usadas a nivel profesional sin usar este gestor de dependencias: Firebase sin CocoaPods.

La gran noticia, es que Google se ha puesto las pilas y ha presentado el soporte de instalación (en beta, por ahora) de Firebase (todas sus APIs) a través del gestor de paquetes oficial del lenguaje Swift: Swift Package Manager. Y vamos a enseñaros cómo usar este y descubriréis un nuevo mundo de gozo y regocijo.

¿Por qué ha tardado tanto?

SPM o Swift Package Manager, es el gestor de paquetes (dependencias) oficial del lenguaje Swift. Un gestor que lleva varios años con nosotros, pero que hasta el pasado año con Xcode 11 no ganó integración con el IDE de Apple. Este motivo, imposibilitaba que pudiera usarse como gestor de dependencias (paquetes) para cualquier proyecto en Xcode.

El pasado año, con la llegada de Swift 5.1, SPM llegó a Xcode 11 pero había una pega: solo aceptaba APIs (librerías) que fueran 100% código fuente. No podían tener recursos binarios, ni localización y mucho menos (aquí el quid de la cuestión), librerías binarias. Como todos sabemos, Firebase está precompilado y se distribuye como librería binaria, así que no podíamos usar SPM para usar Firebase.

Di no a CocoaPods… vive un mundo libre de ataduras de dependencias, conflictos y errores aleatorios sin sentido.

Esto, por fortuna, ha cambiado este año con la llegada de Swift 5.3 y Xcode 12. Ahora SPM sí soporta recursos binarios (imágenes, ficheros de cualquier tipo e incluso .storyboards), soporta localizar estos recursos y, lo más importante, también librerías en formato binario ya compiladas. Librerías que pueden proceder de cualquier lenguaje compatible como C, C++ u Objective-C, y que deben estar en un formato que sea entendible por el compilador LLVM para incluirlas como dependencias binarias en nuestros proyectos.

Por este motivo, ahora ya podemos incluir Firebase en Swift Package Manager. Siempre, obviamente, contando con que Google ha creado la conveniente recopilación de repositorios de código y fuentes binarias para cada uno de los componentes de este enorme servicio de APIs de Google.

¿Cómo instalamos Firebase con SPM?

La instalación es bastante simple, y solo tiene un paso «extraño» que nos obligará a tocar una línea de las opciones en los Build Setiings del proyecto. Pero nada que nos quite el sueño (menos que CocoaPods, seguro).

La única pega de usar SPM con Firebase, es que (por ahora) tenemos que modificar un parámetro en los Build Settings si usamos la API de analíticas. Pero nada que sea traumático.

Lo primero es que no vamos a repetir cómo configurar tu proyecto y bajarte el fichero de configuración correspondiente: puedes consultar este paso en el anterior tutorial, que te volvemos a referenciar aquí: pulsar para ver el tutorial.

Si vamos a la página de configuración de los proyectos iOS en Firebase (la versión en inglés) nos indica que disponen de soporte en beta para Swift Package Manager. Allí nos manda directamente a la documentación en GitHub, donde nos informa que desde la versión 6.31.0 podemos usar SPM para Firebase, siempre a partir de Xcode 12 beta 4. Si queremos usarlo con SwiftUI, deberá ser la beta 5.

Por desgracia en esta primera beta tenemos algunas limitaciones, como la necesidad de configurar las opciones del enlazador del compilador si queremos usar Analytics, el no soporte de proyectos watchOS o la no inclusión (todavía) de las librerías Messaging, Performance, Firebase ML y App Distribution.

Si nuestro proyecto usaba previamente CocoaPods, deberemos quitarlo usando el comando: pod deintegrate. Si sentís una sensación de placer lujurioso al hacerlo, es normal, no os preocupéis.

Menú File, Swift Packages, Add Package Dependency.

Una vez hecho, nos vamos a las opciones del proyecto Xcode y allí a Swift Packages, para luego pulsar el +. También podemos hacerlo en el menú File, Swift Packages, Add Package Dependency.

En el diálogo emergente que aparecerá ponemos: https://github.com/firebase/firebase-ios-sdk.git.

Accedemos a la URL donde está todo el repositorio de Firebase para luego elegir las dependencias de la misma que queremos.

Lo siguiente que nos pedirá es la versión del branch del queremos extraer la versión. En este caso, hasta que no salga la versión final de Xcode, tendremos que usar el branch beta: 6.31-spm-beta.

Hay que usar el branch 6.31-spm-beta.

Hecho esto, veremos un listado de todas las librerías que podemos instalar y nos pedirá que seleccionemos (en caso de haber más de uno) sobre qué target queremos instalar la dependencia.

Listado de las diferentes APIs de Firebase que podemos instalar.

Como ya hemos comentado, poco más hay que hacer. Eso sí, si vamos a usar la librería FirebaseAnalytics, deberemos poner el flag del enlazador del compilador, como cuando se instalaba manualmente la librería. Pulsamos en Build Settings, buscamos other, vamos a Other Linker Flags y añadimos -ObjC (tal cual, respetando mayúsculas y minúsculas).

Configuración de Build Settings para poner el indicador Other Linker Flags.

No hay nada más. Ya tenemos Firebase listo para usar en Xcode 12 beta con Swift Package Manager y podemos importar sus librerías. Y no os preocupéis, cuando esté disponible la versión final actualizaremos este tutorial con el proceso final.

Quiero usar Firebase con SwiftUI 2 pero, ¿dónde está mi AppDelegate?

Si hemos creado un proyecto con SwiftUI 2, usando el nuevo ciclo de vida de apps para Swift de iOS 14, veremos que ya no existen los ficheros AppDelegate.swift y SceneDelegate.swift. Estos han desaparecido y ahora solo tenemos un nuevo fichero que se llame igual que nuestro proyecto, pero acabado en App.

En él, nos encontramos con el siguiente código:

import SwiftUI

@main
struct demodemodemoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

El comando @main nos indica que ese es el punto de inicio de la app. En él, tenemos un struct que se conforma con el protocolo App, que también nos dice que esa es nuestra app: su punto de entrada. En ella hay una escena directamente sobre body (una some Scene) y dentro un grupo de ventanas que llaman al struct ContentView, que es donde tenemos la primera pantalla a mostrar.

Pero no hay AppDelegate ni nada parecido. Ha desaparecido. Así que si queremos ejecutar algo que se lance antes que el arranque de la app (como la configuración de Firebase) tenemos un problema.

Para subsanarlo nada más fácil que crear nosotros ese AppDelegate y asociarlo en nuestro struct conformado con App.

final class AppDelegate:NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

        return true
    }
}

Básicamente, lo que estamos haciendo es crear una clase de tipo NSObject (la clase de jerarquía más alta de Objective-C, y el padre de todas las clases de Cocoa Touch, por lo que es necesario que sea de ese tipo para poder decirle luego que se conforme a la interfaz UIApplicationDelegate). Una vez hecho, ya podemos incluir nuestra función didFinishLaunchingWithOptions que tanto echábamos de menos. Una función que devuelva true y donde incluir el famoso FirebaseApp.configure(), siempre sin olvidar importar la librería en el fichero (obviamente).

Pero no acaba aquí el cambio: ahora hay que asociarlo a nuestra app. Para ello hemos de añadir un property wrapper nuevo dentro del struct de tipo App. Llamado @UIApplicationDelegateAdaptor al que pasarle el tipo de la clase AppDelegate que hemos creado.

@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

Listo. Hemos creado el adaptador que conecta el ciclo de vida nuevo con un AppDelegate que nos permitirá inicializar Firebase, donde también podremos poner (por ejemplo) el control de las notificaciones que tengamos en la app o las entradas a través de llamadas por enlaces profundos (por citar algunos ejemplos).

Poco más, espero que le saques buen provecho a este tutorial y si tienes alguna sugerencia de algo que quieras que tratemos aquí, solo dínoslo en los comentarios o en nuestro twitter, @apple_coding. Un saludo y Good Apple Coding.

Julio César Fernández

Analista, consultor y periodista tecnológico, desarrollador, empresario, productor audiovisual, actor de doblaje e ingeniero de vídeo y audio.

Artículos relacionados

Botón volver arriba