madewulf madewulf - 5 months ago 29
iOS Question

ABAddressBook external callback not called in iOS

I have a class holding the list of contacts of my user in an iPhone app.

The core of it is implemented as follows.

//file Contacts.m
//imports here
void MyAddressBookExternalChangeCallback (
ABAddressBookRef addressBook,
CFDictionaryRef info,
void *context
)
{
NSLog(@"callback called ");
[[Contacts sharedInstance] refresh];
}

@implementation Contacts
@synthesize addressBook;

+ (Contacts*)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[Contacts alloc] init];
}
}
return sharedInstance;
}

- (void)refresh
{
ABAddressBookRevert(addressBook); /*refreshing the address book in case of changes*/
[people release];
people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);

}

- (id)init
{
if ((self = [super init]))
{
sharedInstance = self;
addressBook = ABAddressBookCreate();;
people = nil;
[self refresh];
ABAddressBookRegisterExternalChangeCallback ( addressBook,
MyAddressBookExternalChangeCallback,
self
);
}
return sharedInstance;
}


In
init
, I setup an external callback
MyAddressBookExternalChangeCallback
to be notified of changes to the contact list.
The problem that I have is that the external callback is not called (I never see the result of the nslog message) when I add a contact in the iPhone phone app.

What did I do wrong ?

Added note: even stranger, if I do

ABAddressBookRevert(addressBook);


every time my app come to the front and the address book has been modified, then the callback is called.

Answer

I tested this on my iPhone and verified that the callback was called:

Contacts.h:

#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>

@interface Contacts : NSObject
{
    ABAddressBookRef addressBook;
    NSArray *people;
}

+ (Contacts*)sharedInstance;
- (void)refresh;

void MyAddressBookExternalChangeCallback (
                                          ABAddressBookRef addressBook,
                                          CFDictionaryRef info,
                                          void *context
                                          );

@end

Contacts.m:

#import "Contacts.h"

void MyAddressBookExternalChangeCallback (
                                          ABAddressBookRef addressBook,
                                          CFDictionaryRef info,
                                          void *context
                                          )
{
    NSLog(@"callback called ");
    [[Contacts sharedInstance] refresh];
}

@implementation Contacts

+ (Contacts*)sharedInstance
{
    static Contacts *sharedInstance = nil;

    @synchronized(self)
    {
        if (sharedInstance == nil)
        {
            sharedInstance = [[Contacts alloc] init];
        }
    }
    return sharedInstance;
}

- (void)refresh
{
    ABAddressBookRevert(addressBook); /*refreshing the address book in case of changes*/
    [people release];
    people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);

}

- (id)init
{
    if ((self = [super init]))
    {
        //sharedInstance = self;
        addressBook = ABAddressBookCreate();
        people = nil;                                                               
        [self refresh];
        ABAddressBookRegisterExternalChangeCallback (addressBook,
                                                     MyAddressBookExternalChangeCallback,
                                                     self
                                                     );
    }
    return self;
}

@end