Saltar al contenido

Lección 17 de 20 · Lectura y práctica

Implementar funcionalidades clave con Expo APIs

Concepto claveLas Expo APIs son interfaces preconstruidas que exponen funcionalidades nativas del dispositivo a través de JavaScript, permitiendo acceder a hardware y servicios del sistema operativo sin necesidad de código.

Del concepto a la práctica

Taller de esta lección

Una API de Expo debe incorporarse porque satisface un requisito concreto. Para recordatorios, el requisito es avisar localmente de una tarea futura; la lógica de vencimiento y el texto siguen perteneciendo al dominio de la aplicación.

Ejemplo resuelto

La tarea t8 vence a las 18:00. La aplicación valida que el título no esté vacío, solicita permiso de notificaciones al activar recordatorios y programa un aviso y guarda el identificador devuelto por scheduleNotificationAsync asociado a la tarea t8. El identificador de tarea y el de notificación son conceptos distintos, aunque los relaciones en tu almacenamiento. Si el permiso se deniega, conserva la tarea y marca el recordatorio como inactivo. La pantalla no elimina la tarea por un fallo de la API.

Pruébalo

  1. Define el requisito que justifica la API.

  2. Valida la tarea antes de programar nada.

  3. Simula permiso concedido y denegado.

  4. Busca el identificador de notificación asociado a t8 y pásalo a cancelScheduledNotificationAsync. Comprueba la lista de avisos programados, además de observar la interfaz.

Error frecuente: programar notificaciones dentro del renderizado. Corrígelo ejecutando la acción tras una decisión explícita y guardando el identificador para poder cancelar.

Comprueba tu resultado

t8 debe conservarse en ambos escenarios; solo con permiso concedido aparece un aviso programado y el identificador devuelto por la API permite cancelarlo. Programar un aviso no garantiza que se muestre: revisa permisos, comportamiento en primer plano y la prueba de dispositivo conforme al SDK utilizado.

Diagrama de decisión con ramas Sí y No y un bucle que procesa cada elemento de una lista.
CursaloMapa de práctica
Cómo avanza un programa

Una condición decide qué camino ejecuta el programa. Un bucle repite una operación mientras queden elementos, y termina cuando la lista se agota. Separar ambas ideas ayuda a seguir el flujo y comprobar casos límite.

Ver la infografía en tamaño completo ↗

Concepto clave

Las Expo APIs son interfaces preconstruidas que exponen funcionalidades nativas del dispositivo a través de JavaScript, permitiendo acceder a hardware y servicios del sistema operativo sin necesidad de código nativo. Piensa en ellas como un conjunto de herramientas estandarizadas que te permiten interactuar con la cámara, notificaciones push, almacenamiento local y otros recursos del dispositivo de forma consistente entre iOS y Android.

En el desarrollo de aplicaciones de productividad, estas APIs son fundamentales para crear experiencias ricas y funcionales. Por ejemplo, una aplicación de tareas podría usar Expo Notifications para recordatorios, Expo FileSystem para guardar documentos localmente, y Expo SQLite para almacenamiento estructurado. La analogía sería como tener un kit de herramientas de taller completo: cada API es una herramienta específica (martillo, destornillador, llave) que realiza una función precisa sin que tengas que fabricarla desde cero.

Cómo funciona en la práctica

Para implementar funcionalidades clave en nuestra aplicación de productividad, seguimos un flujo estructurado. Primero, identificamos qué APIs de Expo necesitamos basándonos en los requisitos de la funcionalidad. Segundo, instalamos los paquetes necesarios usando npx expo install. Tercero, configuramos los permisos requeridos en el archivo app.json. Cuarto, implementamos la lógica de la API en nuestro código, manejando adecuadamente los estados de carga y error.

Veamos un ejemplo concreto: implementar notificaciones locales para recordatorios de tareas. El proceso paso a paso sería: 1) Instalar expo-notifications, 2) Configurar permisos en app.json, 3) Solicitar permisos al usuario al iniciar la app, 4) Programar notificaciones cuando se crea una tarea con fecha límite, 5) Manejar la interacción del usuario con las notificaciones.

Código en acción

Implementemos un sistema de notificaciones para nuestra app de productividad. Primero, el código básico para solicitar permisos y programar una notificación:

import * as Notifications from 'expo-notifications';
import * as Device from 'expo-device';
import { Platform } from 'react-native';

// Configurar el manejo de notificaciones
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: true,
  }),
});

// Función para solicitar permisos
async function solicitarPermisosNotificaciones() {
  if (Device.isDevice) {
    const { status: statusExistente } = await Notifications.getPermissionsAsync();
    let statusFinal = statusExistente;
    
    if (statusExistente !== 'granted') {
      const { status } = await Notifications.requestPermissionsAsync();
      statusFinal = status;
    }
    
    if (statusFinal !== 'granted') {
      alert('Se necesitan permisos para enviar notificaciones');
      return false;
    }
    
    // En Android, necesitamos configurar el canal de notificaciones
    if (Platform.OS === 'android') {
      await Notifications.setNotificationChannelAsync('recordatorios', {
        name: 'Recordatorios de tareas',
        importance: Notifications.AndroidImportance.HIGH,
        vibrationPattern: [0, 250, 250, 250],
        lightColor: '#FF231F7C',
      });
    }
    
    return true;
  } else {
    alert('Debes usar un dispositivo físico para notificaciones');
    return false;
  }
}

