Después de implementar widgets en mi último proyecto de React Native con Expo, decidí compartir mi experiencia. 🚀 Los widgets transforman tu app de un simple ícono a una experiencia realmente útil, mostrando información clave directamente en la pantalla de inicio.
En este tutorial, te mostraré los pasos clave para crear widgets para dispositivos iOS usando react-native-shared-group-preferences, la librería que simplifica todo el proceso. ¡Vamos a codear! 💡
🔥 ¿Para qué servirá?
✅ Puedes ver tus próximas tareas sin abrir la app.
✅ Se actualiza automáticamente con la info más reciente.
✅ Es rápido, práctico y queda increíble en la pantalla de inicio.
Paso 1: Crear tu app de React Native con Expo
Note
Si ya tienes creada tu aplicación de React Native con Expo, omite este paso.
- Instala la CLI de Expo (si aún no la tienes):
npm install --global expo-cli
Esta herramienta te permitirá crear y administrar proyectos de Expo fácilmente.
- Crea un nuevo proyecto con Expo:
expo init MyNewApp
Elige la plantilla que más te guste (por ejemplo, la “blank”) y espera a que se instalen todas las dependencias.
- Navega dentro de la carpeta del proyecto y ejecuta tu app:
cd MyNewApp
expo start
Se abrirá la interfaz de Expo en tu navegador. Desde ahí, puedes escanear el código QR con la app de Expo Go en tu dispositivo o ejecutar la aplicación en un emulador.
- ¡Listo! Ya tienes una app de React Native con Expo corriendo. Siéntete libre de hacer un “Hello World” para comprobar que todo está en orden.
Paso 2: Preparando tu proyecto para widgets en iOS
Si estás usando Expo o necesitas generar la carpeta de iOS desde cero, npx expo prebuild
es tu mejor amigo. Este comando no solo crea la carpeta ./ios
, sino que también configura todos los archivos nativos necesarios con la magia de Expo.
# Ejecuta este comando en la raíz de tu proyecto
npx expo prebuild --platform ios
Note
prebuild
regenerará completamente tu carpetaios
, así que si tienes configuraciones personalizadas, deberás readaptarlas después.
Paso 3: Instalar react-native-shared-group-preferences
Luego, instala la librería que nos permitirá compartir datos entre nuestra aplicación React Native y el widget iOS:
npm install react-native-shared-group-preferences --save
# o con yarn
yarn add react-native-shared-group-preferences
Después, instala los pods necesarios:
cd ios && pod install
# o
npx pod-install
Note
Después de instalar cualquier librería de npm se debe ejecutarpod install
.
Paso 4: Configurar App Groups en Xcode
1. Abre tu proyecto en Xcode (`ios/TuProyecto.xcworkspace`).
2. Selecciona tu proyecto en el navegador de proyectos.
3. Selecciona la pestaña **Signing & Capabilities**.
4. Haz clic en el botón **+** para añadir una nueva capacidad.
5. Añade **App Groups**.
6. Crea un nuevo grupo con el formato `group.com.tudominio.tuapp`.
7. Asegúrate de que tu App ID tiene habilitada esta capacidad en el portal de desarrolladores de Apple.
Paso 5: Crear una extensión de widget en Xcode
1. En Xcode, ve a **File > New > Target**.
2. Selecciona **Widget Extension** de la sección "iOS".
3. Nombra tu widget (por ejemplo, **MyAppWidget**).
4. Selecciona **Include Configuration Intent** si deseas que tu widget sea configurable.
5. Asegúrate de que **Group** esté configurado para el mismo App Group que configuraste previamente.
Paso 6: Configurar tu widget en Swift
Note
Al crear un widget con Xcode, se generan diferentes archivos swift dentro de la carpeta ./ios/MyAppWidget, para simplificar la guía solo vamos dejar el archivo MyAppWidget.swift
Modifica el archivo MyAppWidget.swift
(anteriormente MyAppWidget.swift
) generado:
import WidgetKit
import SwiftUI
struct Reminder: Codable, Identifiable {
var id: Int
var name: String
}
struct ReminderWidgetEntry: TimelineEntry {
let date: Date
let reminders: [Reminder]
}
struct ReminderWidgetProvider: TimelineProvider {
func placeholder(in context: Context) -> ReminderWidgetEntry {
ReminderWidgetEntry(date: Date(), reminders: [Reminder(id: 0, name: "Sample Reminder")])
}
func getSnapshot(in context: Context, completion: @escaping (ReminderWidgetEntry) -> ()) {
let entry = ReminderWidgetEntry(date: Date(), reminders: loadReminders())
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<ReminderWidgetEntry>) -> ()) {
let entry = ReminderWidgetEntry(date: Date(), reminders: loadReminders())
let timeline = Timeline(entries: [entry], policy: .after(Date().addingTimeInterval(900)))
completion(timeline)
}
func loadReminders() -> [Reminder] {
let sharedDefaults = UserDefaults(suiteName: "group.com.tudominio.tuapp")
if let jsonString = sharedDefaults?.string(forKey: "reminders"),
let data = jsonString.data(using: .utf8),
let reminders = try? JSONDecoder().decode([Reminder].self, from: data) {
return reminders
}
return []
}
}
struct MyAppWidgetEntryView: View {
var entry: ReminderWidgetProvider.Entry
var body: some View {
VStack(alignment: .leading) {
Text("My Reminders")
.font(.headline)
if entry.reminders.isEmpty {
Text("No reminders")
.font(.caption)
} else {
ForEach(entry.reminders) { reminder in
Text(reminder.name)
.font(.body)
.lineLimit(1)
}
}
}
.padding()
}
}
@main
struct MyAppWidget: Widget {
let kind: String = "MyAppWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: ReminderWidgetProvider()) { entry in
MyAppWidgetEntryView(entry: entry)
}
.configurationDisplayName("Widget Reminder Calendar")
.description("Displays a list of your reminders.")
}
}
struct MyAppWidget_Previews: PreviewProvider {
static var previews: some View {
let entry = ReminderWidgetEntry(date: Date(), reminders: [
Reminder(id: 1, name: "Reminder A"),
Reminder(id: 2, name: "Reminder B"),
Reminder(id: 3, name: "Reminder C")
])
MyAppWidgetEntryView(entry: entry)
.previewContext(WidgetPreviewContext(family: .systemMedium))
}
}
Paso 7: Compartir datos desde React Native
Ahora, modifica tu aplicación React Native para compartir datos con el widget:
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import SharedGroupPreferences from 'react-native-shared-group-preferences';
const APP_GROUP_IDENTIFIER = 'group.com.tudominio.tuapp';
export default function UpdateWidget() {
const updateWidgetData = async () => {
const data = [
{ id: 1, name: 'Reminder A' },
{ id: 2, name: 'Reminder B' },
];
await SharedGroupPreferences.setItem(
'reminders',
JSON.stringify(data),
APP_GROUP_IDENTIFIER
);
};
return (
<View style={styles.container}>
<Text style={styles.title}>Update Widget</Text>
<Button
title="Update Widget Now"
onPress={updateWidgetData}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
},
title: {
fontSize: 18,
marginBottom: 8
}
});
Paso 8: Ejecutar en emulador 🚀
- En Xcode, en la pestaña superior selecciona el Target principal y el emulador del dispositivo.
- En Xcode, ve a Product > Run.
- ¡Listo! Si no tuviste errores, deberías poder agregar un widget con los datos sincronizados de tu aplicación como en la siguiente imagen:
Conclusión
¿Listo para darle un superpoder a tu app? 🚀 Los widgets te simplifican la vida y te muestran información esencial sin tener que abrir la aplicación. Con React Native y react-native-shared-group-preferences
, convertir tu app en una experiencia de pantalla de inicio es más fácil de lo que imaginas.
Sí, tendrás que ensuciarte un poco con Swift, pero el resultado final vale cada línea de código.
A codear ese widget!🔥🔥
Si tienes dudas, no dudes en preguntar 🤘
Top comments (0)