Question

I am trying to insert contact information in a specific group in the address group, but I cannot save any values except First Name, Last Name. I am using the following method to save contact information, and the app crashes with no trace (BAD ACCESS).

- (void) addSingleContact:(NSDictionary*)contact {

if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusDenied ||
    ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusRestricted){

    UIAlertView *cantAddContactAlert = [[UIAlertView alloc] initWithTitle:@"Cannot Add Contact"
                                                                  message:@"You must give the app permission to add the contact first."
                                                                 delegate:nil
                                                        cancelButtonTitle:@"OK"
                                                        otherButtonTitles:nil];
    [cantAddContactAlert show];

} else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized){

    CFErrorRef error, anError;

    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); // create address book record
    ABRecordRef person = ABPersonCreate(); // create a person

    ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABPersonPhoneProperty);

    ABMultiValueAddValueAndLabel(phoneNumberMultiValue , (__bridge CFTypeRef)([contact objectForKey:@"mobile"]), kABPersonPhoneMobileLabel, NULL);

    ABRecordSetValue(person, kABPersonFirstNameProperty, (__bridge CFTypeRef)([contact objectForKey:@"firstName"]) , nil);
    ABRecordSetValue(person, kABPersonLastNameProperty, (__bridge CFTypeRef)([contact objectForKey:@"lastName"]), nil);
    // *** CRASHES ON NEXT LINE ***
    ABRecordSetValue(person, kABPersonEmailProperty, (__bridge CFTypeRef)([contact objectForKey:@"email"]), nil);
    ABRecordSetValue(person, kABPersonJobTitleProperty, (__bridge CFTypeRef)([contact objectForKey:@"designation"]), nil);
    ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, &anError);

    ABAddressBookAddRecord(addressBook, person, nil);

    ABRecordRef group = [self getAddressGroup:addressBook];

    ABGroupAddMember(group, person, &error); // add the person to the group
    ABAddressBookAddRecord(addressBook, group, &error); // add the group


    ABAddressBookSave(addressBook, nil); //save the record


    CFRelease(person); // relase the ABRecordRef  variable

} else { //ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined

    ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool authorized, CFErrorRef error) {

        dispatch_async(dispatch_get_main_queue(), ^{

            if (!authorized){

                UIAlertView *cantAddContactAlert = [[UIAlertView alloc] initWithTitle:@"Cannot Add Contact"
                                                                              message:@"You must give the app permission to add the contact first."
                                                                             delegate:nil
                                                                    cancelButtonTitle:@"OK"
                                                                    otherButtonTitles:nil];
                [cantAddContactAlert show];
            }
        });
    });
}
}

The getAddressGroup: method is as follows, but I doubt it is responsible, since Name is saved successfully :

- (ABAddressBookRef) getAddressGroup:(ABAddressBookRef)addressBook {

ABAddressBookRef group = NULL;

NSArray *groups = (__bridge NSArray *) ABAddressBookCopyArrayOfAllGroups(addressBook);

for (id _group in groups) {

    NSString *currentGroupName = (__bridge NSString*) ABRecordCopyValue((__bridge ABRecordRef)(_group), kABGroupNameProperty);

    if ([currentGroupName isEqualToString:GROUP_NAME]){

        group = (__bridge ABAddressBookRef)(_group);

        CFRelease((__bridge CFTypeRef)(currentGroupName));
        break;
    }

    CFRelease((__bridge CFTypeRef)(currentGroupName));
}

if (groups) {

    groups = nil;
}

if (group == NULL) {

    group = ABGroupCreate();

    ABRecordSetValue(group, kABGroupNameProperty, GROUP_NAME, nil);
}
return group;
}

If i try to save any other values, including job title, organisation, e-mail, phone-mobile, etc, the app crashes with BAD ACCESS. I have only begun working with ABAddressBook and Address Book Programming, and I simply don't get what I should do.

Was it helpful?

Solution

From the accepted answer here :

