April 10, 2024

Deep linking con React Native

Guía básica para aceptar Deep Linking en tu app creada con React Native y react-native-navigation

Esta guía solo es para aplicaciones creadas con el CLI React Native sin usar Expo, es decir para código nativo. Después verán que prácticamente no se menciona react-native-navigation, debido a que no hay algo desarrollado por parte de la librería para manejar Deep Linking. Más adelante verán que la interfaz de Linking que viene con React Native es suficiente para lograr lo que queremos. Se hace énfasis en la librería para dejar claro como sería la solución si se hace uso de ella, ya que esto no se menciona en la documentación.

Por otro lado esta guía nace de la necesidad de autorizar una aplicación con Uber a través de su API. Una vez que el usuario ingresa sus credenciales en la página web de Uber o realiza la autorización desde la aplicación de Uber, el flujo de autorización se encarga de llamar a una URL de redirección en donde Uber nos mandará el token de acceso del usuario que nos permitirá realizar llamadas al APIcon privilegios.

Una vez que creas una aplicación en el Dashboard de desarrolladores de Uber es necesario configurar toda la información de nuestra aplicación siguiendo la documentación de Uber pero sobre todo se tiene que prestar bastante atención al parámetro URI de redirección el cual debe seguir el siguiente formato: esquema://recurso

En donde el esquema será el Bundle Identifier de nuestra aplicación iOS y el recurso será el path que quereamos otorgale para identificar la redirección de autorización. Mi configuración queda de la siguiente manera: io.tello.UberAPI://uber

Una vez configurado lo anterior se tienen que hacer los siguientes cambios en Xcode:
// AppDelegate.m
#import <React/RCTLinkingManager.h>
// Los otros imports van aquí

@implementation AppDelegate

// Aquí va el código restante del archivo

// Esto solo funciona para iOS > 9
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
    return [RCTLinkingManager application:application openURL:url options:options];
}

@end

// Info.plist

// Asegúrate de no borrar los demás valores
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>io.tello.UberAPI://uber</string>
        </array>
    </dict>
</array>
<key>CFBundleVersion</key>
Una vez teniendo todo lo anterior lo único que falta es modificar nuestro archivo de entrada que normalmente es App.js, en el se tiene que agregar un EventListener que la interfaz de Linkingexpone. Esto quedará de la siguiente manera:
// App.js
import React, { PureComponent } from 'react'
import { Linking, Text } from 'react-native'

class App extends PureComponent {
  componentDidMount() {
    Linking.addEventListener('url', this._handleOpenURL)

  }

  componentWillUnmount() {
    Linking.removeEventListener('url', this._handleOpenURL)
  }

  _handleOpenURL = async (event) => {
    if (event && event.url) {
      console.log(event.url)
        // Aquí pondrás la lógica para hacer push a la pantalla correcta con react-native-navigation
    }
  }

  render () {
    return (
        <Text>Hello Tello</Text>
    )
  }
}
Por último la prueba final será correr nuestra aplicación con react-native run-ios, abrir Safari e ir directamente a la URL que anteriormente especificamos: io.tello.UberAPI://uber