how can I Add a ABRecordRef to a NSMutableArray in iPhone?
Asked Answered
S

4

10

I want to create an array of ABRecordRef(s) to store contacts which have a valid birthday field.

   NSMutableArray* bContacts = [[NSMutableArray alloc] init];
   ABAddressBookRef addressBook = ABAddressBookCreate();
   CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
   CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

   for( int i = 0 ; i < nPeople ; i++ )
   {
       ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i );
       NSDate* birthdayDate = (NSDate*) ABRecordCopyValue(ref, kABPersonBirthdayProperty);
       if (birthdayDate != nil){
           [bContacts addObject:ref];
       }
   }

The compiler shows this warning: warning: passing argument 1 of 'addObject:' discards qualifiers from pointer target type I searched the web and found I have to cast ABRecordRef to a ABRecord* to be able to store in a NSMutableArray.

[bContacts addObject:(ABRecord*) ref];

But it seems ABRecord is not part of iOS frameworks. Now how I store ABRecordRef to NSMutableArray?

Saba answered 20/5, 2011 at 11:28 Comment(0)
F
7
[bContacts addObject:(id) ref];
Fibrin answered 20/5, 2011 at 11:40 Comment(0)
B
12

A ABRecordRef is a typedef for CFTypeRef and that in turn resolves to const void *. And this is where the warning comes from: with the call to addObject:, the const qualifier is "lost".

In this case we know it's OK. A CFTypeRef is a semi-highlevel type, instances of this type support CFRetain and CFRelease. That in turn means it's probably OK to cast it to id and treat it as a NSObject. So you should be simply able to do:

[bContacts addObject:(id)ref];
Blithesome answered 20/5, 2011 at 11:56 Comment(0)
F
7
[bContacts addObject:(id) ref];
Fibrin answered 20/5, 2011 at 11:40 Comment(0)
D
6

Create an NSObject wich store your ABRecordRef like this :

// ABContact.h
@interface ABContact : NSObject
{
    ABRecordRef _record;
}

@property (nonatomic, readonly) NSDate *birthday;

- (id)initWithRecord:(ABRecordRef)aRecord;

@end

// ABContact.m
@implementation ABContact

#pragma mark - Init

- (id)initWithRecord:(ABRecordRef)aRecord;
{
    if ((self = [super init]))
        _record = CFRetain(aRecord);
    return self;
}


#pragma mark - Getter

- (NSDate *)birthday
{
    return (NSDate *)ABRecordCopyValue(record, kABPersonBirthdayProperty) autorelease];
}


#pragma mark - Memory management

- (void)dealloc
{
    CFRelease(_record);
    [super dealloc];
}

@end


You should take a look at the Erica Sadum library the author of the iPhone cookbook. Here is the code wich inspire this code -> url

Dishonest answered 20/5, 2011 at 11:48 Comment(0)
C
4

I know this is an old question, but since the introduction of ARC, this is handled in a different way.

There are two possible ways of adding an ABRecordRef to an NSMutableArray now, both of which require a bridged cast:

Direct conversion

[bContacts addObject:(__bridge id)(ref)];

This simply converts the ABRecordRef pointer, and should be used, if you didn't create ref yourself using a method that has Create in its name.

Transfer ownership to ARC

[bContacts addObject:CFBridgingRelease(ref)];

This converts the ABRecordRef pointer, and in addition transfers its ownership to ARC. This should be used, if you used e.g. ABPersonCreate() to create a new person.

More information can be found in the Transitioning to ARC Release Notes. There are also many other informative sources here on Stack Overflow, such as this question.

Childish answered 24/3, 2015 at 10:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.