- (void) addSingleContact:(NSDictionary*)contact {

if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusDenied ||
    ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusRestricted){

    UIAlertView *cantAddContactAlert = [[UIAlertView alloc] initWithTitle:@"Cannot Add Contact"
                                                                  message:@"You must give the app permission to add the contact first."
                                                                 delegate:nil
                                                        cancelButtonTitle:@"OK"
                                                        otherButtonTitles:nil];
    [cantAddContactAlert show];

} else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized){

    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

    // create person record

    ABRecordRef person = ABPersonCreate();
    // set name and other string values

    NSString *firstName = [contact objectForKey:@"firstName"];
    NSString *lastName = [contact objectForKey:@"lastName"];
    NSString *organization = [contact objectForKey:@"company"];
    NSString *designation = [contact objectForKey:@"designation"];
    NSString *personEmail = [contact objectForKey:@"email"];
    NSString *phoneNo = [contact objectForKey:@"phone"];
    NSString *mobileNo = [contact objectForKey:@"mobile"];
    NSString *webURL = [contact objectForKey:@"website"];
    NSString *address = [contact objectForKey:@"address"];

    ABRecordSetValue(person, kABPersonOrganizationProperty, (__bridge CFStringRef)organization, NULL);
    ABRecordSetValue(person, kABPersonJobTitleProperty, (__bridge CFStringRef)designation, NULL);

    if (webURL.length) {

        ABMutableMultiValueRef urlMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
        ABMultiValueAddValueAndLabel(urlMultiValue, (__bridge CFStringRef) webURL, kABPersonHomePageLabel, NULL);
        ABRecordSetValue(person, kABPersonURLProperty, urlMultiValue, nil);
        CFRelease(urlMultiValue);
    }

    if (personEmail.length) {

        ABMutableMultiValueRef emailMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
        ABMultiValueAddValueAndLabel(emailMultiValue, (__bridge CFStringRef) personEmail, kABWorkLabel, NULL);
        ABRecordSetValue(person, kABPersonEmailProperty, emailMultiValue, nil);
        CFRelease(emailMultiValue);
    }


    //Add numbers ()
    ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);

NSArray *venuePhoneNumbers;

if (phoneNo.length) {

    venuePhoneNumbers = [phoneNo componentsSeparatedByString:@" or "];

    for (NSString *venuePhoneNumberString in venuePhoneNumbers)
        ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFStringRef) venuePhoneNumberString, kABPersonPhoneMainLabel, NULL);
}

if (mobileNo.length) {

    venuePhoneNumbers = [mobileNo componentsSeparatedByString:@" or "];
    for (NSString *venuePhoneNumberString in venuePhoneNumbers)
        ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFStringRef) venuePhoneNumberString, kABPersonPhoneMobileLabel, NULL);
}

if (faxNo.length) {

    venuePhoneNumbers = [faxNo componentsSeparatedByString:@" or "];
    for (NSString *venuePhoneNumberString in venuePhoneNumbers)
        ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFStringRef) venuePhoneNumberString, kABPersonPhoneWorkFAXLabel, NULL);
}

ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, NULL);
CFRelease(phoneNumberMultiValue);



    // add address

    ABMutableMultiValueRef multiAddress = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
    NSMutableDictionary *addressDictionary = [[NSMutableDictionary alloc] init];

    if (address) {

        addressDictionary[(NSString *) kABPersonAddressStreetKey] = [NSString stringWithFormat:@"%@", address];
    }


    ABRecordSetValue(person, kABPersonFirstNameProperty, (__bridge CFTypeRef)(firstName) , nil);
    ABRecordSetValue(person, kABPersonLastNameProperty, (__bridge CFTypeRef)(lastName), nil);


    ABMultiValueAddValueAndLabel(multiAddress, (__bridge CFDictionaryRef) addressDictionary, kABWorkLabel, NULL);
    ABRecordSetValue(person, kABPersonAddressProperty, multiAddress, NULL);
    CFRelease(multiAddress);

    ABAddressBookAddRecord(addressBook, person, &error);

    ABRecordRef group = [self getAddressGroup:addressBook];

    ABGroupAddMember(group, person, &error); // add the person to the group
    ABAddressBookAddRecord(addressBook, group, &error); // add the group

    ABAddressBookSave(addressBook, &error);

    CFRelease(person); // relase the ABRecordRef  variable
    CFRelease(group);
    CFRelease(addressBook);

} else { //ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined

    ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool authorized, CFErrorRef error) {

        dispatch_async(dispatch_get_main_queue(), ^{

            if (!authorized){

                UIAlertView *cantAddContactAlert = [[UIAlertView alloc] initWithTitle:@"Cannot Add Contact"
                                                                              message:@"You must give the app permission to add the contact first."
                                                                             delegate:nil
                                                                    cancelButtonTitle:@"OK"
                                                                    otherButtonTitles:nil];
                [cantAddContactAlert show];
            }
        });
    });
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top