Exploring the Capacitor Contacts API¶
Modern mobile applications often require seamless access to device contacts for enhanced user experiences, from social features to communication tools. With the Capacitor Contacts plugin from Capawesome, developers can integrate comprehensive contact management capabilities into their Ionic and Capacitor applications, enabling users to create, read, update, and delete contacts across Android, iOS, and Web platforms through a unified API that simplifies the complexity of platform-specific contact implementations.
Installation¶
To install the Capacitor Contacts plugin, please refer to the Installation section in the plugin documentation.
Usage¶
Let's explore the key features of the Capacitor Contacts API and how to implement them effectively in your Ionic applications.
Checking Availability¶
Before implementing contact functionality, it's important to verify if contact features are available on the device. The Capacitor Contacts API provides the isAvailable(...)
method for this purpose:
import { Contacts } from '@capawesome-team/capacitor-contacts';
const checkAvailability = async () => {
const { isAvailable } = await Contacts.isAvailable();
if (isAvailable) {
console.log('Contacts API is ready to use!');
} else {
console.log('Contacts API is not available on this device.');
}
};
This method ensures that the contacts API is accessible before attempting any contact operations. If contacts are not available, you can handle this gracefully by disabling contact-related features or providing alternative functionality.
Handling Permissions¶
Contact access requires proper permissions to ensure user privacy and security. Use the checkPermissions(...)
and requestPermissions(...)
methods to manage contact permissions:
import { Contacts } from '@capawesome-team/capacitor-contacts';
const checkPermissions = async () => {
const { readContacts, writeContacts } = await Contacts.checkPermissions();
if (readContacts !== 'granted') {
console.log('Contacts can not be read.');
}
if (writeContacts !== 'granted') {
console.log('Contacts can not be written.');
}
};
const requestPermissions = async () => {
const { readContacts, writeContacts } = await Contacts.requestPermissions();
if (readContacts !== 'granted') {
console.log('Contacts can not be read.');
}
if (writeContacts !== 'granted') {
console.log('Contacts can not be written.');
}
};
Always check and request permissions before performing contact operations to ensure your application has the necessary access rights.
Creating a Contact¶
Creating new contacts programmatically is straightforward with the createContact(...)
method:
import { Contacts, EmailAddressType, PhoneNumberType } from '@capawesome-team/capacitor-contacts';
const createContact = async () => {
const newContact = {
givenName: 'John',
familyName: 'Doe',
organizationName: 'Capawesome',
phoneNumbers: [
{
value: '+1-555-123-4567',
type: PhoneNumberType.Mobile,
},
],
emailAddresses: [
{
value: 'john.doe@example.com',
type: EmailAddressType.Work,
},
],
postalAddresses: [
{
street: '123 Main Street',
city: 'New York',
region: 'NY',
postalCode: '10001',
country: 'United States',
},
],
};
await Contacts.createContact({ contact: newContact });
console.log('Contact created successfully.');
};
The method accepts a comprehensive contact object with various fields including names, phone numbers, email addresses, and postal addresses. This way, you can create rich contact entries that enhance user interaction.
Retrieving Contacts¶
To retrieve contacts from the device, use the getContacts(...)
method with various filtering and pagination options:
const getContacts = async () => {
const { contacts } = await Contacts.getContacts({
fields: [
'id',
'givenName',
'familyName',
'emailAddresses',
'phoneNumbers',
'postalAddresses'
],
limit: 10,
offset: 0
});
return contacts;
};
This method allows you to specify which fields to retrieve, enabling efficient data handling and reducing memory usage. You can also implement pagination by adjusting the limit
and offset
parameters to load contacts in manageable chunks. There is also a getContactById(...)
method to retrieve a single contact by its ID.
Updating a Contact¶
Existing contacts can be updated using the updateContactById(...)
method. This method requires the contact ID of the contact you want to update, along with the new contact data:
import { Contacts, PhoneNumberType } from '@capawesome-team/capacitor-contacts';
const updateContactById = async (contactId: string) => {
await Contacts.updateContactById({
id: contactId,
contact: {
givenName: 'Jane',
familyName: 'Smith',
organizationName: 'Capawesome Inc.',
phoneNumbers: [
{
value: '+1-555-987-6543',
type: PhoneNumberType.Work,
},
],
},
});
console.log('Contact updated successfully');
};
When updating a contact, make sure to provide all fields, even those that have not changed. This is necessary because the update operation replaces the entire contact record. We recommend retrieving the existing contact first to ensure you have all the necessary fields.
Deleting a Contact¶
To remove a contact from the device, use the deleteContactById(...)
method:
const deleteContactById = async (contactId: string) => {
await Contacts.deleteContactById({ id: contactId });
console.log('Contact deleted successfully');
};
Be cautious when implementing contact deletion, as this operation is irreversible. Consider adding confirmation dialogs to prevent accidental data loss.
Picking a Contact¶
For user-driven contact selection, the pickContacts(...)
method opens the native contact picker:
const pickContacts = async () => {
const { contacts } = await Contacts.pickContacts({
fields: [
'id',
'givenName',
'familyName',
'emailAddresses',
'phoneNumbers',
'postalAddresses'
],
multiple: false
});
if (contacts.length > 0) {
console.log('Contact selected:', contacts[0]);
} else {
console.log('No contact selected');
}
};
The native contact picker provides a familiar interface for users to select contacts, with options to choose single or multiple contacts.
Advanced¶
Accounts and Groups¶
On Android, contacts can be associated with different accounts (like Google, CalDAV, etc.). The Capawesome Contacts plugin allows you to retrieve a list of available accounts:
const getAccounts = async () => {
const result = await Contacts.getAccounts();
console.log('Available contact accounts:', result.accounts);
};
Unfortunately, Android does not offer a way to create new accounts programmatically due to security and privacy restrictions. However, you can use the retrieved accounts to offer users the option to select a specific account when creating or updating contacts.
On iOS, contacts can be organized into groups. This is also supported by the Capawesome Contacts plugin, allowing you to manage contact groups without user intervention:
import { Contacts } from '@capawesome-team/capacitor-contacts';
const getGroups = async () => {
const result = await Contacts.getGroups();
console.log('Available contact groups:', result.groups);
result.groups.forEach(group => {
console.log(`Group: ${group.name} (ID: ${group.id})`);
});
};
const createContactGroup = async () => {
const result = await Contacts.createGroup({
group: {
name: 'Friends'
}
});
console.log('Group created with ID:', result.id);
};
Unlike Android, iOS allows you to create new groups programmatically, enabling better organization of contacts within your application.
Photos¶
You can also manage contact photos using the Capawesome Contacts plugin. The plugin allows you to retrieve, set, and delete contact photos, enhancing the visual representation of contacts in your application.
Here’s how to retrieve a contact's photo:
const getContactWithPhoto = async (contactId: string) => {
const { contact } = await Contacts.getContactById({
id: contactId,
fields: ['id', 'givenName', 'familyName', 'photo'],
});
if (contact?.photo) {
console.log('Contact photo as base64:', contact.photo);
} else {
console.log('No photo available for this contact.');
}
};
Contact photos are always handled as base64-encoded strings, making it easy to use them in your application, such as displaying them in user interfaces or uploading them to a server.
Best Practices¶
When implementing contact management with the Capacitor Contacts API, consider these best practices:
-
Implement proper permission handling: Always check and request contact permissions before attempting any contact operations. Provide clear explanations to users about why your app needs contact access, and gracefully handle permission denials by offering alternative functionality or limited features.
-
Use fields wisely: When retrieving contacts, specify only the fields you need. This reduces memory usage and improves performance, especially when dealing with large contact lists. Avoid requesting unnecessary fields to keep your application efficient.
-
Handle updates carefully: When updating contacts, ensure you retrieve the existing contact first to avoid losing any data. The update operation replaces the entire contact record, so it’s crucial to include all fields, even those that have not changed.
Conclusion¶
The Capacitor Contacts Plugin from Capawesome provides a comprehensive solution for integrating contact management into Ionic applications. By offering a unified API across multiple platforms, it enables developers to create powerful contact-driven features without the complexity of platform-specific implementations.
To stay updated with the latest updates, features, and news about the Capawesome, Capacitor, and Ionic ecosystem, subscribe to the Capawesome newsletter and follow us on X (formerly Twitter).
If you have any questions or need assistance with the Capacitor Contacts Plugin, feel free to reach out to the Capawesome team. We're here to help you implement seamless contact management in your Ionic applications.