Skip to content

Commit

Permalink
[TIMOB-20589] iOS: Allow editing contacts in iOS9 and above
Browse files Browse the repository at this point in the history
  • Loading branch information
sriks committed Mar 22, 2016
1 parent d38b1de commit 83fe7b8
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 53 deletions.
2 changes: 1 addition & 1 deletion iphone/Classes/ContactsModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#import "KrollCallback.h"
#import "TiContactsPerson.h"

@interface ContactsModule : TiModule<ABPeoplePickerNavigationControllerDelegate, CNContactPickerDelegate,CNContactViewControllerDelegate> {
@interface ContactsModule : TiModule<ABPeoplePickerNavigationControllerDelegate, CNContactPickerDelegate,CNContactViewControllerDelegate, TiContactsPersonUpdateObserver> {
@private
ABAddressBookRef addressBook;
ABPeoplePickerNavigationController* picker;
Expand Down
50 changes: 31 additions & 19 deletions iphone/Classes/ContactsModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

static NSArray* contactKeysWithImage;
static NSArray* contactKeysWithoutImage;

@implementation ContactsModule

void CMExternalChangeCallback (ABAddressBookRef notifyAddressBook,CFDictionaryRef info,void *context)
Expand Down Expand Up @@ -151,7 +152,6 @@ -(void)dealloc
saveRequest = nil;
RELEASE_TO_NIL(contactPicker)
[[NSNotificationCenter defaultCenter] removeObserver:self name:CNContactStoreDidChangeNotification object:nil];

[super dealloc];
}

Expand Down Expand Up @@ -196,7 +196,6 @@ -(void)requestContactsPermissions:(id)args
NSString * error = nil;
int code = 0;
BOOL doPrompt = NO;

if ([TiUtils isIOS9OrGreater]) {
CNAuthorizationStatus permissions = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
switch (permissions) {
Expand Down Expand Up @@ -236,7 +235,7 @@ -(void)requestContactsPermissions:(id)args
}, NO);
return;
}

ABAuthorizationStatus permissions = ABAddressBookGetAuthorizationStatus();
switch (permissions) {
case kABAuthorizationStatusNotDetermined:
Expand Down Expand Up @@ -284,15 +283,14 @@ -(NSNumber*) contactsAuthorization
CNAuthorizationStatus result = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
return [NSNumber numberWithInt:result];
}

ABAuthorizationStatus result = ABAddressBookGetAuthorizationStatus();
return [NSNumber numberWithLong:result];
}

-(void)save:(id)unused
{
ENSURE_UI_THREAD(save, unused)

if ([TiUtils isIOS9OrGreater]) {
CNContactStore *ourContactStore = [self contactStore];
if (ourContactStore == NULL) {
Expand All @@ -308,10 +306,10 @@ -(void)save:(id)unused
subreason:nil
location:CODELOCATION];
};
saveRequest = nil;
RELEASE_TO_NIL(saveRequest)
return;
}

CFErrorRef error;
ABAddressBookRef ourAddressBook = [self addressBook];
if (ourAddressBook == NULL) {
Expand Down Expand Up @@ -348,11 +346,9 @@ -(void)showContacts:(id)args
RELEASE_TO_NIL(selectedPropertyCallback)
RELEASE_TO_NIL(picker)
RELEASE_TO_NIL(contactPicker)

cancelCallback = [[args objectForKey:@"cancel"] retain];
selectedPersonCallback = [[args objectForKey:@"selectedPerson"] retain];
selectedPropertyCallback = [[args objectForKey:@"selectedProperty"] retain];

if ([TiUtils isIOS9OrGreater]) {
contactPicker = [[CNContactPickerViewController alloc] init];
[contactPicker setDelegate:self];
Expand Down Expand Up @@ -383,7 +379,6 @@ -(void)showContacts:(id)args
return;

}

picker = [[ABPeoplePickerNavigationController alloc] init];
[picker setPeoplePickerDelegate:self];

Expand Down Expand Up @@ -498,7 +493,10 @@ -(TiContactsPerson*)getPersonByIdentifier:(id)arg
if (error) {
return nil;
}
return [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact *)contact module:self] autorelease];
return [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext]
contactId:(CNMutableContact *)contact
module:self
observer:self] autorelease];
}

