Primeros pasos con Share Target
Esta guía lo guiará a través de la integración del complemento Capacitor Share Target para permitir que su aplicación reciba contenido compartido de otras aplicaciones.
Instalación
Section titled “Instalación”Instale el complemento usando npm:
npm install @capgo/capacitor-share-targetnpx cap syncAndroid Configuración
Section titled “Android Configuración”Add intent filters to your AndroidManifest.xml inside the <activity> tag:
Aceptar contenido de texto
Section titled “Aceptar contenido de texto”<intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/*" /></intent-filter>Aceptar imágenes
Section titled “Aceptar imágenes”<intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /></intent-filter>
<intent-filter> <action android:name="android.intent.action.SEND_MULTIPLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /></intent-filter>Aceptar todos los tipos de contenido
Section titled “Aceptar todos los tipos de contenido”<intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="*/*" /></intent-filter>
<intent-filter> <action android:name="android.intent.action.SEND_MULTIPLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="*/*" /></intent-filter>iOS Configuración
Section titled “iOS Configuración”For iOS, you need to create a Share Extension:
1. Crear extensión para compartir en Xcode
Section titled “1. Crear extensión para compartir en Xcode”- Abra su proyecto en Xcode
- Vaya a Archivo > Nuevo > Destino
- Seleccione Compartir extensión y haga clic en Siguiente
- Name it (e.g., “ShareExtension”) and click Finish
- Si se le solicita, active el esquema.
2. Configurar grupo de aplicaciones
Section titled “2. Configurar grupo de aplicaciones”- In your main app target, go to Signing & Capabilities
- Haga clic en + Capacidad y agregue Grupos de aplicaciones
- Create or select an app group (e.g.,
group.com.yourcompany.yourapp) - Repita para el objetivo de Share Extension
3. Actualizar el código de extensión para compartir
Section titled “3. Actualizar el código de extensión para compartir”The Share Extension needs to save shared data to the app group container so your main app can access it.
For detailed iOS setup, see Apple’s Share Extension documentation.
Uso básico
Section titled “Uso básico”Importar el complemento
Section titled “Importar el complemento”import { CapacitorShareTarget } from '@capgo/capacitor-share-target';Escuche el contenido compartido
Section titled “Escuche el contenido compartido”CapacitorShareTarget.addListener('shareReceived', (event) => { console.log('Received share event'); console.log('Title:', event.title); console.log('Texts:', event.texts);
// Handle shared files if (event.files && event.files.length > 0) { event.files.forEach(file => { console.log(`File: ${file.name}`); console.log(`Type: ${file.mimeType}`); console.log(`URI: ${file.uri}`); }); }});Ejemplo completo
Section titled “Ejemplo completo”Here’s a comprehensive example handling different types of shared content:
import { CapacitorShareTarget } from '@capgo/capacitor-share-target';
class ShareTargetService { private listener: any;
initialize() { this.listener = CapacitorShareTarget.addListener('shareReceived', (event) => { this.handleSharedContent(event); });
console.log('Share target listener initialized'); }
handleSharedContent(event: any) { console.log('=== Share Received ===');
// Handle title if (event.title) { console.log('Title:', event.title); this.showNotification('Shared: ' + event.title); }
// Handle text content if (event.texts && event.texts.length > 0) { event.texts.forEach((text: string, index: number) => { console.log(`Text ${index + 1}:`, text); this.processSharedText(text); }); }
// Handle files if (event.files && event.files.length > 0) { console.log(`Received ${event.files.length} file(s)`);
event.files.forEach((file: any) => { console.log('File details:'); console.log(' Name:', file.name); console.log(' Type:', file.mimeType); console.log(' URI:', file.uri);
this.processSharedFile(file); }); } }
processSharedText(text: string) { // Check if it's a URL if (this.isURL(text)) { console.log('Shared URL detected:', text); // Handle URL (e.g., create bookmark) this.saveBookmark(text); } else { console.log('Shared text detected'); // Handle plain text (e.g., create note) this.createNote(text); } }
processSharedFile(file: any) { const fileType = file.mimeType.split('/')[0];
switch (fileType) { case 'image': console.log('Processing shared image'); this.handleImage(file); break;
case 'video': console.log('Processing shared video'); this.handleVideo(file); break;
case 'audio': console.log('Processing shared audio'); this.handleAudio(file); break;
case 'application': console.log('Processing shared document'); this.handleDocument(file); break;
default: console.log('Processing generic file'); this.handleGenericFile(file); } }
handleImage(file: any) { // Process image file console.log('Saving image:', file.name); // Implementation: Save to gallery, upload, etc. }
handleVideo(file: any) { // Process video file console.log('Saving video:', file.name); }
handleAudio(file: any) { // Process audio file console.log('Saving audio:', file.name); }
handleDocument(file: any) { // Process document file console.log('Saving document:', file.name); }
handleGenericFile(file: any) { // Process generic file console.log('Saving file:', file.name); }
isURL(text: string): boolean { try { new URL(text); return true; } catch { return false; } }
saveBookmark(url: string) { console.log('Creating bookmark for:', url); // Implementation }
createNote(text: string) { console.log('Creating note with text:', text.substring(0, 50)); // Implementation }
showNotification(message: string) { console.log('Notification:', message); // Show toast or notification }
cleanup() { if (this.listener) { this.listener.remove(); } }}
// Usageconst shareTarget = new ShareTargetService();shareTarget.initialize();
// Cleanup when app closes// shareTarget.cleanup();Integración de reacción
Section titled “Integración de reacción”import { useEffect } from 'react';import { CapacitorShareTarget } from '@capgo/capacitor-share-target';
function useShareTarget(onShareReceived: (event: any) => void) { useEffect(() => { const listener = CapacitorShareTarget.addListener('shareReceived', onShareReceived);
return () => { listener.remove(); }; }, [onShareReceived]);}
// Usage in componentfunction App() { useShareTarget((event) => { console.log('Share received:', event); // Handle shared content });
return <div>Your App</div>;}Integración de Vue
Section titled “Integración de Vue”import { onMounted, onUnmounted } from 'vue';import { CapacitorShareTarget } from '@capgo/capacitor-share-target';
export default { setup() { let listener: any;
onMounted(() => { listener = CapacitorShareTarget.addListener('shareReceived', (event) => { console.log('Share received:', event); // Handle shared content }); });
onUnmounted(() => { if (listener) { listener.remove(); } }); }};Manejo de diferentes tipos de contenido
Section titled “Manejo de diferentes tipos de contenido”if (event.texts && event.texts.length > 0) { const text = event.texts[0];
if (text.startsWith('http://') || text.startsWith('https://')) { // Handle URL window.open(text, '_blank'); }}Imágenes
Section titled “Imágenes”if (event.files) { const images = event.files.filter(f => f.mimeType.startsWith('image/'));
images.forEach(async (image) => { // Read and display image const response = await fetch(image.uri); const blob = await response.blob(); const imageUrl = URL.createObjectURL(blob);
// Display or process image console.log('Image URL:', imageUrl); });}Múltiples archivos
Section titled “Múltiples archivos”if (event.files && event.files.length > 1) { console.log(`Processing ${event.files.length} files`);
const processPromises = event.files.map(file => processFile(file) );
await Promise.all(processPromises); console.log('All files processed');}Mejores prácticas
Section titled “Mejores prácticas”- Handle Multiple Content Types: Be prepared to receive text, URLs, and files
- Validate Content: Check MIME types before processing
- Provide Feedback: Show users what was received
- Handle Errors: File URIs might be invalid or inaccessible
- Clean Up Listeners: Remove listeners when not needed
- Test Thoroughly: Test with different apps and content types
- Request Permissions: Some file types may require additional permissions
Problemas comunes
Section titled “Problemas comunes”Compartir no funciona en Android
Section titled “Compartir no funciona en Android”Ensure intent filters are correctly configured in AndroidManifest.xml within the <activity> tag that has android.intent.action.MAIN.
iOS Share Extension Not Appearing
Section titled “iOS Share Extension Not Appearing”- Verify App Group is configured in both targets
- Asegúrese de que Share Extension esté activado
- Check that Info.plist in Share Extension has correct configuration
Errores de acceso a archivos
Section titled “Errores de acceso a archivos”try { const response = await fetch(file.uri); const blob = await response.blob(); // Process blob} catch (error) { console.error('Failed to access file:', error); // Show error to user}Próximos pasos
Section titled “Próximos pasos”- Explore the API Reference for complete method documentation
- Check out the example app for advanced usage
- See the tutorial for complete implementation examples