Skip to content

Commit 6c1b709

Browse files
committed
feat: add contact images to contact objects
1 parent 81af9e9 commit 6c1b709

File tree

2 files changed

+65
-13
lines changed

2 files changed

+65
-13
lines changed

README.md

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ console.log(`Authorization access to contacts is: ${authStatus}`)
5050

5151
Returns `Array<Object>` - Returns an array of contact objects.
5252

53+
The returned objects will take the following format:
54+
55+
* `firstName` String - The contact's first name, or an empty string ('') if one is not set.
56+
* `lastName` String - The contact's last name, or an empty string ('') if one is not set.
57+
* `nickname` String - The contact's nickname, or an empty string ('') if one is not set.
58+
* `birthday` String - The contact's birthday in YYYY-MM-DD format, or an empty string ('') if one is not set.
59+
* `phoneNumbers` Array<String> - An array of phone numbers as strings in [E.164 format](https://en.wikipedia.org/wiki/E.164).
60+
* `emailAddresses` Array<String> - An array of email addresses as strings.
61+
* `postalAddresses` Array<String> - An array of postal as strings.
62+
* `contactImage` Buffer (optional) - a Buffer representation of the contact's image, if one has been set.
63+
64+
This method will return an empty array (`[]`) if access to Contacts has not been granted.
65+
66+
Example:
67+
5368
```js
5469
const allContacts = contacts.getAllContacts()
5570

@@ -63,14 +78,13 @@ console.log(allContacts[0])
6378
birthday: '1970-01-01',
6479
phoneNumbers: [ +11234566789' ],
6580
emailAddresses: [ 'johnny@appleseed.com' ]
66-
postalAddresses: [ '123 Pine Tree Way\nBlack Oak, Arkansas 72414\nUnited States' ]
81+
postalAddresses: [ '123 Pine Tree Way\nBlack Oak, Arkansas 72414\nUnited States' ],
82+
contactImage: <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 48 00 48 00 00 ff e1 00 4c 45 78 69 66 00 00 4d 4d 00 2a 00 00 00 08 00 01 87 69 00 04 00 00 00 01 00 00 ... 139493 more bytes>
6783
}
6884
]
6985
*/
7086
```
7187

72-
This method will return an empty array (`[]`) if access to Contacts has not been granted.
73-
7488
### contacts.getContactsByName(name)
7589

7690
* `name` String (required) - The first, last, or full name of a contact.
@@ -79,6 +93,21 @@ Returns `Array<Object>` - Returns an array of contact objects where either the f
7993

8094
If a contact's full name is 'Shelley Vohr', I could pass 'Shelley', 'Vohr', or 'Shelley Vohr' as `name`.
8195

96+
The returned object will take the following format:
97+
98+
* `firstName` String - The contact's first name, or an empty string ('') if one is not set.
99+
* `lastName` String - The contact's last name, or an empty string ('') if one is not set.
100+
* `nickname` String - The contact's nickname, or an empty string ('') if one is not set.
101+
* `birthday` String - The contact's birthday in YYYY-MM-DD format, or an empty string ('') if one is not set.
102+
* `phoneNumbers` Array<String> - An array of phone numbers as strings in [E.164 format](https://en.wikipedia.org/wiki/E.164).
103+
* `emailAddresses` Array<String> - An array of email addresses as strings.
104+
* `postalAddresses` Array<String> - An array of postal as strings.
105+
* `contactImage` Buffer (optional) - a Buffer representation of the contact's image, if one has been set.
106+
107+
This method will return an empty array (`[]`) if access to Contacts has not been granted.
108+
109+
Example:
110+
82111
```js
83112
const contacts = contacts.getContactsByName('Appleseed')
84113

@@ -93,13 +122,12 @@ console.log(contacts)
93122
phoneNumbers: [ +11234566789' ],
94123
emailAddresses: [ 'johnny@appleseed.com' ]
95124
postalAddresses: [ '123 Pine Tree Way\nBlack Oak, Arkansas 72414\nUnited States' ]
125+
contactImage: <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 48 00 48 00 00 ff e1 00 4c 45 78 69 66 00 00 4d 4d 00 2a 00 00 00 08 00 01 87 69 00 04 00 00 00 01 00 00 ... 139493 more bytes>
96126
}
97127
]
98128
*/
99129
```
100130

101-
This method will return an empty array (`[]`) if access to Contacts has not been granted.
102-
103131
### contacts.addNewContact(contact)
104132

105133
* `contact` Object
@@ -112,7 +140,11 @@ This method will return an empty array (`[]`) if access to Contacts has not been
112140

113141
Returns `Boolean` - whether the contact information was created successfully.
114142

115-
Creates and save a new contact to the user's contacts database.
143+
Creates and save a new contact to the user's contacts database.
144+
145+
This method will return `false` if access to Contacts has not been granted.
146+
147+
Example:
116148

117149
```js
118150
const success = contacts.addNewContact({
@@ -127,8 +159,6 @@ const success = contacts.addNewContact({
127159
console.log(`New contact was ${success ? 'saved' : 'not saved'}.`)
128160
```
129161

130-
This method will return `false` if access to Contacts has not been granted.
131-
132162
### contacts.deleteContact(name)
133163

134164
* `name` String (required) - The first, last, or full name of a contact.
@@ -140,15 +170,17 @@ Deletes a contact to the user's contacts database.
140170
If a contact's full name is 'Shelley Vohr', I could pass 'Shelley', 'Vohr', or 'Shelley Vohr' as `name`.
141171
However, you should take care to specify `name` to such a degree that you can be confident the first contact to be returned from a predicate search is the contact you intend to delete.
142172

173+
This method will return `false` if access to Contacts has not been granted.
174+
175+
Example:
176+
143177
```js
144178
const name = 'Jonathan Appleseed'
145179
const deleted = contacts.deleteContact(name)
146180

147181
console.log(`Contact ${name} was ${deleted ? 'deleted' : 'not deleted'}.`)
148182
```
149183

150-
This method will return `false` if access to Contacts has not been granted.
151-
152184
### contacts.updateContact(contact)
153185

154186
* `contact` Object
@@ -165,6 +197,10 @@ Updates a contact to the user's contacts database.
165197

166198
You should take care to specify parameters to the `contact` object to such a degree that you can be confident the first contact to be returned from a predicate search is the contact you intend to update.
167199

200+
This method will return `false` if access to Contacts has not been granted.
201+
202+
Example:
203+
168204
```js
169205
// Change contact's nickname from Billy -> Will
170206
const updated = contacts.updateContact({
@@ -175,5 +211,3 @@ const updated = contacts.updateContact({
175211

176212
console.log(`Contact was ${updated ? 'updated' : 'not updated'}.`)
177213
```
178-
179-
This method will return `false` if access to Contacts has not been granted.

contacts.mm

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@
6767
return result;
6868
}
6969

70+
Napi::Buffer<uint8_t> GetContactImage(Napi::Env env, CNContact *cncontact) {
71+
std::vector<uint8_t> data;
72+
73+
NSData *image_data = [cncontact imageData];
74+
const uint8 *bytes = (uint8 *)[image_data bytes];
75+
data.assign(bytes, bytes + [image_data length]);
76+
77+
if (data.empty())
78+
return Napi::Buffer<uint8_t>::New(env, 0);
79+
return Napi::Buffer<uint8_t>::Copy(env, &data[0], data.size());
80+
}
81+
7082
// Creates an object containing all properties of a macOS contact
7183
Napi::Object CreateContact(Napi::Env env, CNContact *cncontact) {
7284
Napi::Object contact = Napi::Object::New(env);
@@ -90,6 +102,12 @@
90102
Napi::Array postal_addresses = GetPostalAddresses(env, cncontact);
91103
contact.Set("postalAddresses", postal_addresses);
92104

105+
// Populate contact image if one exists.
106+
Napi::Buffer<uint8_t> image_buffer = GetContactImage(env, cncontact);
107+
if (image_buffer.Length() > 0) {
108+
contact.Set("contactImage", image_buffer);
109+
}
110+
93111
return contact;
94112
}
95113

@@ -161,7 +179,7 @@ CNAuthorizationStatus AuthStatus() {
161179
NSArray *keys = @[
162180
CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey,
163181
CNContactEmailAddressesKey, CNContactNicknameKey,
164-
CNContactPostalAddressesKey, CNContactBirthdayKey
182+
CNContactPostalAddressesKey, CNContactBirthdayKey, CNContactImageDataKey
165183
];
166184

167185
return keys;

0 commit comments

Comments
 (0)