Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(ios): support new property to remove note #11248

Merged
merged 3 commits into from
Oct 8, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 16 additions & 1 deletion apidoc/Titanium/Contacts/Contacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,21 @@ methods:
type: Callback<ContactsAuthorizationResponse>

properties:
- name: includeNote
summary: A boolean value that indicates whether to fetch the notes stored in contacts or not.
description: |
This property need to be set before calling contacts APIs.
From iOS 13 or later if your app fetch note field from contact, the app must have to set key 'com.apple.developer.contacts.notes' to 'true' in entitelements section of tiapp.xml.

<key>com.apple.developer.contacts.notes</key>
<true/>

See more details at https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_contacts_notes and https://developer.apple.com/contact/request/contact-note-field.
type: Boolean
default: true
platforms: [iphone, ipad]
since: 8.2.1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From an architecture point of view, this is the wrong API design I think. Apple will very likely add more properties to the "sensitive" ones, so probably the user should have a property to override all fields that should be fetched - with the default not containing this one anymore. And it's likely a breaking change, just like this one also is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can be agree with you that we have to change/extend the behavior of exiting APIs specially which are fetching use contacts data. Probably android also have to make some changes to have a parity and there may be some breaking change. For that I think we can not make it before 9.0.0.
But this new property will give developer an option to avoid fetching the 'note' in iOS otherwise they have to make some unnecessary setup. So there is no problem in having this new property. And by default this property is true, so there is no breaking change.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without implementing this property, apps are being rejected, so it's a breaking change for them. Either adding this property or defining the properties they actually need, which will be more future proof in the first place. But it's just a community comment 🙂


- name: CONTACTS_KIND_ORGANIZATION
summary: Specifies that a contact is an organization.
description: |
Expand Down Expand Up @@ -565,4 +580,4 @@ properties:
---
name: ContactsAuthorizationResponse
summary: Argument passed to the callback when a request finishes successfully or erroneously.
extends: ErrorResponse
extends: ErrorResponse
1 change: 1 addition & 0 deletions iphone/Classes/ContactsModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@private
BOOL reloadAddressBook;
BOOL animated;
BOOL _includeNote;
KrollCallback *cancelCallback;
KrollCallback *selectedPersonCallback;
KrollCallback *selectedPropertyCallback;
Expand Down
24 changes: 21 additions & 3 deletions iphone/Classes/ContactsModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ - (void)startup
{
[super startup];
contactStore = NULL;
_includeNote = YES;
}

//used for fetch predicates.
Expand Down Expand Up @@ -103,6 +104,11 @@ - (NSString *)apiName

#pragma mark Public API

- (void)setIncludeNote:(id)arg
{
_includeNote = [TiUtils boolValue:arg def:YES];
}

- (NSNumber *)hasContactsPermissions:(id)unused
{
NSString *calendarPermission = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSContactsUsageDescription"];
Expand Down Expand Up @@ -271,7 +277,11 @@ - (TiContactsPerson *)getPersonByIdentifier:(id)arg
}
NSError *error = nil;
CNContact *contact = nil;
contact = [ourContactStore unifiedContactWithIdentifier:arg keysToFetch:[ContactsModule contactKeysWithImage] error:&error];
NSMutableArray *contactKeys = [NSMutableArray arrayWithArray:[ContactsModule contactKeysWithImage]];
if (!_includeNote) {
[contactKeys removeObject:CNContactNoteKey];
}
contact = [ourContactStore unifiedContactWithIdentifier:arg keysToFetch:contactKeys error:&error];
if (error) {
return nil;
}
Expand Down Expand Up @@ -327,8 +337,12 @@ - (NSArray *)getPeopleWithName:(id)arg
}
NSError *error = nil;
NSArray *contacts = nil;
NSMutableArray *contactKeys = [NSMutableArray arrayWithArray:[ContactsModule contactKeysWithImage]];
if (!_includeNote) {
[contactKeys removeObject:CNContactNoteKey];
}
//returns empty array or nil if there's an error
contacts = [ourContactStore unifiedContactsMatchingPredicate:[CNContact predicateForContactsMatchingName:arg] keysToFetch:[ContactsModule contactKeysWithImage] error:&error];
contacts = [ourContactStore unifiedContactsMatchingPredicate:[CNContact predicateForContactsMatchingName:arg] keysToFetch:contactKeys error:&error];
if (!contacts) {
return nil;
}
Expand Down Expand Up @@ -365,7 +379,11 @@ - (NSArray *)getAllPeople:(id)unused
NSMutableArray *peopleRefs = nil;
peopleRefs = [[NSMutableArray alloc] init];
//this fetch request takes all information. Not advised to use this method if addressbook is huge. May result in performance issues.
CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:[ContactsModule contactKeysWithImage]];
NSMutableArray *array = [NSMutableArray arrayWithArray:[ContactsModule contactKeysWithImage]];
if (!_includeNote) {
[array removeObject:CNContactNoteKey];
}
CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:array];
BOOL success = [ourContactStore enumerateContactsWithFetchRequest:fetchRequest
error:&error
usingBlock:^(CNContact *__nonnull contact, BOOL *__nonnull stop) {
Expand Down