1

I am attempting to create a feature with my app that allows people to be easily added and/or removed from a group on iOS. The code below works perfectly if I:

1) add one person at a time 2) remove one person at a time

If however I select multiple people to add and/or remove simultaneously only the first action - first add if any or first remove if no additions - is committed to the address book. This method can be called over and over again with any one individual action and it will succeed. I cannot determine why I cannot get it to save multiple adds/deletes within the context of a single call to save. It should be pointed out that no error is giving and stepping through the code the booleans used to determine success indicate that everything worked perfectly.

I have attempted various combinations of adjusting code, for example: create a local address book, retrieve the groupRef, save the address book all within each of the for loops. I've also investigated reverting the address book after saving it to no avail. Thoughts or experiences?

-(IBAction)save:(id)sender
{
    @synchronized(self)
    {
        CFErrorRef error = NULL;
        BOOL success = NO;
        BOOL successfulSave = NO;

        ABAddressBookRef localAddressBook = ABAddressBookCreateWithOptions(NULL, &error);
        group = ABAddressBookGetGroupWithRecordID(localAddressBook, groupID);

        for (CFIndex addItemCount = 0; addItemCount < [theAddList count]; ++addItemCount)
        {
            NSNumber *addID = [theAddList objectAtIndex:addItemCount];
            ABRecordRef thePersonID = ABAddressBookGetPersonWithRecordID(localAddressBook, [addID intValue]);
            success = success || ABGroupAddMember(group, thePersonID, &error);
        }

        for (CFIndex removeItemCount = 0; removeItemCount < [theRemoveList count]; ++removeItemCount)
        {
            NSNumber *removeID = [theRemoveList objectAtIndex:removeItemCount];
            ABRecordRef thePersonID = ABAddressBookGetPersonWithRecordID(localAddressBook, [removeID intValue]);
            success = success || ABGroupRemoveMember(group, thePersonID, &error);
        }

        if (success)
        {
            successfulSave = ABAddressBookSave(localAddressBook, &error);
        }

        if (!(successfulSave && success))
        {
            UIAlertView *addressBookUpdateAlert = [[UIAlertView alloc] initWithTitle:@"AddressBook Error" message:@"An update to your address book could not be processed at this time. Try again shortly." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
            // we can't update a GUI element from a background thread - appears sensitivity didn't appear until iOS 8
            [[NSOperationQueue mainQueue] addOperationWithBlock:
             ^{
                 [addressBookUpdateAlert show];
             }];
        }
        else
        {
            [[self navigationController] popViewControllerAnimated:YES];
        }
    }
}
mcoding
  • 9
  • 2

1 Answers1

0

I can't explain it, but I made a minor change which should have done a better job of trapping an error and instead seems to caused to code to magically start working - which by the way is usually code for you over wrote memory somewhere.

Anyway I did the following and it started working:

  1. Set success = YES before entering the loop
  2. Changed the || test to an && test in both loops

All I changed and yet somehow it just started working...weird...I'm off to test/hammer the thing in case I'm seeing things...

mcoding
  • 9
  • 2