在处理ABAddressBookRef时似乎无法找到解决方案

时间:2013-12-25 18:34:54

标签: ios objective-c addressbook

我的代码中有一些'EXC_BAD_ACCESS', 我试图弄清楚问题是什么,但我仍然不知道为什么。 有什么想法吗?

- (void)requestPermissionForContacts {
    NSLog(@"requestPermissionForContacts");
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(duplicateUserContacts:) name:kAccessGrantedNotification object:nil];
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

    if (addressBook != NULL) {
        if (kWeDontHaveAccessToContacts) {
            ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
                if (granted) {
                    NSLog(@"Access granted");
                    [[NSNotificationCenter defaultCenter] postNotificationName:kAccessGrantedNotification object:nil];
                }
            });
        }
        else if (kWeHaveAccessToContacts) {
            [[NSNotificationCenter defaultCenter] postNotificationName:kAccessGrantedNotification object:nil];
        }
    }
}

- (void)duplicateUserContacts:(NSNotification*)notification {
    NSLog(@"duplicateUserContacts");
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

    if (addressBook != NULL && kWeHaveAccessToContacts) {
        // Get all user contacts
        NSArray *allContacts = [self getAllContacts];
        CFArrayRef allContactsRef = (__bridge CFArrayRef)allContacts;

        // Delete old group if exists
        [self deleteOwnGroup];

        // Create Mobile Control 'white list' group
        [self createGroup];

        // Copy contacts to new group
        if (addressBook != NULL && kWeHaveAccessToContacts) {
            for (int i = 0; i < ABAddressBookGetPersonCount(addressBook); i++) {
                ABRecordRef personFromContacts = CFArrayGetValueAtIndex(allContactsRef, i);
                [self addContactToGroup:personFromContacts];
            }
        }
        CFRelease(allContactsRef);
        CFRelease(addressBook);
    }
}

- (ABRecordRef)getGroupReference {
    NSLog(@"getGroupReference");

    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

    if (addressBook != NULL && kWeHaveAccessToContacts) {
        CFArrayRef allGroups = ABAddressBookCopyArrayOfAllGroups(addressBook);

        if (allGroups != NULL) {
            for (int i = 0; i < CFArrayGetCount(allGroups); i++) {
                ABRecordRef group = CFArrayGetValueAtIndex(allGroups, i);
                CFStringRef name = ABRecordCopyCompositeName(group);
                NSString *groupName = (__bridge NSString*)name;

                NSLog(@"groupName: %@", groupName);

                if ([groupName isEqualToString:kCallBlockGroupName]) {
                    self.groupCallBlockRef = group;

                    CFRelease(group);
                    CFRelease(name);
                    CFRelease(allGroups);

                    break;
                }
                else {
                    continue;
                }
            }
        }
    }
    //CFRelease(addressBook);
    return self.groupCallBlockRef != NULL ? self.groupCallBlockRef : NULL;
}

- (NSArray*)getAllContacts {
    NSLog(@"getAllContacts");

    __block NSArray *allContacts = [NSArray new];
    __block CFErrorRef *error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);

    if (addressBook != NULL && kWeHaveAccessToContacts) {
        CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
        allContacts = CFBridgingRelease(people);
        self.arrayOfAllContacts = allContacts;

        CFRelease(addressBook);
        //CFRelease(error);
    }
    else {
        NSLog(@"addressBook is NULL");
        allContacts = NULL;
    }

    NSLog(@"Total number of contacts: %i", allContacts.count);
    return allContacts;
}

- (void)deleteContact:(ABRecordRef)person {
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

    if (addressBook != NULL && kWeHaveAccessToContacts) {
        CFErrorRef error = NULL;
        ABAddressBookRemoveRecord(addressBook, person, &error);
        ABAddressBookSave(addressBook, &error);

        CFRelease(addressBook);
        CFRelease(error);
        CFRelease(person);
    }
}

- (void)blockPerson:(ABRecordRef)person {
    BOOL hasContact = [self checkIfContactExists:person];
    if (hasContact) {
        NSLog(@"Contact exists, delete him.");
        [self deleteContact:person];
    }
    else {
        NSLog(@"Contact not exists.");
    }
}

- (BOOL)checkIfContactExists:(ABRecordRef)person {
    __block BOOL answer = NO;
    CFErrorRef *error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);

    if (addressBook != NULL && kWeHaveAccessToContacts) {
        CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);

        for(int i=0; i<ABAddressBookGetPersonCount(addressBook); i++) {
            ABRecordRef personToCompare = CFArrayGetValueAtIndex(people, i);

            if (ABRecordGetRecordID(personToCompare) == ABRecordGetRecordID(person)) {
                answer = YES;

                CFRelease(addressBook);
                CFRelease(people);
                CFRelease(personToCompare);
                CFRelease(person);

                break;
            }
        }
    }
    return answer;
}