//New in iOS9
Expand Down Expand Up @@ -557,7 +555,10 @@ -(NSArray*)getPeopleWithName:(id)arg
}
NSMutableArray* people = [NSMutableArray arrayWithCapacity:[contacts count]];
for (CNContact *personRef in contacts) {
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact *)personRef module:self] autorelease];
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext]
contactId:(CNMutableContact *)personRef
module:self
observer:self] autorelease];
[people addObject:person];
}
return people;
Expand Down Expand Up @@ -604,7 +605,9 @@ -(NSArray*)getAllPeople:(id)unused
//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]];
BOOL success = [ourContactStore enumerateContactsWithFetchRequest:fetchRequest error:&error usingBlock:^(CNContact * __nonnull contact, BOOL * __nonnull stop) {
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact*)contact module:self] autorelease];
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext]
contactId:(CNMutableContact*)contact
module:self observer:self] autorelease];
[peopleRefs addObject:person];
}];
RELEASE_TO_NIL(fetchRequest)
Expand Down Expand Up @@ -716,12 +719,16 @@ -(TiContactsPerson*)createPerson:(id)arg
}
NSError *error = nil;
CNMutableContact *newContact = [[CNMutableContact alloc] init];
TiContactsPerson* newPerson = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:newContact module:self] autorelease];
TiContactsPerson* newPerson = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext]
contactId:newContact
module:self
observer:nil] autorelease];
RELEASE_TO_NIL(newContact);
[newPerson setValuesForKeysWithDictionary:arg];
[newPerson updateiOS9ContactProperties];
saveRequest = [newPerson getSaveRequestForAddition:[ourContactStore defaultContainerIdentifier]];
[self save:nil];
newPerson.observer = self;
return newPerson;
}

Expand Down Expand Up @@ -770,14 +777,13 @@ -(void)removePerson:(id)arg
{
ENSURE_SINGLE_ARG(arg,TiContactsPerson)
ENSURE_UI_THREAD(removePerson,arg)

if([TiUtils isIOS9OrGreater]) {
TiContactsPerson *person = arg;
saveRequest = nil;
saveRequest = [person getSaveRequestForDeletion];
return;
}

[self removeRecord:[arg record]];
}

Expand Down Expand Up @@ -857,7 +863,6 @@ -(void)removeGroup:(id)arg
{
ENSURE_SINGLE_ARG(arg,TiContactsGroup)
ENSURE_UI_THREAD(removeGroup,arg)

if([TiUtils isIOS9OrGreater]) {
TiContactsGroup *group = arg;
saveRequest = nil;
Expand Down Expand Up @@ -1017,11 +1022,12 @@ - (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)pe
{
[self peoplePickerNavigationController:peoplePicker shouldContinueAfterSelectingPerson:person property:property identifier:identifier];
}

//iOS9 delegates
- (void)contactPicker:(nonnull CNContactPickerViewController *)picker didSelectContact:(nonnull CNContact *)contact
{
if (selectedPersonCallback) {
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact*)contact module:self] autorelease];
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact*)contact module:self observer:self] autorelease];
[self _fireEventToListener:@"selectedPerson"
withObject:[NSDictionary dictionaryWithObject:person forKey:@"person"]
listener:selectedPersonCallback
Expand All @@ -1038,7 +1044,7 @@ - (void)contactPicker:(nonnull CNContactPickerViewController *)picker didSelectC
- (void)contactPicker:(nonnull CNContactPickerViewController *)picker didSelectContactProperty:(nonnull CNContactProperty *)contactProperty
{
if (selectedPropertyCallback) {
TiContactsPerson *personObject = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact*)contactProperty.contact module:self] autorelease];
TiContactsPerson* personObject = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact*)contactProperty.contact module:self observer:self] autorelease];

