Getting Started with Contacts
Este contenido aún no está disponible en tu idioma.
This guide will walk you through integrating the Capacitor Contacts plugin into your application.
Installation
Install the plugin using npm:
npm install @capgo/capacitor-contactsnpx cap synciOS Configuration
Add the following to your Info.plist:
<key>NSContactsUsageDescription</key><string>This app needs access to contacts to let you select recipients</string>Android Configuration
Add the following permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_CONTACTS" /><uses-permission android:name="android.permission.WRITE_CONTACTS" />Basic Usage
Import the Plugin
import { Contacts } from '@capgo/capacitor-contacts';Request Permissions
const requestPermissions = async () => { const permission = await Contacts.requestPermissions(); console.log('Permission status:', permission.contacts);};Get All Contacts
const getAllContacts = async () => { const result = await Contacts.getContacts({ projection: { name: true, phones: true, emails: true, image: true } });
console.log('Contacts:', result.contacts);};Search Contacts
const searchContacts = async (query: string) => { const result = await Contacts.getContacts({ projection: { name: true, phones: true, emails: true }, query: query });
console.log('Search results:', result.contacts);};Create Contact
const createContact = async () => { const newContact = { name: { given: 'John', family: 'Doe' }, phones: [{ type: 'mobile', number: '+1234567890' }], emails: [{ type: 'work', address: 'john.doe@example.com' }] };
const result = await Contacts.createContact(newContact); console.log('Contact created:', result);};Update Contact
const updateContact = async (contactId: string) => { const updates = { contactId: contactId, name: { given: 'Jane', family: 'Doe' } };
await Contacts.updateContact(updates); console.log('Contact updated');};Delete Contact
const deleteContact = async (contactId: string) => { await Contacts.deleteContact({ contactId }); console.log('Contact deleted');};Complete Example
Here’s a complete example with a contact service:
import { Contacts } from '@capgo/capacitor-contacts';
interface Contact { contactId: string; name: { display?: string; given?: string; family?: string; }; phones?: Array<{ type: string; number: string }>; emails?: Array<{ type: string; address: string }>; image?: { base64String: string };}
class ContactsService { async checkPermissions(): Promise<boolean> { const permission = await Contacts.checkPermissions();
if (permission.contacts === 'granted') { return true; }
const requested = await Contacts.requestPermissions(); return requested.contacts === 'granted'; }
async getAllContacts(): Promise<Contact[]> { const hasPermission = await this.checkPermissions(); if (!hasPermission) { throw new Error('Contacts permission denied'); }
const result = await Contacts.getContacts({ projection: { name: true, phones: true, emails: true, image: true } });
return result.contacts; }
async searchContacts(query: string): Promise<Contact[]> { if (!query || query.length < 2) { return []; }
const result = await Contacts.getContacts({ projection: { name: true, phones: true, emails: true }, query: query });
return result.contacts; }
async getContactById(contactId: string): Promise<Contact | null> { const result = await Contacts.getContacts({ projection: { name: true, phones: true, emails: true, image: true, organization: true, birthday: true, note: true, urls: true, postalAddresses: true }, contactId: contactId });
return result.contacts.length > 0 ? result.contacts[0] : null; }
async createContact(contact: Partial<Contact>): Promise<string> { const hasPermission = await this.checkPermissions(); if (!hasPermission) { throw new Error('Contacts permission denied'); }
const result = await Contacts.createContact(contact); return result.contactId; }
async updateContact(contactId: string, updates: Partial<Contact>): Promise<void> { await Contacts.updateContact({ contactId, ...updates }); }
async deleteContact(contactId: string): Promise<void> { await Contacts.deleteContact({ contactId }); }
formatPhoneNumber(phone: string): string { // Remove non-numeric characters const cleaned = phone.replace(/\D/g, '');
// Format as (XXX) XXX-XXXX if (cleaned.length === 10) { return `(${cleaned.slice(0, 3)}) ${cleaned.slice(3, 6)}-${cleaned.slice(6)}`; }
return phone; }
getContactInitials(contact: Contact): string { const given = contact.name?.given || ''; const family = contact.name?.family || '';
if (given && family) { return `${given[0]}${family[0]}`.toUpperCase(); }
const display = contact.name?.display || ''; const parts = display.split(' ');
if (parts.length >= 2) { return `${parts[0][0]}${parts[1][0]}`.toUpperCase(); }
return display.slice(0, 2).toUpperCase(); }}
// Usageconst contactsService = new ContactsService();
// Get all contactsconst contacts = await contactsService.getAllContacts();console.log('Contacts:', contacts);
// Search contactsconst results = await contactsService.searchContacts('john');console.log('Search results:', results);
// Create contactconst newContactId = await contactsService.createContact({ name: { given: 'Jane', family: 'Smith' }, phones: [{ type: 'mobile', number: '+1234567890' }]});
// Update contactawait contactsService.updateContact(newContactId, { emails: [{ type: 'work', address: 'jane@example.com' }]});Understanding Projection
The projection parameter controls which fields to fetch:
const result = await Contacts.getContacts({ projection: { name: true, // Contact name phones: true, // Phone numbers emails: true, // Email addresses image: true, // Contact photo organization: true, // Company/organization birthday: true, // Birth date note: true, // Notes urls: true, // Websites postalAddresses: true // Physical addresses }});Tip: Only request fields you need to improve performance.
Contact Picker UI
Many apps prefer using the native contact picker:
const pickContact = async () => { try { const result = await Contacts.pickContact({ projection: { name: true, phones: true, emails: true } });
if (result.contacts.length > 0) { const contact = result.contacts[0]; console.log('Selected contact:', contact); } } catch (error) { console.error('Contact picker cancelled or failed:', error); }};Best Practices
- Request Minimal Permissions: Only request contacts permission when needed
- Use Projection: Only fetch fields you actually use
- Handle Denials: Provide fallback when permissions denied
- Cache Wisely: Contacts can change, don’t cache too long
- Respect Privacy: Be transparent about contact usage
- Async Operations: All contact operations are async
Common Issues
Permission Denied
const handlePermissionDenied = async () => { const permission = await Contacts.checkPermissions();
if (permission.contacts === 'denied') { // Show dialog explaining why permission is needed showPermissionDialog(); // Direct user to settings // On iOS: Settings > [App] > Contacts // On Android: Settings > Apps > [App] > Permissions }};Large Contact Lists
const loadContactsInBatches = async () => { // Get count first (lightweight) const projection = { name: true }; // Minimal projection
// Implement pagination if needed const allContacts = await Contacts.getContacts({ projection });
// Process in chunks const chunkSize = 100; for (let i = 0; i < allContacts.contacts.length; i += chunkSize) { const chunk = allContacts.contacts.slice(i, i + chunkSize); await processContactChunk(chunk); }};Next Steps
- Explore the API Reference for complete method documentation
- Check out the example app for advanced usage
- See the tutorial for complete implementation examples