// Función para programar una notificación
async function programarNotificacion(titulo, cuerpo, fecha) {
  const permisosOtorgados = await solicitarPermisosNotificaciones();
  
  if (!permisosOtorgados) {
    return null;
  }
  
  const identificador = await Notifications.scheduleNotificationAsync({
    content: {
      title: titulo,
      body: cuerpo,
      data: { tipo: 'recordatorio_tarea' },
      sound: 'default',
    },
    trigger: {
      date: fecha, // Fecha y hora específica
    },
  });
  
  return identificador;
}

Ahora, mejoremos este código agregando manejo de errores y cancelación de notificaciones:

// Versión mejorada con manejo de errores
async function programarNotificacionMejorada(titulo, cuerpo, fecha) {
  try {
    const permisosOtorgados = await solicitarPermisosNotificaciones();
    
    if (!permisosOtorgados) {
      throw new Error('Permisos de notificación no otorgados');
    }
    
    // Validar que la fecha sea futura
    if (fecha <= new Date()) {
      throw new Error('La fecha de la notificación debe ser futura');
    }
    
    const identificador = await Notifications.scheduleNotificationAsync({
      content: {
        title: titulo || 'Recordatorio',
        body: cuerpo || 'Tienes una tarea pendiente',
        data: { 
          tipo: 'recordatorio_tarea',
          timestamp: Date.now()
        },
        sound: 'default',
        priority: Notifications.AndroidNotificationPriority.HIGH,
      },
      trigger: {
        date: fecha,
      },
    });
    
    console.log(`Notificación programada con ID: ${identificador}`);
    return identificador;
    
  } catch (error) {
    console.error('Error al programar notificación:', error.message);
    // Podríamos registrar este error en un servicio de analytics
    return null;
  }
}

// Función para cancelar una notificación
async function cancelarNotificacion(identificador) {
  if (!identificador) return;
  
  try {
    await Notifications.cancelScheduledNotificationAsync(identificador);
    console.log(`Notificación ${identificador} cancelada`);
  } catch (error) {
    console.error('Error al cancelar notificación:', error);
  }
}

Errores comunes

  • No verificar permisos antes de usar la API: Intentar usar Notifications sin haber solicitado permisos primero causará errores silenciosos. Siempre verifica el estado de permisos y solicítalos si es necesario.
  • Olvidar configurar canales en Android: En Android 8+, las notificaciones requieren canales configurados. Sin esto, las notificaciones no se mostrarán correctamente.
  • No manejar el estado "no es un dispositivo": En simuladores o emuladores, algunas APIs no funcionan. Siempre verifica con Device.isDevice antes de usar APIs de hardware.
  • Programar notificaciones con fechas pasadas: Esto puede causar comportamientos inesperados. Siempre valida que la fecha del trigger sea futura.
  • No limpiar notificaciones canceladas: Si permites a los usuarios eliminar tareas, asegúrate de cancelar también sus notificaciones programadas para evitar notificaciones huérfanas.

Checklist de dominio

  1. Puedo explicar la diferencia entre Expo APIs y APIs nativas de React Native
  2. He implementado al menos 3 APIs diferentes de Expo en un proyecto real
  3. Sé cómo manejar permisos de usuario para diferentes APIs (notificaciones, cámara, ubicación)
  4. Puedo debuggear problemas comunes de APIs de Expo usando logs y la documentación oficial
  5. He implementado manejo de errores robusto para fallos de APIs
  6. Sé cómo optimizar el uso de APIs para mejor rendimiento (lazy loading, cleanup)
  7. Puedo integrar múltiples APIs de Expo que interactúen entre sí en una funcionalidad compleja

Implementar sistema completo de recordatorios con Expo APIs

En este ejercicio, implementarás un sistema completo de recordatorios para la aplicación de productividad usando múltiples APIs de Expo. Sigue estos pasos:

  1. Configuración inicial: Crea un nuevo componente RecordatoriosManager.js en tu proyecto. Instala las dependencias necesarias: expo-notifications, expo-device, y expo-calendar si quieres integración con calendario nativo.
  2. Implementa el núcleo: Crea una función programarRecordatorio que acepte título, descripción, fecha y repetición (diaria, semanal, ninguna). Usa expo-notifications para programar la notificación. Para repeticiones, investiga el trigger calendar en la documentación.
  3. Agrega persistencia: Usa expo-sqlite para guardar los recordatorios programados en una base de datos local. Crea una tabla con campos: id, título, descripción, fecha_programada, repetir, notificacion_id.
  4. Implementa UI: Crea una pantalla donde los usuarios puedan ver todos sus recordatorios programados, con opción de editar o eliminar. Al eliminar un recordatorio, también cancela la notificación correspondiente.
  5. Agrega características avanzadas: Implementa una función que verifique al iniciar la app si hay recordatorios pasados que no se ejecutaron (por ejemplo, si la app estaba cerrada) y los reprograma para el próximo intervalo válido.
  6. Testing: Prueba tu implementación en dispositivo físico, verificando que las notificaciones se muestran correctamente y que la persistencia funciona después de reiniciar la app.
Pistas
  • Usa async/await consistentemente para manejar las operaciones asíncronas de las APIs
  • Para las repeticiones, considera usar cron expressions o la API de calendar triggers de expo-notifications
  • No olvides limpiar los listeners de notificaciones en el cleanup de useEffect

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con Desarrollo Avanzado de Aplicaciones con Expo: De Concepto a Producción

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.