Search code examples
iosiphoneaddressbook

ABGroupCreate not working with Exchange


I have a problem when I run this snippet of code on the emulator it works, and I get the id of the group but when I run it on a device the id is set to -1 ... but the error message stays null.

    -(NSNumber *)addGroupeToAddressbookWithName:(NSString *)name{
    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFErrorRef error = NULL;
    ABRecordRef group = ABGroupCreate();
    ABRecordSetValue(group, kABGroupNameProperty,(__bridge CFStringRef)name, &error);
    ABAddressBookAddRecord(addressBook, group, &error);
    ABAddressBookSave(addressBook,&error);
    NSNumber *gId = [NSNumber numberWithInt:ABRecordGetRecordID(group)];

    CFRelease(group);
    return gId;
}

I can't figure out what the difference is and how to make it work on a real device.

EDIT: Found that it works if I remove the exchange sync on my phone, but still want it to work while being able to have a exchange account on the phone. So not really solving the problem

EDIT / Answer

Found that it was because exchange don't know about groups, to save a group it is needed to use the right source, also see : Obtaining Specific ABSource from ABAddressBook in iOS 4+

new code:

-(NSNumber *)addGroupeToAddressbookWithName:(NSString *)name{
    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFErrorRef error = NULL;
    CFArrayRef sources = ABAddressBookCopyArrayOfAllSources(addressBook);
    CFIndex sourceCount = CFArrayGetCount(sources);
    NSNumber *gId = nil;
    for (CFIndex i = 0 ; i < sourceCount; i++) {
        ABRecordRef currentSource = CFArrayGetValueAtIndex(sources, i);
        CFTypeRef sourceType = ABRecordCopyValue(currentSource, kABSourceTypeProperty);

        BOOL isMatch = kABSourceTypeLocal == [(__bridge NSNumber *)sourceType intValue];
        CFRelease(sourceType);

        if (isMatch) {
            ABRecordRef group = ABGroupCreateInSource(currentSource);//ABGroupCreate();
            ABRecordSetValue(group, kABGroupNameProperty,(__bridge CFStringRef)name, &error);
            ABAddressBookAddRecord(addressBook, group, &error);
            ABAddressBookSave(addressBook,&error);
            gId = [NSNumber numberWithInt:ABRecordGetRecordID(group)];
            CFRelease(group);
            CFRelease(currentSource);
            break;
        }
    }

    CFRelease(sources);
    return gId;
}

Solution

  • Found that it was because exchange dont know about groups, to save a group it is needed to use the right source, also see : Obtaining Specific ABSource from ABAddressBook in iOS 4+

    new code:

    -(NSNumber *)addGroupeToAddressbookWithName:(NSString *)name{
        ABAddressBookRef addressBook = ABAddressBookCreate();
        CFErrorRef error = NULL;
        CFArrayRef sources = ABAddressBookCopyArrayOfAllSources(addressBook);
        CFIndex sourceCount = CFArrayGetCount(sources);
        NSNumber *gId = nil;
        for (CFIndex i = 0 ; i < sourceCount; i++) {
            ABRecordRef currentSource = CFArrayGetValueAtIndex(sources, i);
            CFTypeRef sourceType = ABRecordCopyValue(currentSource, kABSourceTypeProperty);
    
            BOOL isMatch = kABSourceTypeLocal == [(__bridge NSNumber *)sourceType intValue];
            CFRelease(sourceType);
    
            if (isMatch) {
                ABRecordRef group = ABGroupCreateInSource(currentSource);//ABGroupCreate();
                ABRecordSetValue(group, kABGroupNameProperty,(__bridge CFStringRef)name, &error);
                ABAddressBookAddRecord(addressBook, group, &error);
                ABAddressBookSave(addressBook,&error);
                gId = [NSNumber numberWithInt:ABRecordGetRecordID(group)];
                CFRelease(group);
                CFRelease(currentSource);
                break;
            }
        }
    
        CFRelease(sources);
        return gId;
    }