Easy access to iOS and Android contact directory. Pick a contact, update it, delete it, or add a new one.
npm install @nativescript/contacts
Add following key to Info.plist often found in App_Resources/iOS/Info.plist
<key>NSContactsUsageDescription</key>
<string>Kindly provide permission to access contacts on your device.</string>
User will be asked for permissions when contacts are accessed by the app.
Since iOS 13, you will also need entitlements. If you do not have App_Resources/iOS/app.entitlements
yet, you can add the file with at least these contents:
<?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>
From API level 23 on you need to check for the appropriate permissions to access the contacts. So not only do you need these permissions in your 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" />
You also need to make sure to request the permissions everytime you perform the operation itself (e.g. using the nativescript-permissions plugin):
import { Contact } from '@nativescript/contacts';
import { requestPermissions } from 'nativescript-permissions';
const contact = new Contact();
// build a new contact...
requestPermissions([android.Manifest.permission.GET_ACCOUNTS, android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.WRITE_CONTACTS, android.Manifest.permission.GLOBAL_SEARCH], "I need these permissions because I'm cool").then(() => {
contact.save();
});
import { Contacts } 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
// lets say you wanted to grab first name and last name
console.log(contact.name.given + ' ' + contact.name.family)
//lets say you want to get the phone numbers
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)
})
}
})
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()
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()
}
)
}
})
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()
}
})
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
console.log(contact.isUnified() ? 'Contact IS unified' : 'Contact is NOT unified')
}
})
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)
}
)
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)
}
)
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)
}
)
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)
}
)
import { Group } from '@nativescript/contacts'
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)
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)
}
)
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
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)
}
)
}
})
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) {
/// Returns args:
/// args.data: Generic cross platform JSON object, null if no groups were found.
/// 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)
}
)
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)
}
)
{
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 following constants are exposed from the plugin in the KnownLabel
structure. See details bellow for what types and on what platform they are supported
Those are the system labels but you can also use any custom label you want.
{
id: ''
name: ''
}
GetFetchResult
Data Structure The object returned by contact fetch requests.
{
data: Contact[];
response: string;
}
See apples docs on properties available: https://developer.apple.com/library/mac/documentation/Contacts/Reference/CNContact_Class/index.html#//apple_ref/occ/cl/CNContact
NOTE: Since the plugin uses the Contact framework it is supported only on iOS 9.0 and above!
All credit to original author Ryan Lebel for creating nativescript-contacts.
Apache License Version 2.0