| title | Contacts |
|---|---|
| editUrl | https://github.com/NativeScript/plugins/tree/main/packages/contacts/README.md |
A plugin that allows you to access Contacts directory on iOS and Android. You can pick a contact, update it, delete it, or add a new one.
- @nativescript/contacts
- Contents
- Installation
- Use @nativescript/contacts
- Get a contact
- Create a new contact
- Update a contact
- Delete a contact
- Check if a contact is unified/linked (iOS Specific)
- Get contacts by name
- Get all the contacts
- Get a contact by id
- Get a group or groups of contacts
- Create a new contacts group
- Delete a group of contacts
- Add a contact to a group
- Remove a contact from a group
- Get all the contacts of a group
- Contact class
- PhoneNumber/EmailAddress structure
- Url structure
- PostalAddress structure
- Known Labels (for Urls, Addresses and Phones)
- Group object structure
- GetFetchResult object structure
- iOS contact object
- Credits
- License
Run the following command to install the plugin:
npm install @nativescript/contacts
For the app to access the user's Contacts app, the user must grant it the permission to do. Before requesting for permissions, ensure that the following requirements are met.
- To clarify why your app needs the permission to access the user's contacts, add the
NSContactsUsageDescriptionkey to theApp_Resources/iOS/Info.plistfile, and your clarification as its value.
<key>NSContactsUsageDescription</key> <string>Kindly provide permission to access contacts on your device.</string>
- For iOS 13+, add the com.apple.developer.contacts.notes entitlement to the
App_Resources/iOS/app.entitlementsfile. If the file does not exist, you should create it.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.contacts.notes</key> <true/> </dict> </plist>
For API level 23+, inform Android about which permissions your app needs from the user in order to access contacts by listing the following permissions in the AndroidManifest.xml:
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="android.permission.GLOBAL_SEARCH" />
Once you've indicated the permissions your app needs from a user, you can request the permissions from the user by calling the request() method from the @nativescript-community/perms plugin.
import { Contact } from '@nativescript/contacts' import { request } from '@nativescript-community/perms' const contact = new Contact() // build a new contact... requestPermissions({ contacts: {}, 'android.permission.GET_ACCOUNTS': {}, 'android.permission.READ_CONTACTS': {}, 'android.permission.WRITE_CONTACTS': {}, 'android.permission.GLOBAL_SEARCH': {}, }).then(() => { contact.save() })
To get a selected contact, call the getContact() method of the Contacts class.
import { Contact } from '@nativescript/contacts' Contacts.getContact().then(function (args) { /// Returns args: /// args.data: Generic cross platform JSON object /// args.reponse: "selected" or "cancelled" depending on wheter the user selected a contact. if (args.response === 'selected') { const contact = args.data //See data structure below console.log(contact.name.given + ' ' + contact.name.family) contact.phoneNumbers.forEach(function (phone) { console.log(phone.value) }) //lets say you want to get the addresses contact.postalAddresses.forEach(function (address) { console.log(address.location.street) }) } })
To create a new contact, first instantiate the Contact class, set the various data of the contact and then to save the contact, call the save() method on the instance.
import { Contact, KnownLabel } from '@nativescript/contacts' import { ImageSource } from '@nativescript/core' const newContact = new Contact() newContact.name.given = 'John' newContact.name.family = 'Doe' newContact.phoneNumbers.push({ label: KnownLabel.HOME, value: '123457890', }) // See below for known labels newContact.phoneNumbers.push({ label: 'My Custom Label', value: '11235813' }) newContact.photo = ImageSource.fromFileOrResource('~/photo.png') newContact.save()
To update an existing contact, get it with the getContact() method, edit it and then call the save() method to update it.
import { Application, ImageSource } from '@nativescript/core' import { Contacts } from '@nativescript/contacts' Contacts.getContact().then(function (args) { if (args.response === 'selected') { const contact = args.data contact.name.given = 'Jane' contact.name.family = 'Doe' ImageSource.fromUrl( 'http://www.google.com/images/errors/logo_sm_2.png', ).then(function (src) { contact.photo = src contact.save() }) } })
To delete a contact, get it with the getContact() method and then call the delete() method on it.
import { Contacts } from '@nativescript/contacts' Contacts.getContact().then(function (args) { /// args.data: Generic cross platform JSON object /// args.reponse: "selected" or "cancelled" depending on wheter the user selected a contact. if (args.response === 'selected') { const contact = args.data //See data structure below contact.delete() } })
To check if a contact is unified, call the isUnified() on the contact.
import { Contacts } from '@nativescript/contacts' Contacts.getContact().then(function (args) { /// args.data: Generic cross platform JSON object /// args.reponse: "selected" or "cancelled" depending on whether the user selected a contact. if (args.response === 'selected') { const contact = args.data //See data structure below console.log( contact.isUnified() ? 'Contact IS unified' : 'Contact is NOT unified', ) } })
To find all the contacts matching a certain name, use the getContactsByName() method. Returns an array of contact data.
import { Contacts } from '@nativescript/contacts' /* contactFields contains the fields to retrieve from native backend to reduce processing time const contactFields = ['name','organization','nickname','notes','photo','urls','phoneNumbers','emailAddresses','postalAddresses'] */ const contactFields = ['name', 'phoneNumbers'] Contacts.getContactsByName('Hicks', contactFields).then( function (args) { console.log('getContactsByName Complete') /// Returns args: /// args.data: Generic cross platform JSON object, null if no contacts were found. /// args.reponse: "fetch" }, function (err) { console.log('Error: ' + err) }, )
To read all the contacts, use the getAllContacts() method. It returns a a promise with an array of Contact instances.
import { Contacts } from '@nativescript/contacts' /* Optional: contactFields contains the fields to retrieve from native backend to reduce processing time const contactFields = ['name','organization','nickname','notes','photo','urls','phoneNumbers','emailAddresses','postalAddresses'] If not supplied, all available contactFields will be returned. */ const contactFields = ['name', 'phoneNumbers'] Contacts.getAllContacts(contactFields).then( function (args) { console.log('getAllContacts Complete') /// Returns args: /// args.data: Generic cross platform JSON object, null if no contacts were found. /// args.reponse: "fetch" }, function (err) { console.log('Error: ' + err) }, )
To find a contact with ta specific identifier, use the getContactById() method. The method returns an iOS-specific GetFetchResult object.
import { Contacts } from '@nativescript/contacts' const contactId = '[Contact Identifier]' // Assumes this is a valid contact identifier (Contact.id) Contacts.getContactById(contactId).then( function (args) { console.log('getContactById Complete') /// Returns args: /// args.data: Generic cross platform JSON object, null if no contacts were found. /// args.reponse: "fetch" }, function (err) { console.log('Error: ' + err) }, )
To get a group or groups of contacts, use the getGroups() method. To get a group of contacts with a specific name, call the method passing it the name of the group.
import { Contacts } from '@nativescript/contacts' Contacts.getGroups('Test Group') //[name] optional. If defined will look for group with the specified name, otherwise will return all groups. .then( function (args) { console.log('getGroups Complete') /// Returns args: /// args.data: Generic cross platform JSON object, null if no groups were found. /// args.reponse: "fetch" if (args.data === null) { console.log('No Groups Found!') } else { console.log('Group(s) Found!') } }, function (err) { console.log('Error: ' + err) }, )
To create a new contacts group, create an instance of the Group class, set group's name and call the save() method on the instance to save it.
import { Group } from '@nativescript/contacts/models' const groupModel = new Group() groupModel.name = 'Test Group' //Save Argument (boolean) //iOS: [false=> Use Local Container, true=> Use Default Container] //Android: will always be true, setting this value will not affect android. groupModel.save(false)
To delete a contacts group, call the getGroups() method to first get the group of interest. Then call the delete() method on that group to delete it.
import { Contacts } from '@nativescript/contacts' Contacts.getGroups('Test Group').then( function (args) { console.log('getGroups Complete') console.log(JSON.stringify(args)) /// Returns args: /// args.data: Generic cross platform JSON object, null if no groups were found. /// args.reponse: "fetch" if (args.data !== null) { console.log('Group(s) Found!') args.data[0].delete() //Delete the first found group } }, function (err) { console.log('Error: ' + err) }, )
To add a contact to a group, get the references to the contact and the group of interest. Next, call the addMember() method on the group passing it the contact reference to add.
import { Contacts } from '@nativescript/contacts' Contacts.getContact().then(function (args) { /// args.reponse: "selected" or "cancelled" depending on whether the user selected a contact. if (args.response === 'selected') { const contact = args.data //See data structure below Contacts.getGroups('Test Group').then( function (a) { if (a.data !== null) { const group = a.data[0] group.addMember(contact) } }, function (err) { console.log('Error: ' + err) }, ) } })
Call the removeMember() on Group class instance passing it the contact to remove.
import { Contacts } from '@nativescript/contacts' Contacts.getGroups('Test Group').then( function (args) { if (args.data !== null) { const group = args.data[0] Contacts.getContactsInGroup(group).then( function (a) { /// args.reponse: "fetch" console.log('getContactsInGroup complete') if (a.data !== null) { a.data.forEach(function (c, idx) { group.removeMember(c) }) } }, function (err) { console.log('Error: ' + err) }, ) } }, function (err) { console.log('Error: ' + err) }, )
To get all of a group's contacts, use the Contacts.getContactsInGroup() method passing it the group instance.
import { Contacts } from '@nativescript/contacts' Contacts.getGroups('Test Group') //[name] optional. If defined will look for group with the specified name, otherwise will return all groups. .then( function (args) { if (args.data !== null) { const group = args.data[0] Contacts.getContactsInGroup(group).then( function (a) { console.log('getContactsInGroup complete') /// Returns args: /// args.data: Generic cross platform JSON object, null if no groups were found. /// args.reponse: "fetch" }, function (err) { console.log('Error: ' + err) }, ) } }, function (err) { console.log('Error: ' + err) }, )
The Contact class has following structure
{ id : "", name : { given: "", middle: "", family: "", prefix: "", suffix: "", displayname: "", phonetic : { given: "", middle: "", family: "" } }, nickname : "", organization : { name: "", jobTitle: "", department: "", // Android Specific properties symbol: "", phonetic: "", location: "", type: "" }, notes : "", photo: null, // {N} ImageSource instance phoneNumbers : [], emailAddresses : [], postalAddresses : [], urls : [] }
{ id: "", label: "", value: "" }
{ label: "", value: "" }
{ id: "", label: "", location: { street: "", city: "", state: "", postalCode: "", country: "", countryCode: "" } }
The plugin exposes the following labels via the KnownLabel object to be used for the contact data.
- HOME iOS - phone, email, postal, url Android - phone, email, postal, url
- WORK iOS - phone, email, postal, url Android - phone, email, postal, url
- OTHER iOS - phone, email, postal, url Android - phone, email, postal, url
- FAX_HOME iOS - phone Android - phone
- FAX_WORK iOS - phone Android - phone
- PAGER iOS - phone Android - phone
- MAIN iOS - phone Android - phone
- HOMEPAGE iOS - url Android - url
- CALLBACK Android - phone
- CAR Android - phone
- COMPANY_MAIN Android - phone
- ISDN Android - phone
- OTHER_FAX Android - phone
- RADIO Android - phone
- TELEX Android - phone
- TTY_TDD Android - phone
- WORK_MOBILE Android - phone
- WORK_PAGER Android - phone
- ASSISTANT Android - phone
- MMS Android - phone
- FTP Android - url
- PROFILE Android - url
- BLOG Android - url
Those are the system labels but you can also use any custom label you want.
{ id: string, name: string, addMember: (constact: Contact) => void removeMember: (constact: Contact) => void }
The object returned by the getContactById() method of the Contacts class.
{ data: Contact[]; response: string; }
See Apple docs on properties available: https://developer.apple.com/library/mac/documentation/Contacts/Reference/CNContact_Class/index.html#//apple_ref/occ/cl/CNContact
:::tip NOTE
The plugin uses the Contact framework and it is supported only on iOS 9.0 and above!
:::
All credits to the original author Ryan Lebel for creating nativescript-contacts.
Apache License Version 2.0