- (void)deleteOwnGroup {
    NSLog(@"deleteOwnGroup");

    ABRecordRef group = [self getGroupReference];
    BOOL hasGroup = group != NULL ? YES : NO;

    if (hasGroup) {
        NSLog(@"Group exists, delete group.");
        ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

        if (addressBook != NULL && kWeHaveAccessToContacts) {
//            CFErrorRef error = NULL;
            ABAddressBookRemoveRecord(addressBook, group, NULL);
            ABAddressBookSave(addressBook, NULL);

            CFRelease(group);
            CFRelease(addressBook);
        }
    }
    else {
        NSLog(@"Group is not exists, no group to delete.");
    }
}

- (void)createGroup {
    NSLog(@"createGroup");

    ABRecordRef group = [self getGroupReference];
    BOOL hasGroup = group != NULL ? YES : NO;

    if (hasGroup) {
        NSLog(@"Group already exists.");
    }
    else {
        NSLog(@"Group is not exists, create group.");
        ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

        if (addressBook != NULL && kWeHaveAccessToContacts) {
            ABRecordRef newGroup = ABGroupCreate();
            ABRecordSetValue(newGroup, kABGroupNameProperty, (__bridge CFStringRef)kCallBlockGroupName, NULL);
            ABAddressBookAddRecord(addressBook, newGroup, NULL);
            ABAddressBookSave(addressBook, NULL);
            self.groupCallBlockRef = newGroup;

            CFRelease(newGroup);
            CFRelease(addressBook);
            CFRelease(group);
        }
    }
}

- (void)addContactToGroup:(ABRecordRef)person {
    NSLog(@"addContactToGroup");

    ABRecordRef group = [self getGroupReference];
    BOOL hasGroup = group != NULL ? YES : NO;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    //ABRecordID recordID = ABRecordGetRecordID(person);

    if (!hasGroup) {
        [self createGroup];
        group = self.groupCallBlockRef;
    }

    CFErrorRef error = NULL;
    BOOL didAdd = ABGroupAddMember(group, person, &error);

    if (!didAdd || error) {
        NSLog(@"Error adding member to group: %@", error);
    }

    error = NULL;
    BOOL didSave = ABAddressBookSave(addressBook, &error);

    if (!didSave || error) {
        NSLog(@"Error saving member to group: %@", error);
    }
    CFRelease(addressBook);
    CFRelease(error);
    CFRelease(group);
    CFRelease(person);
}
  1. 在'deleteOwnGroup'中:

    ABAddressBookRemoveRecord(addressBook,group,NULL); ABAddressBookSave(addressBook,NULL);

  2. 在'addContactToGroup'中:

    BOOL didAdd = ABGroupAddMember(group,person,&amp; error);

1 个答案:

答案 0 :(得分:0)

我修复了我的代码,现在它就像一个魅力, 我的完整代码:

- (id)initAddressBook {
    self = [super init];
    if (self) {
        self.addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
        ABAddressBookRegisterExternalChangeCallback(self.addressBook, addressBookChangeHandler, NULL);
    }
    return self;
}

- (void)duplicateUserContactsFromAddressBook:(ABAddressBookRef)myAddressBook {
    NSLog(@"duplicateUserContacts");

    if (myAddressBook != NULL && kWeHaveAccessToContacts) {
        // Get all user contacts
        CFArrayRef allContactsRef = [self getAllContactsInAddressBook:myAddressBook];

        // Delete old group if exists
        [self deleteGroupWithName:kGroupNameMobileControl fromAddressBook:myAddressBook];

        // Create Mobile Control 'white list' group
        self.groupCallBlockRef = [self createGroupWithName:kGroupNameMobileControl fromAddressBook:myAddressBook];

        // Copy contacts to new group
        for (int i = 0; i < ABAddressBookGetPersonCount(myAddressBook); i++) {
            ABRecordRef personFromContacts = CFArrayGetValueAtIndex(allContactsRef, i);
            [self addPerson:personFromContacts toGroup:self.groupCallBlockRef fromAddressBook:myAddressBook];
        }
    }
}

- (void)deleteGroupWithName:(NSString*)groupName fromAddressBook:(ABAddressBookRef)myAddressBook {
    if (myAddressBook != NULL && kWeHaveAccessToContacts) {
        CFArrayRef allGroups = ABAddressBookCopyArrayOfAllGroups(myAddressBook);
        if (allGroups != NULL) {
            for (int i = 0; i < CFArrayGetCount(allGroups); i++) {
                ABRecordRef group = CFArrayGetValueAtIndex(allGroups, i);
                CFStringRef name = ABRecordCopyCompositeName(group);
                NSString *currentGroupName = (__bridge NSString*)name;

                if ([currentGroupName isEqualToString:groupName]) {
                    [self deleteGroup:group fromAddressBook:myAddressBook];
                }
            }
        }
    }
}

