转载请说明(谢谢)
http://blog.csdn.net/a21064346/article/details/8016935
今天准备 做一个和系统自带的 contact 通讯录 交互的软件。
找了很多 资料,发现大部分的开发者 并没有什么简便的方法,都是 把所有的属性 key 罗列出来,一个一个进行处理。
对一些 属性进行分类进行管理,一些前辈写的 文件比较好。不过看了一下时间,发现是两三年前的作品了,让我觉得 是不是还有更好的资源可以使用。。
下面的是 大部分开发者都会使用或者了解的 属性 key 的module,大家根据自己的要求对其使用
为了方便 ,就用了 复制粘贴的方式给大家。本文到此就结束了。谢谢
代码如下
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License, Use at your own risk
*/
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
@interface ABContact : NSObject
{
ABRecordRef record;
}
// Convenience allocation methods
+ (id) contact;
+ (id) contactWithRecord: (ABRecordRef) record;
+ (id) contactWithRecordID: (ABRecordID) recordID;
// Class utility methods
+ (NSString *) localizedPropertyName: (ABPropertyID) aProperty;
+ (ABPropertyType) propertyType: (ABPropertyID) aProperty;
+ (NSString *) propertyTypeString: (ABPropertyID) aProperty;
+ (NSString *) propertyString: (ABPropertyID) aProperty;
+ (BOOL) propertyIsMultivalue: (ABPropertyID) aProperty;
+ (NSArray *) arrayForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record;
+ (id) objectForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record;
// Creating proper dictionaries
+ (NSDictionary *) dictionaryWithValue: (id) value andLabel: (CFStringRef) label;
+ (NSDictionary *) addressWithStreet: (NSString *) street withCity: (NSString *) city
withState:(NSString *) state withZip: (NSString *) zip
withCountry: (NSString *) country withCode: (NSString *) code;
+ (NSDictionary *) smsWithService: (CFStringRef) service andUser: (NSString *) userName;
// Instance utility methods
- (BOOL) removeSelfFromAddressBook: (NSError **) error;
@property (nonatomic, readonly) ABRecordRef record;
@property (nonatomic, readonly) ABRecordID recordID;
@property (nonatomic, readonly) ABRecordType recordType;
@property (nonatomic, readonly) BOOL isPerson;
#pragma mark SINGLE VALUE STRING
@property (nonatomic, assign) NSString *firstname;
@property (nonatomic, assign) NSString *lastname;
@property (nonatomic, assign) NSString *middlename;
@property (nonatomic, assign) NSString *prefix;
@property (nonatomic, assign) NSString *suffix;
@property (nonatomic, assign) NSString *nickname;
@property (nonatomic, assign) NSString *firstnamephonetic;
@property (nonatomic, assign) NSString *lastnamephonetic;
@property (nonatomic, assign) NSString *middlenamephonetic;
@property (nonatomic, assign) NSString *organization;
@property (nonatomic, assign) NSString *jobtitle;
@property (nonatomic, assign) NSString *department;
@property (nonatomic, assign) NSString *note;
@property (nonatomic, readonly) NSString *contactName; // my friendly utility
@property (nonatomic, readonly) NSString *compositeName; // via AB
#pragma mark NUMBER
@property (nonatomic, assign) NSNumber *kind;
#pragma mark DATE
@property (nonatomic, assign) NSDate *birthday;
@property (nonatomic, readonly) NSDate *creationDate;
@property (nonatomic, readonly) NSDate *modificationDate;
#pragma mark MULTIVALUE
// Each of these produces an array of NSStrings
@property (nonatomic, readonly) NSArray *emailArray;
@property (nonatomic, readonly) NSArray *emailLabels;
@property (nonatomic, readonly) NSArray *phoneArray;
@property (nonatomic, readonly) NSArray *phoneLabels;
@property (nonatomic, readonly) NSArray *relatedNameArray;
@property (nonatomic, readonly) NSArray *relatedNameLabels;
@property (nonatomic, readonly) NSArray *urlArray;
@property (nonatomic, readonly) NSArray *urlLabels;
@property (nonatomic, readonly) NSArray *dateArray;
@property (nonatomic, readonly) NSArray *dateLabels;
@property (nonatomic, readonly) NSArray *addressArray;
@property (nonatomic, readonly) NSArray *addressLabels;
@property (nonatomic, readonly) NSArray *smsArray;
@property (nonatomic, readonly) NSArray *smsLabels;
@property (nonatomic, readonly) NSString *emailaddresses;
@property (nonatomic, readonly) NSString *phonenumbers;
@property (nonatomic, readonly) NSString *urls;
// Each of these uses an array of dictionaries
@property (nonatomic, assign) NSArray *emailDictionaries;
@property (nonatomic, assign) NSArray *phoneDictionaries;
@property (nonatomic, assign) NSArray *relatedNameDictionaries;
@property (nonatomic, assign) NSArray *urlDictionaries;
@property (nonatomic, assign) NSArray *dateDictionaries;
@property (nonatomic, assign) NSArray *addressDictionaries;
@property (nonatomic, assign) NSArray *smsDictionaries;
#pragma mark IMAGES
@property (nonatomic, assign) UIImage *image;
#pragma mark REPRESENTATIONS
// Conversion to dictionary
- (NSDictionary *) baseDictionaryRepresentation; // no image
- (NSDictionary *) dictionaryRepresentation; // image where available
// Conversion to data
- (NSData *) baseDataRepresentation; // no image
- (NSData *) dataRepresentation; // image where available
+ (id) contactWithDictionary: (NSDictionary *) dict;
+ (id) contactWithData: (NSData *) data;
@end
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License, Use at your own risk
*/
#import "ABContact.h"
#import "ABContactsHelper.h"
#define CFAutorelease(obj) ({CFTypeRef _obj = (obj); (_obj == NULL) ? NULL : [(id)CFMakeCollectable(_obj) autorelease]; })
#define FIRST_NAME_STRING @"First Name"
#define MIDDLE_NAME_STRING @"Middle Name"
#define LAST_NAME_STRING @"Last Name"
#define PREFIX_STRING @"Prefix"
#define SUFFIX_STRING @"Suffix"
#define NICKNAME_STRING @"Nickname"
#define PHONETIC_FIRST_STRING @"Phonetic First Name"
#define PHONETIC_MIDDLE_STRING @"Phonetic Middle Name"
#define PHONETIC_LAST_STRING @"Phonetic Last Name"
#define ORGANIZATION_STRING @"Organization"
#define JOBTITLE_STRING @"Job Title"
#define DEPARTMENT_STRING @"Department"
#define NOTE_STRING @"Note"
#define BIRTHDAY_STRING @"Birthday"
#define CREATION_DATE_STRING @"Creation Date"
#define MODIFICATION_DATE_STRING @"Modification Date"
#define KIND_STRING @"Kind"
#define EMAIL_STRING @"Email"
#define ADDRESS_STRING @"Address"
#define DATE_STRING @"Date"
#define PHONE_STRING @"Phone"
#define SMS_STRING @"Instant Message"
#define URL_STRING @"URL"
#define RELATED_STRING @"Related Name"
#define IMAGE_STRING @"Image"
@implementation ABContact
@synthesize record;
// Thanks to Quentarez, Ciaran
- (id) initWithRecord: (ABRecordRef) aRecord
{
if (self = [super init]) record = CFRetain(aRecord);
return self;
}
+ (id) contactWithRecord: (ABRecordRef) person
{
return [[[ABContact alloc] initWithRecord:person] autorelease];
}
+ (id) contactWithRecordID: (ABRecordID) recordID
{
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef contactrec = ABAddressBookGetPersonWithRecordID(addressBook, recordID);
ABContact *contact = [self contactWithRecord:contactrec];
// CFRelease(contactrec); // Thanks Gary Fung
return contact;
}
// Thanks to Ciaran
+ (id) contact
{
ABRecordRef person = ABPersonCreate();
id contact = [ABContact contactWithRecord:person];
CFRelease(person);
return contact;
}
- (void) dealloc
{
if (record) CFRelease(record);
[super dealloc];
}
#pragma mark utilities
+ (NSString *) localizedPropertyName: (ABPropertyID) aProperty
{
return [(NSString *)ABPersonCopyLocalizedPropertyName(aProperty) autorelease];
}
+ (ABPropertyType) propertyType: (ABPropertyID) aProperty
{
return ABPersonGetTypeOfProperty(aProperty);
}
// Thanks to Eridius for suggestions re switch
+ (NSString *) propertyTypeString: (ABPropertyID) aProperty
{
switch (ABPersonGetTypeOfProperty(aProperty))
{
case kABInvalidPropertyType: return @"Invalid Property";
case kABStringPropertyType: return @"String";
case kABIntegerPropertyType: return @"Integer";
case kABRealPropertyType: return @"Float";
case kABDateTimePropertyType: return DATE_STRING;
case kABDictionaryPropertyType: return @"Dictionary";
case kABMultiStringPropertyType: return @"Multi String";
case kABMultiIntegerPropertyType: return @"Multi Integer";
case kABMultiRealPropertyType: return @"Multi Float";
case kABMultiDateTimePropertyType: return @"Multi Date";
case kABMultiDictionaryPropertyType: return @"Multi Dictionary";
default: return @"Invalid Property";
}
}
+ (NSString *) propertyString: (ABPropertyID) aProperty
{
/* switch (aProperty) // Sorry, this won't compile
{
case kABPersonFirstNameProperty: return FIRST_NAME_STRING;
case kABPersonMiddleNameProperty: return MIDDLE_NAME_STRING;
case kABPersonLastNameProperty: return LAST_NAME_STRING;
case kABPersonPrefixProperty: return PREFIX_STRING;
case kABPersonSuffixProperty: return SUFFIX_STRING;
case kABPersonNicknameProperty: return NICKNAME_STRING;
case kABPersonFirstNamePhoneticProperty: return PHONETIC_FIRST_STRING;
case kABPersonMiddleNamePhoneticProperty: return PHONETIC_MIDDLE_STRING;
case kABPersonLastNamePhoneticProperty: return PHONETIC_LAST_STRING;
case kABPersonOrganizationProperty: return ORGANIZATION_STRING;
case kABPersonJobTitleProperty: return JOBTITLE_STRING;
case kABPersonDepartmentProperty: return DEPARTMENT_STRING;
case kABPersonNoteProperty: return NOTE_STRING;
case kABPersonKindProperty: return KIND_STRING;
case kABPersonBirthdayProperty: return BIRTHDAY_STRING;
case kABPersonCreationDateProperty: return CREATION_DATE_STRING;
case kABPersonModificationDateProperty: return MODIFICATION_DATE_STRING;
case kABPersonEmailProperty: return EMAIL_STRING;
case kABPersonAddressProperty: return ADDRESS_STRING;
case kABPersonDateProperty: return DATE_STRING;
case kABPersonPhoneProperty: return PHONE_STRING;
case kABPersonInstantMessageProperty: return SMS_STRING;
case kABPersonURLProperty: return URL_STRING;
case kABPersonRelatedNamesProperty: return RELATED_STRING;
} */
if (aProperty == kABPersonFirstNameProperty) return FIRST_NAME_STRING;
if (aProperty == kABPersonMiddleNameProperty) return MIDDLE_NAME_STRING;
if (aProperty == kABPersonLastNameProperty) return LAST_NAME_STRING;
if (aProperty == kABPersonPrefixProperty) return PREFIX_STRING;
if (aProperty == kABPersonSuffixProperty) return SUFFIX_STRING;
if (aProperty == kABPersonNicknameProperty) return NICKNAME_STRING;
if (aProperty == kABPersonFirstNamePhoneticProperty) return PHONETIC_FIRST_STRING;
if (aProperty == kABPersonMiddleNamePhoneticProperty) return PHONETIC_MIDDLE_STRING;
if (aProperty == kABPersonLastNamePhoneticProperty) return PHONETIC_LAST_STRING;
if (aProperty == kABPersonOrganizationProperty) return ORGANIZATION_STRING;
if (aProperty == kABPersonJobTitleProperty) return JOBTITLE_STRING;
if (aProperty == kABPersonDepartmentProperty) return DEPARTMENT_STRING;
if (aProperty == kABPersonNoteProperty) return NOTE_STRING;
if (aProperty == kABPersonKindProperty) return KIND_STRING;
if (aProperty == kABPersonBirthdayProperty) return BIRTHDAY_STRING;
if (aProperty == kABPersonCreationDateProperty) return CREATION_DATE_STRING;
if (aProperty == kABPersonModificationDateProperty) return MODIFICATION_DATE_STRING;
if (aProperty == kABPersonEmailProperty) return EMAIL_STRING;
if (aProperty == kABPersonAddressProperty) return ADDRESS_STRING;
if (aProperty == kABPersonDateProperty) return DATE_STRING;
if (aProperty == kABPersonPhoneProperty) return PHONE_STRING;
if (aProperty == kABPersonInstantMessageProperty) return SMS_STRING;
if (aProperty == kABPersonURLProperty) return URL_STRING;
if (aProperty == kABPersonRelatedNamesProperty) return RELATED_STRING;
return nil;
}
+ (BOOL) propertyIsMultivalue: (ABPropertyID) aProperty;
{
if (aProperty == kABPersonFirstNameProperty) return NO;
if (aProperty == kABPersonMiddleNameProperty) return NO;
if (aProperty == kABPersonLastNameProperty) return NO;
if (aProperty == kABPersonPrefixProperty) return NO;
if (aProperty == kABPersonSuffixProperty) return NO;
if (aProperty == kABPersonNicknameProperty) return NO;
if (aProperty == kABPersonFirstNamePhoneticProperty) return NO;
if (aProperty == kABPersonMiddleNamePhoneticProperty) return NO;
if (aProperty == kABPersonLastNamePhoneticProperty) return NO;
if (aProperty == kABPersonOrganizationProperty) return NO;
if (aProperty == kABPersonJobTitleProperty) return NO;
if (aProperty == kABPersonDepartmentProperty) return NO;
if (aProperty == kABPersonNoteProperty) return NO;
if (aProperty == kABPersonKindProperty) return NO;
if (aProperty == kABPersonBirthdayProperty) return NO;
if (aProperty == kABPersonCreationDateProperty) return NO;
if (aProperty == kABPersonModificationDateProperty) return NO;
return YES;
/*
if (aProperty == kABPersonEmailProperty) return YES;
if (aProperty == kABPersonAddressProperty) return YES;
if (aProperty == kABPersonDateProperty) return YES;
if (aProperty == kABPersonPhoneProperty) return YES;
if (aProperty == kABPersonInstantMessageProperty) return YES;
if (aProperty == kABPersonURLProperty) return YES;
if (aProperty == kABPersonRelatedNamesProperty) return YES;
*/
}
+ (NSArray *) arrayForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record
{
// Recover the property for a given record
CFTypeRef theProperty = ABRecordCopyValue(record, anID);
NSArray *items = (NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty);
CFRelease(theProperty);
return [items autorelease];
}
+ (id) objectForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record
{
return [(id) ABRecordCopyValue(record, anID) autorelease];
}
+ (NSDictionary *) dictionaryWithValue: (id) value andLabel: (CFStringRef) label
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
if (value) [dict setObject:value forKey:@"value"];
if (label) [dict setObject:(NSString *)label forKey:@"label"];
return dict;
}
+ (NSDictionary *) addressWithStreet: (NSString *) street withCity: (NSString *) city
withState:(NSString *) state withZip: (NSString *) zip
withCountry: (NSString *) country withCode: (NSString *) code
{
NSMutableDictionary *md = [NSMutableDictionary dictionary];
if (street) [md setObject:street forKey:(NSString *) kABPersonAddressStreetKey];
if (city) [md setObject:city forKey:(NSString *) kABPersonAddressCityKey];
if (state) [md setObject:state forKey:(NSString *) kABPersonAddressStateKey];
if (zip) [md setObject:zip forKey:(NSString *) kABPersonAddressZIPKey];
if (country) [md setObject:country forKey:(NSString *) kABPersonAddressCountryKey];
if (code) [md setObject:code forKey:(NSString *) kABPersonAddressCountryCodeKey];
return md;
}
+ (NSDictionary *) smsWithService: (CFStringRef) service andUser: (NSString *) userName
{
NSMutableDictionary *sms = [NSMutableDictionary dictionary];
if (service) [sms setObject:(NSString *) service forKey:(NSString *) kABPersonInstantMessageServiceKey];
if (userName) [sms setObject:userName forKey:(NSString *) kABPersonInstantMessageUsernameKey];
return sms;
}
// Thanks to Eridius for suggestions re: error
- (BOOL) removeSelfFromAddressBook: (NSError **) error
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
if (!ABAddressBookRemoveRecord(addressBook, self.record, (CFErrorRef *) error)) return NO;
return ABAddressBookSave(addressBook, (CFErrorRef *) error);
}
#pragma mark Record ID and Type
- (ABRecordID) recordID {return ABRecordGetRecordID(record);}
- (ABRecordType) recordType {return ABRecordGetRecordType(record);}
- (BOOL) isPerson {return self.recordType == kABPersonType;}
#pragma mark Getting Single Value Strings
- (NSString *) getRecordString:(ABPropertyID) anID
{
return [(NSString *) ABRecordCopyValue(record, anID) autorelease];
}
- (NSString *) firstname {return [self getRecordString:kABPersonFirstNameProperty];}
- (NSString *) middlename {return [self getRecordString:kABPersonMiddleNameProperty];}
- (NSString *) lastname {return [self getRecordString:kABPersonLastNameProperty];}
- (NSString *) prefix {return [self getRecordString:kABPersonPrefixProperty];}
- (NSString *) suffix {return [self getRecordString:kABPersonSuffixProperty];}
- (NSString *) nickname {return [self getRecordString:kABPersonNicknameProperty];}
- (NSString *) firstnamephonetic {return [self getRecordString:kABPersonFirstNamePhoneticProperty];}
- (NSString *) middlenamephonetic {return [self getRecordString:kABPersonMiddleNamePhoneticProperty];}
- (NSString *) lastnamephonetic {return [self getRecordString:kABPersonLastNamePhoneticProperty];}
- (NSString *) organization {return [self getRecordString:kABPersonOrganizationProperty];}
- (NSString *) jobtitle {return [self getRecordString:kABPersonJobTitleProperty];}
- (NSString *) department {return [self getRecordString:kABPersonDepartmentProperty];}
- (NSString *) note {return [self getRecordString:kABPersonNoteProperty];}
#pragma mark Contact Name Utility
- (NSString *) contactName
{
NSMutableString *string = [NSMutableString string];
if (self.firstname || self.lastname)
{
if (self.prefix) [string appendFormat:@"%@ ", self.prefix];
if (self.firstname) [string appendFormat:@"%@ ", self.firstname];
if (self.nickname) [string appendFormat:@"\"%@\" ", self.nickname];
if (self.lastname) [string appendFormat:@"%@", self.lastname];
if (self.suffix && string.length)
[string appendFormat:@", %@ ", self.suffix];
else
[string appendFormat:@" "];
}
if (self.organization) [string appendString:self.organization];
return [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (NSString *) compositeName
{
NSString *string = (NSString *)ABRecordCopyCompositeName(record);
return [string autorelease];
}
#pragma mark NUMBER
- (NSNumber *) getRecordNumber: (ABPropertyID) anID
{
return [(NSNumber *) ABRecordCopyValue(record, anID) autorelease];
}
- (NSNumber *) kind {return [self getRecordNumber:kABPersonKindProperty];}
#pragma mark Dates
- (NSDate *) getRecordDate:(ABPropertyID) anID
{
return [(NSDate *) ABRecordCopyValue(record, anID) autorelease];
}
- (NSDate *) birthday {return [self getRecordDate:kABPersonBirthdayProperty];}
- (NSDate *) creationDate {return [self getRecordDate:kABPersonCreationDateProperty];}
- (NSDate *) modificationDate {return [self getRecordDate:kABPersonModificationDateProperty];}
#pragma mark Getting MultiValue Elements
- (NSArray *) arrayForProperty: (ABPropertyID) anID
{
CFTypeRef theProperty = ABRecordCopyValue(record, anID);
NSArray *items = (NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty);
CFRelease(theProperty);
return [items autorelease];
}
- (NSArray *) labelsForProperty: (ABPropertyID) anID
{
CFTypeRef theProperty = ABRecordCopyValue(record, anID);
NSMutableArray *labels = [NSMutableArray array];
for (int i = 0; i < ABMultiValueGetCount(theProperty); i++)
{
NSString *label = (NSString *)ABMultiValueCopyLabelAtIndex(theProperty, i);
[labels addObject:label];
[label release];
}
CFRelease(theProperty);
return labels;
}
- (NSArray *) emailArray {return [self arrayForProperty:kABPersonEmailProperty];}
- (NSArray *) emailLabels {return [self labelsForProperty:kABPersonEmailProperty];}
- (NSArray *) phoneArray {return [self arrayForProperty:kABPersonPhoneProperty];}
- (NSArray *) phoneLabels {return [self labelsForProperty:kABPersonPhoneProperty];}
- (NSArray *) relatedNameArray {return [self arrayForProperty:kABPersonRelatedNamesProperty];}
- (NSArray *) relatedNameLabels {return [self labelsForProperty:kABPersonRelatedNamesProperty];}
- (NSArray *) urlArray {return [self arrayForProperty:kABPersonURLProperty];}
- (NSArray *) urlLabels {return [self labelsForProperty:kABPersonURLProperty];}
- (NSArray *) dateArray {return [self arrayForProperty:kABPersonDateProperty];}
- (NSArray *) dateLabels {return [self labelsForProperty:kABPersonDateProperty];}
- (NSArray *) addressArray {return [self arrayForProperty:kABPersonAddressProperty];}
- (NSArray *) addressLabels {return [self labelsForProperty:kABPersonAddressProperty];}
- (NSArray *) smsArray {return [self arrayForProperty:kABPersonInstantMessageProperty];}
- (NSArray *) smsLabels {return [self labelsForProperty:kABPersonInstantMessageProperty];}
- (NSString *) phonenumbers {return [self.phoneArray componentsJoinedByString:@" "];}
- (NSString *) emailaddresses {return [self.emailArray componentsJoinedByString:@" "];}
- (NSString *) urls {return [self.urlArray componentsJoinedByString:@" "];}
- (NSArray *) dictionaryArrayForProperty: (ABPropertyID) aProperty
{
NSArray *valueArray = [self arrayForProperty:aProperty];
NSArray *labelArray = [self labelsForProperty:aProperty];
int num = MIN(valueArray.count, labelArray.count);
NSMutableArray *items = [NSMutableArray array];
for (int i = 0; i < num; i++)
{
NSMutableDictionary *md = [NSMutableDictionary dictionary];
[md setObject:[valueArray objectAtIndex:i] forKey:@"value"];
[md setObject:[labelArray objectAtIndex:i] forKey:@"label"];
[items addObject:md];
}
return items;
}
- (NSArray *) emailDictionaries
{
return [self dictionaryArrayForProperty:kABPersonEmailProperty];
}
- (NSArray *) phoneDictionaries
{
return [self dictionaryArrayForProperty:kABPersonPhoneProperty];
}
- (NSArray *) relatedNameDictionaries
{
return [self dictionaryArrayForProperty:kABPersonRelatedNamesProperty];
}
- (NSArray *) urlDictionaries
{
return [self dictionaryArrayForProperty:kABPersonURLProperty];
}
- (NSArray *) dateDictionaries
{
return [self dictionaryArrayForProperty:kABPersonDateProperty];
}
- (NSArray *) addressDictionaries
{
return [self dictionaryArrayForProperty:kABPersonAddressProperty];
}
- (NSArray *) smsDictionaries
{
return [self dictionaryArrayForProperty:kABPersonInstantMessageProperty];
}
#pragma mark Setting Strings
- (BOOL) setString: (NSString *) aString forProperty:(ABPropertyID) anID
{
CFErrorRef error;
BOOL success = ABRecordSetValue(record, anID, (CFStringRef) aString, &error);
if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]);
return success;
}
- (void) setFirstname: (NSString *) aString {[self setString: aString forProperty: kABPersonFirstNameProperty];}
- (void) setMiddlename: (NSString *) aString {[self setString: aString forProperty: kABPersonMiddleNameProperty];}
- (void) setLastname: (NSString *) aString {[self setString: aString forProperty: kABPersonLastNameProperty];}
- (void) setPrefix: (NSString *) aString {[self setString: aString forProperty: kABPersonPrefixProperty];}
- (void) setSuffix: (NSString *) aString {[self setString: aString forProperty: kABPersonSuffixProperty];}
- (void) setNickname: (NSString *) aString {[self setString: aString forProperty: kABPersonNicknameProperty];}
- (void) setFirstnamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonFirstNamePhoneticProperty];}
- (void) setMiddlenamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonMiddleNamePhoneticProperty];}
- (void) setLastnamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonLastNamePhoneticProperty];}
- (void) setOrganization: (NSString *) aString {[self setString: aString forProperty: kABPersonOrganizationProperty];}
- (void) setJobtitle: (NSString *) aString {[self setString: aString forProperty: kABPersonJobTitleProperty];}
- (void) setDepartment: (NSString *) aString {[self setString: aString forProperty: kABPersonDepartmentProperty];}
- (void) setNote: (NSString *) aString {[self setString: aString forProperty: kABPersonNoteProperty];}
#pragma mark Setting Numbers
- (BOOL) setNumber: (NSNumber *) aNumber forProperty:(ABPropertyID) anID
{
CFErrorRef error;
BOOL success = ABRecordSetValue(record, anID, (CFNumberRef) aNumber, &error);
if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]);
return success;
}
// const CFNumberRef kABPersonKindPerson;
// const CFNumberRef kABPersonKindOrganization;
- (void) setKind: (NSNumber *) aKind {[self setNumber:aKind forProperty: kABPersonKindProperty];}
#pragma mark Setting Dates
- (BOOL) setDate: (NSDate *) aDate forProperty:(ABPropertyID) anID
{
CFErrorRef error;
BOOL success = ABRecordSetValue(record, anID, (CFDateRef) aDate, &error);
if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]);
return success;
}
- (void) setBirthday: (NSDate *) aDate {[self setDate: aDate forProperty: kABPersonBirthdayProperty];}
#pragma mark Setting MultiValue
- (BOOL) setMulti: (ABMutableMultiValueRef) multi forProperty: (ABPropertyID) anID
{
CFErrorRef error;
BOOL success = ABRecordSetValue(record, anID, multi, &error);
if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]);
return success;
}
- (ABMutableMultiValueRef) createMultiValueFromArray: (NSArray *) anArray withType: (ABPropertyType) aType
{
ABMutableMultiValueRef multi = ABMultiValueCreateMutable(aType);
for (NSDictionary *dict in anArray)
ABMultiValueAddValueAndLabel(multi, (CFTypeRef) [dict objectForKey:@"value"], (CFTypeRef) [dict objectForKey:@"label"], NULL);
return CFAutorelease(multi);
}
- (void) setEmailDictionaries: (NSArray *) dictionaries
{
// kABWorkLabel, kABHomeLabel, kABOtherLabel
ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType];
[self setMulti:multi forProperty:kABPersonEmailProperty];
// CFRelease(multi);
}
- (void) setPhoneDictionaries: (NSArray *) dictionaries
{
// kABWorkLabel, kABHomeLabel, kABOtherLabel
// kABPersonPhoneMobileLabel, kABPersonPhoneIPhoneLabel, kABPersonPhoneMainLabel
// kABPersonPhoneHomeFAXLabel, kABPersonPhoneWorkFAXLabel, kABPersonPhonePagerLabel
ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType];
[self setMulti:multi forProperty:kABPersonPhoneProperty];
// CFRelease(multi);
}
- (void) setUrlDictionaries: (NSArray *) dictionaries
{
// kABWorkLabel, kABHomeLabel, kABOtherLabel
// kABPersonHomePageLabel
ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType];
[self setMulti:multi forProperty:kABPersonURLProperty];
// CFRelease(multi);
}
// Not used/shown on iPhone
- (void) setRelatedNameDictionaries: (NSArray *) dictionaries
{
// kABWorkLabel, kABHomeLabel, kABOtherLabel
// kABPersonMotherLabel, kABPersonFatherLabel, kABPersonParentLabel,
// kABPersonSisterLabel, kABPersonBrotherLabel, kABPersonChildLabel,
// kABPersonFriendLabel, kABPersonSpouseLabel, kABPersonPartnerLabel,
// kABPersonManagerLabel, kABPersonAssistantLabel
ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType];
[self setMulti:multi forProperty:kABPersonRelatedNamesProperty];
// CFRelease(multi);
}
- (void) setDateDictionaries: (NSArray *) dictionaries
{
// kABWorkLabel, kABHomeLabel, kABOtherLabel
// kABPersonAnniversaryLabel
ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiDateTimePropertyType];
[self setMulti:multi forProperty:kABPersonDateProperty];
// CFRelease(multi);
}
- (void) setAddressDictionaries: (NSArray *) dictionaries
{
// kABPersonAddressStreetKey, kABPersonAddressCityKey, kABPersonAddressStateKey
// kABPersonAddressZIPKey, kABPersonAddressCountryKey, kABPersonAddressCountryCodeKey
ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiDictionaryPropertyType];
[self setMulti:multi forProperty:kABPersonAddressProperty];
// CFRelease(multi);
}
- (void) setSmsDictionaries: (NSArray *) dictionaries
{
// kABWorkLabel, kABHomeLabel, kABOtherLabel,
// kABPersonInstantMessageServiceKey, kABPersonInstantMessageUsernameKey
// kABPersonInstantMessageServiceYahoo, kABPersonInstantMessageServiceJabber
// kABPersonInstantMessageServiceMSN, kABPersonInstantMessageServiceICQ
// kABPersonInstantMessageServiceAIM,
ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiDictionaryPropertyType];
[self setMulti:multi forProperty:kABPersonInstantMessageProperty];
// CFRelease(multi);
}
#pragma mark Images
- (UIImage *) image
{
if (!ABPersonHasImageData(record)) return nil;
CFDataRef imageData = ABPersonCopyImageData(record);
UIImage *image = [UIImage imageWithData:(NSData *) imageData];
CFRelease(imageData);
return image;
}
- (void) setImage: (UIImage *) image
{
CFErrorRef error;
BOOL success;
if (image == nil) // remove
{
if (!ABPersonHasImageData(record)) return; // no image to remove
success = ABPersonRemoveImageData(record, &error);
if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]);
return;
}
NSData *data = UIImagePNGRepresentation(image);
success = ABPersonSetImageData(record, (CFDataRef) data, &error);
if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]);
}
#pragma mark Representations
// No Image
- (NSDictionary *) baseDictionaryRepresentation
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
if (self.firstname) [dict setObject:self.firstname forKey:FIRST_NAME_STRING];
if (self.middlename) [dict setObject:self.middlename forKey:MIDDLE_NAME_STRING];
if (self.lastname) [dict setObject:self.lastname forKey:LAST_NAME_STRING];
if (self.prefix) [dict setObject:self.prefix forKey:PREFIX_STRING];
if (self.suffix) [dict setObject:self.suffix forKey:SUFFIX_STRING];
if (self.nickname) [dict setObject:self.nickname forKey:NICKNAME_STRING];
if (self.firstnamephonetic) [dict setObject:self.firstnamephonetic forKey:PHONETIC_FIRST_STRING];
if (self.middlenamephonetic) [dict setObject:self.middlenamephonetic forKey:PHONETIC_MIDDLE_STRING];
if (self.lastnamephonetic) [dict setObject:self.lastnamephonetic forKey:PHONETIC_LAST_STRING];
if (self.organization) [dict setObject:self.organization forKey:ORGANIZATION_STRING];
if (self.jobtitle) [dict setObject:self.jobtitle forKey:JOBTITLE_STRING];
if (self.department) [dict setObject:self.department forKey:DEPARTMENT_STRING];
if (self.note) [dict setObject:self.note forKey:NOTE_STRING];
if (self.kind) [dict setObject:self.kind forKey:KIND_STRING];
if (self.birthday) [dict setObject:self.birthday forKey:BIRTHDAY_STRING];
if (self.creationDate) [dict setObject:self.creationDate forKey:CREATION_DATE_STRING];
if (self.modificationDate) [dict setObject:self.modificationDate forKey:MODIFICATION_DATE_STRING];
[dict setObject:self.emailDictionaries forKey:EMAIL_STRING];
[dict setObject:self.addressDictionaries forKey:ADDRESS_STRING];
[dict setObject:self.dateDictionaries forKey:DATE_STRING];
[dict setObject:self.phoneDictionaries forKey:PHONE_STRING];
[dict setObject:self.smsDictionaries forKey:SMS_STRING];
[dict setObject:self.urlDictionaries forKey:URL_STRING];
[dict setObject:self.relatedNameDictionaries forKey:RELATED_STRING];
return dict;
}
// With image where available
- (NSDictionary *) dictionaryRepresentation
{
NSMutableDictionary *dict = [[[self baseDictionaryRepresentation] mutableCopy] autorelease];
if (ABPersonHasImageData(record))
{
CFDataRef imageData = ABPersonCopyImageData(record);
[dict setObject:(NSData *)imageData forKey:IMAGE_STRING];
CFRelease(imageData);
}
return dict;
}
// No Image
- (NSData *) baseDataRepresentation
{
NSString *errorString;
NSDictionary *dict = [self baseDictionaryRepresentation];
NSData *data = [NSPropertyListSerialization dataFromPropertyList:dict format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString];
if (!data) CFShow(errorString);
return data;
}
// With image where available
- (NSData *) dataRepresentation
{
NSString *errorString;
NSDictionary *dict = [self dictionaryRepresentation];
NSData *data = [NSPropertyListSerialization dataFromPropertyList:dict format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString];
if (!data) CFShow(errorString);
return data;
}
+ (id) contactWithDictionary: (NSDictionary *) dict
{
ABContact *contact = [ABContact contact];
if ([dict objectForKey:FIRST_NAME_STRING]) contact.firstname = [dict objectForKey:FIRST_NAME_STRING];
if ([dict objectForKey:MIDDLE_NAME_STRING]) contact.middlename = [dict objectForKey:MIDDLE_NAME_STRING];
if ([dict objectForKey:LAST_NAME_STRING]) contact.lastname = [dict objectForKey:LAST_NAME_STRING];
if ([dict objectForKey:PREFIX_STRING]) contact.prefix = [dict objectForKey:PREFIX_STRING];
if ([dict objectForKey:SUFFIX_STRING]) contact.suffix = [dict objectForKey:SUFFIX_STRING];
if ([dict objectForKey:NICKNAME_STRING]) contact.nickname = [dict objectForKey:NICKNAME_STRING];
if ([dict objectForKey:PHONETIC_FIRST_STRING]) contact.firstnamephonetic = [dict objectForKey:PHONETIC_FIRST_STRING];
if ([dict objectForKey:PHONETIC_MIDDLE_STRING]) contact.middlenamephonetic = [dict objectForKey:PHONETIC_MIDDLE_STRING];
if ([dict objectForKey:PHONETIC_LAST_STRING]) contact.lastnamephonetic = [dict objectForKey:PHONETIC_LAST_STRING];
if ([dict objectForKey:ORGANIZATION_STRING]) contact.organization = [dict objectForKey:ORGANIZATION_STRING];
if ([dict objectForKey:JOBTITLE_STRING]) contact.jobtitle = [dict objectForKey:JOBTITLE_STRING];
if ([dict objectForKey:DEPARTMENT_STRING]) contact.department = [dict objectForKey:DEPARTMENT_STRING];
if ([dict objectForKey:NOTE_STRING]) contact.note = [dict objectForKey:NOTE_STRING];
if ([dict objectForKey:KIND_STRING]) contact.kind = [dict objectForKey:KIND_STRING];
if ([dict objectForKey:EMAIL_STRING]) contact.emailDictionaries = [dict objectForKey:EMAIL_STRING];
if ([dict objectForKey:ADDRESS_STRING]) contact.addressDictionaries = [dict objectForKey:ADDRESS_STRING];
if ([dict objectForKey:DATE_STRING]) contact.dateDictionaries = [dict objectForKey:DATE_STRING];
if ([dict objectForKey:PHONE_STRING]) contact.phoneDictionaries = [dict objectForKey:PHONE_STRING];
if ([dict objectForKey:SMS_STRING]) contact.smsDictionaries = [dict objectForKey:SMS_STRING];
if ([dict objectForKey:URL_STRING]) contact.urlDictionaries = [dict objectForKey:URL_STRING];
if ([dict objectForKey:RELATED_STRING]) contact.relatedNameDictionaries = [dict objectForKey:RELATED_STRING];
if ([dict objectForKey:IMAGE_STRING])
{
CFErrorRef error;
BOOL success = ABPersonSetImageData(contact.record, (CFDataRef) [dict objectForKey:IMAGE_STRING], &error);
if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]);
}
return contact;
}
+ (id) contactWithData: (NSData *) data
{
// Otherwise handle points
CFStringRef errorString;
CFPropertyListRef plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, (CFDataRef)data, kCFPropertyListMutableContainers, &errorString);
if (!plist)
{
CFShow(errorString);
return nil;
}
NSDictionary *dict = (NSDictionary *) plist;
[dict autorelease];
return [self contactWithDictionary:dict];
}
@end
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License, Use at your own risk
*/
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import "ABContact.h"
#import "ABGroup.h"
@interface ABContactsHelper : NSObject
// Address Book
+ (ABAddressBookRef) addressBook;
// Address Book Contacts and Groups
+ (NSArray *) contacts; // people
+ (NSArray *) groups; // groups
// Counting
+ (int) contactsCount;
+ (int) contactsWithImageCount;
+ (int) contactsWithoutImageCount;
+ (int) numberOfGroups;
// Sorting
+ (BOOL) firstNameSorting;
// Add contacts and groups
+ (BOOL) addContact: (ABContact *) aContact withError: (NSError **) error;
+ (BOOL) addGroup: (ABGroup *) aGroup withError: (NSError **) error;
// Find contacts
+ (NSArray *) contactsMatchingName: (NSString *) fname;
+ (NSArray *) contactsMatchingName: (NSString *) fname andName: (NSString *) lname;
+ (NSArray *) contactsMatchingPhone: (NSString *) number;
// Find groups
+ (NSArray *) groupsMatchingName: (NSString *) fname;
@end
// For the simple utility of it. Feel free to comment out if desired
@interface NSString (cstring)
@property (readonly) char *UTF8String;
@end
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License, Use at your own risk
*/
#import "ABContactsHelper.h"
#define CFAutorelease(obj) ({CFTypeRef _obj = (obj); (_obj == NULL) ? NULL : [(id)CFMakeCollectable(_obj) autorelease]; })
@implementation ABContactsHelper
/*
Note: You cannot CFRelease the addressbook after CFAutorelease(ABAddressBookCreate());
*/
+ (ABAddressBookRef) addressBook
{
return CFAutorelease(ABAddressBookCreate());
}
+ (NSArray *) contacts
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSMutableArray *array = [NSMutableArray arrayWithCapacity:thePeople.count];
for (id person in thePeople)
[array addObject:[ABContact contactWithRecord:(ABRecordRef)person]];
[thePeople release];
return array;
}
+ (int) contactsCount
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
return ABAddressBookGetPersonCount(addressBook);
}
+ (int) contactsWithImageCount
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
NSArray *peopleArray = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
int ncount = 0;
for (id person in peopleArray) if (ABPersonHasImageData(person)) ncount++;
[peopleArray release];
return ncount;
}
+ (int) contactsWithoutImageCount
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
NSArray *peopleArray = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
int ncount = 0;
for (id person in peopleArray) if (!ABPersonHasImageData(person)) ncount++;
[peopleArray release];
return ncount;
}
// Groups
+ (int) numberOfGroups
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
NSArray *groups = (NSArray *)ABAddressBookCopyArrayOfAllGroups(addressBook);
int ncount = groups.count;
[groups release];
return ncount;
}
+ (NSArray *) groups
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
NSArray *groups = (NSArray *)ABAddressBookCopyArrayOfAllGroups(addressBook);
NSMutableArray *array = [NSMutableArray arrayWithCapacity:groups.count];
for (id group in groups)
[array addObject:[ABGroup groupWithRecord:(ABRecordRef)group]];
[groups release];
return array;
}
// Sorting
+ (BOOL) firstNameSorting
{
return (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst);
}
#pragma mark Contact Management
// Thanks to Eridius for suggestions re: error
+ (BOOL) addContact: (ABContact *) aContact withError: (NSError **) error
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
if (!ABAddressBookAddRecord(addressBook, aContact.record, (CFErrorRef *) error)) return NO;
return ABAddressBookSave(addressBook, (CFErrorRef *) error);
}
+ (BOOL) addGroup: (ABGroup *) aGroup withError: (NSError **) error
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
if (!ABAddressBookAddRecord(addressBook, aGroup.record, (CFErrorRef *) error)) return NO;
return ABAddressBookSave(addressBook, (CFErrorRef *) error);
}
+ (NSArray *) contactsMatchingName: (NSString *) fname
{
NSPredicate *pred;
NSArray *contacts = [ABContactsHelper contacts];
pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", fname, fname, fname, fname];
return [contacts filteredArrayUsingPredicate:pred];
}
+ (NSArray *) contactsMatchingName: (NSString *) fname andName: (NSString *) lname
{
NSPredicate *pred;
NSArray *contacts = [ABContactsHelper contacts];
pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", fname, fname, fname, fname];
contacts = [contacts filteredArrayUsingPredicate:pred];
pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", lname, lname, lname, lname];
contacts = [contacts filteredArrayUsingPredicate:pred];
return contacts;
}
+ (NSArray *) contactsMatchingPhone: (NSString *) number
{
NSPredicate *pred;
NSArray *contacts = [ABContactsHelper contacts];
pred = [NSPredicate predicateWithFormat:@"phonenumbers contains[cd] %@", number];
return [contacts filteredArrayUsingPredicate:pred];
}
+ (NSArray *) groupsMatchingName: (NSString *) fname
{
NSPredicate *pred;
NSArray *groups = [ABContactsHelper groups];
pred = [NSPredicate predicateWithFormat:@"name contains[cd] %@ ", fname];
return [groups filteredArrayUsingPredicate:pred];
}
@end
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License, Use at your own risk
*/
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import "ABContact.h"
@interface ABGroup : NSObject
{
ABRecordRef record;
}
+ (id) group;
+ (id) groupWithRecord: (ABRecordRef) record;
+ (id) groupWithRecordID: (ABRecordID) recordID;
- (BOOL) removeSelfFromAddressBook: (NSError **) error;
@property (nonatomic, readonly) ABRecordRef record;
@property (nonatomic, readonly) ABRecordID recordID;
@property (nonatomic, readonly) ABRecordType recordType;
@property (nonatomic, readonly) BOOL isPerson;
- (NSArray *) membersWithSorting: (ABPersonSortOrdering) ordering;
- (BOOL) addMember: (ABContact *) contact withError: (NSError **) error;
- (BOOL) removeMember: (ABContact *) contact withError: (NSError **) error;
@property (nonatomic, assign) NSString *name;
@property (nonatomic, readonly) NSArray *members;
@end
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License, Use at your own risk
*/
#import "ABGroup.h"
#import "ABContactsHelper.h"
#define CFAutorelease(obj) ({CFTypeRef _obj = (obj); (_obj == NULL) ? NULL : [(id)CFMakeCollectable(_obj) autorelease]; })
@implementation ABGroup
@synthesize record;
// Thanks to Quentarez, Ciaran
- (id) initWithRecord: (ABRecordRef) aRecord
{
if (self = [super init]) record = CFRetain(aRecord);
return self;
}
+ (id) groupWithRecord: (ABRecordRef) grouprec
{
return [[[ABGroup alloc] initWithRecord:grouprec] autorelease];
}
+ (id) groupWithRecordID: (ABRecordID) recordID
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
ABRecordRef grouprec = ABAddressBookGetGroupWithRecordID(addressBook, recordID);
ABGroup *group = [self groupWithRecord:grouprec];
CFRelease(grouprec);
return group;
}
// Thanks to Ciaran
+ (id) group
{
ABRecordRef grouprec = ABGroupCreate();
id group = [ABGroup groupWithRecord:grouprec];
CFRelease(grouprec);
return group;
}
- (void) dealloc
{
if (record) CFRelease(record);
[super dealloc];
}
- (BOOL) removeSelfFromAddressBook: (NSError **) error
{
ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
if (!ABAddressBookRemoveRecord(addressBook, self.record, (CFErrorRef *) error)) return NO;
return ABAddressBookSave(addressBook, (CFErrorRef *) error);
}
#pragma mark Record ID and Type
- (ABRecordID) recordID {return ABRecordGetRecordID(record);}
- (ABRecordType) recordType {return ABRecordGetRecordType(record);}
- (BOOL) isPerson {return self.recordType == kABPersonType;}
#pragma mark management
- (NSArray *) members
{
NSArray *contacts = (NSArray *)ABGroupCopyArrayOfAllMembers(self.record);
NSMutableArray *array = [NSMutableArray arrayWithCapacity:contacts.count];
for (id contact in contacts)
[array addObject:[ABContact contactWithRecord:(ABRecordRef)contact]];
[contacts release];
return array;
}
// kABPersonSortByFirstName = 0, kABPersonSortByLastName = 1
- (NSArray *) membersWithSorting: (ABPersonSortOrdering) ordering
{
NSArray *contacts = (NSArray *)ABGroupCopyArrayOfAllMembersWithSortOrdering(self.record, ordering);
NSMutableArray *array = [NSMutableArray arrayWithCapacity:contacts.count];
for (id contact in contacts)
[array addObject:[ABContact contactWithRecord:(ABRecordRef)contact]];
[contacts release];
return array;
}
- (BOOL) addMember: (ABContact *) contact withError: (NSError **) error
{
return ABGroupAddMember(self.record, contact.record, (CFErrorRef *) error);
}
- (BOOL) removeMember: (ABContact *) contact withError: (NSError **) error
{
return ABGroupRemoveMember(self.record, contact.record, (CFErrorRef *) error);
}
#pragma mark name
- (NSString *) getRecordString:(ABPropertyID) anID
{
return [(NSString *) ABRecordCopyValue(record, anID) autorelease];
}
- (NSString *) name
{
NSString *string = [self getRecordString:kABGroupNameProperty];
return string;
}
- (void) setName: (NSString *) aString
{
CFErrorRef error;
BOOL success = ABRecordSetValue(record, kABGroupNameProperty, (CFStringRef) aString, &error);
if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]);
}
@end