id value = contactProperty.value;
id result = [NSNull null];
Expand Down Expand Up @@ -1134,6 +1140,12 @@ - (void)contactViewController:(nonnull CNContactViewController *)viewController
{

}

#pragma mark - TiContactsPersonUpdateObserver
- (void)didUpdatePerson:(TiContactsPerson*)person {
saveRequest = saveRequest ? saveRequest : [CNSaveRequest new];
[saveRequest updateContact:person.nativePerson];
}
@end

#endif
11 changes: 8 additions & 3 deletions iphone/Classes/TiContactsGroup.m
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ -(NSArray*)members:(id)unused
CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:[ContactsModule contactKeysWithImage]];
fetchRequest.predicate = [CNContact predicateForContactsInGroupWithIdentifier:[group identifier]];
BOOL success = [ourContactStore enumerateContactsWithFetchRequest:fetchRequest error:&error usingBlock:^(CNContact * __nonnull contact, BOOL * __nonnull stop) {
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact*)contact module:module] autorelease];
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext]
contactId:(CNMutableContact*)contact
module:module
observer:module] autorelease];
[peopleRefs addObject:person];
}];
if (success) {
Expand Down Expand Up @@ -211,7 +214,10 @@ -(NSArray*)sortedMembers:(id)value
fetchRequest.sortOrder = sortOrder;
fetchRequest.mutableObjects = YES;
BOOL success = [ourContactStore enumerateContactsWithFetchRequest:fetchRequest error:&error usingBlock:^(CNContact * __nonnull contact, BOOL * __nonnull stop) {
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext] contactId:(CNMutableContact*)contact module:module] autorelease];
TiContactsPerson* person = [[[TiContactsPerson alloc] _initWithPageContext:[self executionContext]
contactId:(CNMutableContact*)contact
module:module
observer:module] autorelease];
[peopleRefs addObject:person];
}];
RELEASE_TO_NIL(fetchRequest)
Expand Down Expand Up @@ -259,7 +265,6 @@ -(void)add:(id)arg
{
ENSURE_SINGLE_ARG(arg,TiContactsPerson)
ENSURE_UI_THREAD(add,arg);

if ([TiUtils isIOS9OrGreater]) {
TiContactsPerson *person = arg;
CNContactStore *ourContactStore = [module contactStore];
Expand Down
14 changes: 13 additions & 1 deletion iphone/Classes/TiContactsPerson.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
#import <AddressBook/AddressBook.h>
#import <Contacts/Contacts.h>

@class TiContactsPerson;
@protocol TiContactsPersonUpdateObserver <NSObject>
@optional
- (void)didUpdatePerson:(TiContactsPerson*)person;
@end

@class ContactsModule;

@interface TiContactsPerson : TiProxy {
Expand All @@ -31,10 +37,16 @@

-(id)_initWithPageContext:(id<TiEvaluator>)context recordId:(ABRecordID)id_ module:(ContactsModule*)module_;
-(id)_initWithPageContext:(id<TiEvaluator>)context person:(ABRecordRef)person_ module:(ContactsModule*)module_;

@property(readonly,nonatomic) NSString* identifier;
@property(assign, nonatomic) id<TiContactsPersonUpdateObserver> observer;

+(NSDictionary*)iOS9multiValueLabels;
+(NSDictionary*)iOS9propertyKeys;
-(id)_initWithPageContext:(id<TiEvaluator>)context contactId:(CNMutableContact*)person_ module:(ContactsModule*)module_;
-(id)_initWithPageContext:(id<TiEvaluator>)context
contactId:(CNMutableContact*)person_
module:(ContactsModule*)module_
observer:(id<TiContactsPersonUpdateObserver>) observer_;
-(CNSaveRequest*)getSaveRequestForDeletion;
-(CNSaveRequest*)getSaveRequestForAddition:(NSString*)containerIdentifier;
-(CNSaveRequest*)getSaveRequestForAddToGroup: (CNMutableGroup*) group;
Expand Down

0 comments on commit 83fe7b8

Please sign in to comment.