- (ABRecordRef)getGroupReference:(ABAddressBookRef)myAddressBook {
    NSLog(@"getGroupReference");

    if (myAddressBook != NULL && kWeHaveAccessToContacts) {
        CFArrayRef allGroups = ABAddressBookCopyArrayOfAllGroups(myAddressBook);
        if (allGroups != NULL) {
            for (int i = 0; i < CFArrayGetCount(allGroups); i++) {
                ABRecordRef group = CFArrayGetValueAtIndex(allGroups, i);
                CFStringRef name = ABRecordCopyCompositeName(group);
                NSString *groupName = (__bridge NSString*)name;
                NSLog(@"groupName: %@", groupName);

                if ([groupName isEqualToString:kGroupNameMobileControl]) {
                    self.groupCallBlockRef = group;
                    break;
                }
                else {
                    continue;
                }
            }
        }
    }
    return self.groupCallBlockRef != NULL ? self.groupCallBlockRef : NULL;
}

- (CFArrayRef)getAllContactsInAddressBook:(ABAddressBookRef)myAddressBook {
    NSLog(@"getAllContacts");

    if (myAddressBook != NULL && kWeHaveAccessToContacts) {
        CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(myAddressBook);
        self.arrayOfAllContacts = people;
    }
    else {
        self.arrayOfAllContacts = NULL;
    }

    NSLog(@"Total number of contacts: %li", CFArrayGetCount(self.arrayOfAllContacts));
    return self.arrayOfAllContacts;
}

- (void)deleteContact:(ABRecordRef)person inAddressBook:(ABAddressBookRef)myAddressBook {
    if (myAddressBook != NULL && kWeHaveAccessToContacts) {
        CFErrorRef error = NULL;
        ABAddressBookRemoveRecord(myAddressBook, person, &error);
        ABAddressBookSave(myAddressBook, &error);

        CFRelease(error);
        CFRelease(person);
    }
}

- (void)blockPerson:(ABRecordRef)person inAddressBook:(ABAddressBookRef)myAddressBook {
    BOOL hasContact = [self checkIfContactExists:person inAddressBook:myAddressBook];
    if (hasContact) {
        NSLog(@"Contact exists, delete him.");
        [self deleteContact:person inAddressBook:myAddressBook];
    }
    else {
        NSLog(@"Contact not exists.");
    }
}

- (BOOL)checkIfContactExists:(ABRecordRef)person inAddressBook:(ABAddressBookRef)myAddressBook {
    __block BOOL answer = NO;

    if (myAddressBook != NULL && kWeHaveAccessToContacts) {
        CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(myAddressBook);

        for(int i=0; i<ABAddressBookGetPersonCount(myAddressBook); i++) {
            ABRecordRef personToCompare = CFArrayGetValueAtIndex(people, i);

            if (ABRecordGetRecordID(personToCompare) == ABRecordGetRecordID(person)) {
                answer = YES;

                CFRelease(people);
                CFRelease(personToCompare);
                CFRelease(person);

                break;
            }
        }
    }
    return answer;
}

- (ABRecordRef)createGroupWithName:(NSString*)groupName fromAddressBook:(ABAddressBookRef)myAddressBook {
    NSLog(@"createGroup");
    ABRecordRef newGroup = ABGroupCreate();
    if (myAddressBook != NULL && kWeHaveAccessToContacts) {
        ABRecordSetValue(newGroup, kABGroupNameProperty, (__bridge CFStringRef)groupName, NULL);
        ABAddressBookAddRecord(myAddressBook, newGroup, NULL);
        ABAddressBookSave(myAddressBook, NULL);
        self.groupCallBlockRef = newGroup;
    }
    return newGroup;
}

- (void)addPerson:(ABRecordRef)person toGroup:(ABRecordRef)group fromAddressBook:(ABAddressBookRef)myAddressBook {
    NSLog(@"addContactToGroup");
    ABGroupAddMember(group, person, NULL);
    ABAddressBookSave(myAddressBook, NULL);
}

static void addressBookChangeHandler(ABAddressBookRef addressBook, CFDictionaryRef info, void *context)
{
    if (context) {
        [(__bridge CallBlockManager*)context handleAddressBookChange:addressBook withInfo:info];
    }
}

- (void)handleAddressBookChange:(ABAddressBookRef)myAddressBook withInfo:(CFDictionaryRef)info {
    //
}