From 1dff44bfa49d5c9a59765171216b2e971feee8ad Mon Sep 17 00:00:00 2001 From: Alexey Belkevich Date: Mon, 13 Jan 2014 17:37:52 +0200 Subject: [PATCH] Added sorting, filtering and checking necessary data --- .../AddressBook.xcodeproj/project.pbxproj | 20 ++---- .../AddressBook/ContactTableViewCell.m | 29 +++++++- .../AddressBook/ContactTableViewCell.xib | 59 +++++++++++++++++ .../AddressBook/ContactViewController.h | 13 ---- .../AddressBook/ContactViewController.m | 38 ----------- .../no_photo.imageset/Contents.json | 18 +++++ .../no_photo.imageset/no_photo.png | Bin 0 -> 4248 bytes .../no_photo.imageset/no_photo@2x.png | Bin 0 -> 11136 bytes AddressBook/AddressBook/ListViewController.m | 17 ++++- AddressBook/AddressBook/Storyboard.storyboard | 20 ------ Classes/APAddressBook.h | 12 ++-- Classes/APAddressBook.m | 51 ++++---------- Classes/APContact.h | 14 +++- Classes/APContact.m | 62 ++++++++++++++++++ Classes/APTypes.h | 37 +++++++++++ 15 files changed, 253 insertions(+), 137 deletions(-) create mode 100644 AddressBook/AddressBook/ContactTableViewCell.xib delete mode 100644 AddressBook/AddressBook/ContactViewController.h delete mode 100644 AddressBook/AddressBook/ContactViewController.m create mode 100644 AddressBook/AddressBook/Images.xcassets/no_photo.imageset/Contents.json create mode 100644 AddressBook/AddressBook/Images.xcassets/no_photo.imageset/no_photo.png create mode 100644 AddressBook/AddressBook/Images.xcassets/no_photo.imageset/no_photo@2x.png create mode 100644 Classes/APTypes.h diff --git a/AddressBook/AddressBook.xcodeproj/project.pbxproj b/AddressBook/AddressBook.xcodeproj/project.pbxproj index 12627df..adb46db 100644 --- a/AddressBook/AddressBook.xcodeproj/project.pbxproj +++ b/AddressBook/AddressBook.xcodeproj/project.pbxproj @@ -17,11 +17,11 @@ FA66282E187FE9EF00667C81 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA66282D187FE9EF00667C81 /* Images.xcassets */; }; FA66284E187FEC1400667C81 /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA66284D187FEC1400667C81 /* Storyboard.storyboard */; }; FA662854187FEC7F00667C81 /* ListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA662853187FEC7F00667C81 /* ListViewController.m */; }; - FA662858187FEC9600667C81 /* ContactViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA662857187FEC9600667C81 /* ContactViewController.m */; }; FA66285C187FFACD00667C81 /* APAddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = FA66285B187FFACD00667C81 /* APAddressBook.m */; }; FA662860187FFB2100667C81 /* APContact.m in Sources */ = {isa = PBXBuildFile; fileRef = FA66285F187FFB2100667C81 /* APContact.m */; }; FA662862187FFCA700667C81 /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA662861187FFCA700667C81 /* AddressBook.framework */; }; FA66286618800DC500667C81 /* ContactTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA66286518800DC500667C81 /* ContactTableViewCell.m */; }; + FAD1CCE91881A18900D03475 /* ContactTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FAD1CCE81881A18900D03475 /* ContactTableViewCell.xib */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -41,8 +41,6 @@ FA66284D187FEC1400667C81 /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; }; FA662852187FEC7F00667C81 /* ListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListViewController.h; sourceTree = ""; }; FA662853187FEC7F00667C81 /* ListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ListViewController.m; sourceTree = ""; }; - FA662856187FEC9600667C81 /* ContactViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactViewController.h; sourceTree = ""; }; - FA662857187FEC9600667C81 /* ContactViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactViewController.m; sourceTree = ""; }; FA66285A187FFACD00667C81 /* APAddressBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = APAddressBook.h; path = ../Classes/APAddressBook.h; sourceTree = ""; }; FA66285B187FFACD00667C81 /* APAddressBook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = APAddressBook.m; path = ../Classes/APAddressBook.m; sourceTree = ""; }; FA66285E187FFB2100667C81 /* APContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = APContact.h; path = ../Classes/APContact.h; sourceTree = ""; }; @@ -50,6 +48,8 @@ FA662861187FFCA700667C81 /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; }; FA66286418800DC500667C81 /* ContactTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactTableViewCell.h; sourceTree = ""; }; FA66286518800DC500667C81 /* ContactTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactTableViewCell.m; sourceTree = ""; }; + FAD1CCE718819F7000D03475 /* APTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = APTypes.h; path = ../Classes/APTypes.h; sourceTree = ""; }; + FAD1CCE81881A18900D03475 /* ContactTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContactTableViewCell.xib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -135,7 +135,6 @@ isa = PBXGroup; children = ( FA662855187FEC8500667C81 /* List */, - FA662859187FECBE00667C81 /* Contact */, ); name = Controllers; sourceTree = ""; @@ -158,15 +157,6 @@ name = List; sourceTree = ""; }; - FA662859187FECBE00667C81 /* Contact */ = { - isa = PBXGroup; - children = ( - FA662856187FEC9600667C81 /* ContactViewController.h */, - FA662857187FEC9600667C81 /* ContactViewController.m */, - ); - name = Contact; - sourceTree = ""; - }; FA66285D187FFAD300667C81 /* Classes */ = { isa = PBXGroup; children = ( @@ -174,6 +164,7 @@ FA66285B187FFACD00667C81 /* APAddressBook.m */, FA66285E187FFB2100667C81 /* APContact.h */, FA66285F187FFB2100667C81 /* APContact.m */, + FAD1CCE718819F7000D03475 /* APTypes.h */, ); name = Classes; sourceTree = ""; @@ -191,6 +182,7 @@ children = ( FA66286418800DC500667C81 /* ContactTableViewCell.h */, FA66286518800DC500667C81 /* ContactTableViewCell.m */, + FAD1CCE81881A18900D03475 /* ContactTableViewCell.xib */, ); name = Cells; sourceTree = ""; @@ -248,6 +240,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + FAD1CCE91881A18900D03475 /* ContactTableViewCell.xib in Resources */, FA662826187FE9EF00667C81 /* InfoPlist.strings in Resources */, FA66282E187FE9EF00667C81 /* Images.xcassets in Resources */, FA66284E187FEC1400667C81 /* Storyboard.storyboard in Resources */, @@ -297,7 +290,6 @@ FA66282C187FE9EF00667C81 /* AppDelegate.m in Sources */, FA66285C187FFACD00667C81 /* APAddressBook.m in Sources */, FA66286618800DC500667C81 /* ContactTableViewCell.m in Sources */, - FA662858187FEC9600667C81 /* ContactViewController.m in Sources */, FA662860187FFB2100667C81 /* APContact.m in Sources */, FA662828187FE9EF00667C81 /* main.m in Sources */, FA662854187FEC7F00667C81 /* ListViewController.m in Sources */, diff --git a/AddressBook/AddressBook/ContactTableViewCell.m b/AddressBook/AddressBook/ContactTableViewCell.m index be287fc..9158574 100644 --- a/AddressBook/AddressBook/ContactTableViewCell.m +++ b/AddressBook/AddressBook/ContactTableViewCell.m @@ -9,6 +9,14 @@ #import "ContactTableViewCell.h" #import "APContact.h" +@interface ContactTableViewCell () +@property (weak, nonatomic) IBOutlet UIImageView *photoView; +@property (weak, nonatomic) IBOutlet UILabel *nameLabel; +@property (weak, nonatomic) IBOutlet UILabel *companyLabel; +@property (weak, nonatomic) IBOutlet UILabel *phonesLabel; +@property (weak, nonatomic) IBOutlet UILabel *emailsLabel; +@end + @implementation ContactTableViewCell #pragma mark - life cycle @@ -28,8 +36,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus - (void)updateWithModel:(id)model { APContact *contact = model; - self.textLabel.text = [self contactName:contact]; - self.detailTextLabel.text = [self contactPhones:contact]; + self.nameLabel.text = [self contactName:contact]; + self.companyLabel.text = contact.company ?: @"(No company)"; + self.phonesLabel.text = [self contactPhones:contact]; + self.emailsLabel.text = [self contactEmails:contact]; + self.photoView.image = contact.photo ?: [UIImage imageNamed:@"no_photo"]; } #pragma mark - private @@ -58,7 +69,19 @@ - (NSString *)contactPhones:(APContact *)contact } else { - return contact.phones.firstObject ?: @"No phones"; + return contact.phones.firstObject ?: @"(No phones)"; + } +} + +- (NSString *)contactEmails:(APContact *)contact +{ + if (contact.emails.count > 1) + { + return [contact.emails componentsJoinedByString:@", "]; + } + else + { + return contact.emails.firstObject ?: @"(No emails)"; } } diff --git a/AddressBook/AddressBook/ContactTableViewCell.xib b/AddressBook/AddressBook/ContactTableViewCell.xib new file mode 100644 index 0000000..37d08d3 --- /dev/null +++ b/AddressBook/AddressBook/ContactTableViewCell.xib @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AddressBook/AddressBook/ContactViewController.h b/AddressBook/AddressBook/ContactViewController.h deleted file mode 100644 index 413912f..0000000 --- a/AddressBook/AddressBook/ContactViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// ContactViewController.h -// AddressBook -// -// Created by Alexey Belkevich on 1/10/14. -// Copyright (c) 2014 alterplay. All rights reserved. -// - -#import - -@interface ContactViewController : UIViewController - -@end diff --git a/AddressBook/AddressBook/ContactViewController.m b/AddressBook/AddressBook/ContactViewController.m deleted file mode 100644 index 6466f53..0000000 --- a/AddressBook/AddressBook/ContactViewController.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// ContactViewController.m -// AddressBook -// -// Created by Alexey Belkevich on 1/10/14. -// Copyright (c) 2014 alterplay. All rights reserved. -// - -#import "ContactViewController.h" - -@interface ContactViewController () - -@end - -@implementation ContactViewController - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -{ - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - // Custom initialization - } - return self; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - // Do any additional setup after loading the view. -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -@end diff --git a/AddressBook/AddressBook/Images.xcassets/no_photo.imageset/Contents.json b/AddressBook/AddressBook/Images.xcassets/no_photo.imageset/Contents.json new file mode 100644 index 0000000..dbc32db --- /dev/null +++ b/AddressBook/AddressBook/Images.xcassets/no_photo.imageset/Contents.json @@ -0,0 +1,18 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x", + "filename" : "no_photo.png" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "no_photo@2x.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/AddressBook/AddressBook/Images.xcassets/no_photo.imageset/no_photo.png b/AddressBook/AddressBook/Images.xcassets/no_photo.imageset/no_photo.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2a3c2e9598e492d16b560d18155d396d95f923 GIT binary patch literal 4248 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 literal 0 HcmV?d00001 diff --git a/AddressBook/AddressBook/ListViewController.m b/AddressBook/AddressBook/ListViewController.m index ff804a8..cca9f9c 100644 --- a/AddressBook/AddressBook/ListViewController.m +++ b/AddressBook/AddressBook/ListViewController.m @@ -10,7 +10,6 @@ #import "ContactTableViewCell.h" #import "APContact.h" #import "APAddressBook.h" -#import "ContactViewController.h" @interface ListViewController () @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activity; @@ -43,12 +42,18 @@ - (void)viewDidLoad [self loadContacts]; } +#pragma mark - table view data source implementation + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return 85.f; +} + #pragma mark - table view delegate implementation - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; - [self performSegueWithIdentifier:NSStringFromClass(ContactViewController.class) sender:self]; } #pragma mark - private @@ -57,6 +62,14 @@ - (void)loadContacts { [self.activity startAnimating]; __weak __typeof(self) weakSelf = self; + addressBook.fieldsMask = APContactFieldAll; + addressBook.sortDescriptors = @[ + [NSSortDescriptor sortDescriptorWithKey:@"firstName" ascending:YES], + [NSSortDescriptor sortDescriptorWithKey:@"lastName" ascending:YES]]; + addressBook.filterBlock = ^BOOL(APContact *contact) + { + return contact.phones.count > 0; + }; [addressBook loadContacts:^(NSArray *contacts, NSError *error) { [weakSelf.activity stopAnimating]; diff --git a/AddressBook/AddressBook/Storyboard.storyboard b/AddressBook/AddressBook/Storyboard.storyboard index 8e0320b..0350ac2 100644 --- a/AddressBook/AddressBook/Storyboard.storyboard +++ b/AddressBook/AddressBook/Storyboard.storyboard @@ -64,32 +64,12 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/APAddressBook.h b/Classes/APAddressBook.h index e0ee3b3..b00429f 100644 --- a/Classes/APAddressBook.h +++ b/Classes/APAddressBook.h @@ -7,16 +7,16 @@ // #import +#import "APTypes.h" -typedef enum -{ - APAddressBookAccessUnknown = 0, - APAddressBookAccessGranted = 1, - APAddressBookAccessDenied = 2 -} APAddressBookAccess; +@class APContact; @interface APAddressBook : NSObject +@property (nonatomic, assign) APContactField fieldsMask; +@property (nonatomic, copy) APContactFilterBlock filterBlock; +@property (nonatomic, strong) NSArray *sortDescriptors; + + (APAddressBookAccess)access; - (void)loadContacts:(void (^)(NSArray *contacts, NSError *error))callbackBlock; diff --git a/Classes/APAddressBook.m b/Classes/APAddressBook.m index 4a5dc1c..eb8ce94 100644 --- a/Classes/APAddressBook.m +++ b/Classes/APAddressBook.m @@ -27,8 +27,10 @@ - (id)init _addressBook = ABAddressBookCreateWithOptions(NULL, error); if (error) { - NSLog(@"%@", CFErrorCopyFailureReason(*error)); + NSLog(@"%@", (__bridge_transfer NSString *)CFErrorCopyFailureReason(*error)); + return nil; } + self.fieldsMask = APContactFieldDefault; } return self; } @@ -63,6 +65,9 @@ + (APAddressBookAccess)access - (void)loadContacts:(void (^)(NSArray *contacts, NSError *error))callbackBlock { __weak __typeof (self) weakSelf = self; + APContactField fieldMask = self.fieldsMask; + NSArray *descriptors = self.sortDescriptors; + APContactFilterBlock filterBlock = self.filterBlock; ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef errorRef) { NSArray *array = nil; @@ -75,12 +80,14 @@ - (void)loadContacts:(void (^)(NSArray *contacts, NSError *error))callbackBlock for (NSUInteger i = 0; i < contactCount; i++) { ABRecordRef recordRef = CFArrayGetValueAtIndex(peopleArrayRef, i); - APContact *contact = [[APContact alloc] init]; - contact.firstName = [APAddressBook firstNameFromRecord:recordRef]; - contact.lastName = [APAddressBook lastNameFromRecord:recordRef]; - contact.phones = [APAddressBook phonesFromRecord:recordRef]; - [contacts addObject:contact]; + APContact *contact = [[APContact alloc] initWithRecordRef:recordRef + fieldMask:fieldMask]; + if (!filterBlock || filterBlock(contact)) + { + [contacts addObject:contact]; + } } + [contacts sortUsingDescriptors:descriptors]; array = contacts.copy; } else if (errorRef) @@ -98,36 +105,4 @@ - (void)loadContacts:(void (^)(NSArray *contacts, NSError *error))callbackBlock }); } -#pragma mark - private - -+ (NSString *)firstNameFromRecord:(ABRecordRef)recordRef -{ - CFTypeRef valueRef = (ABRecordCopyValue(recordRef, kABPersonFirstNameProperty)); - return (__bridge_transfer NSString *)valueRef; -} - -+ (NSString *)lastNameFromRecord:(ABRecordRef)recordRef -{ - CFTypeRef valueRef = (ABRecordCopyValue(recordRef, kABPersonLastNameProperty)); - return (__bridge_transfer NSString *)valueRef; -} - -+ (NSArray *)phonesFromRecord:(ABRecordRef)recordRef -{ - ABMultiValueRef phonesValueRef = ABRecordCopyValue(recordRef, kABPersonPhoneProperty); - NSUInteger phonesCount = (NSUInteger)ABMultiValueGetCount(phonesValueRef); - NSMutableArray *phones = [[NSMutableArray alloc] init]; - for (NSUInteger i = 0; i < phonesCount; i++) - { - CFTypeRef value = ABMultiValueCopyValueAtIndex(phonesValueRef, i); - NSString *number = (__bridge_transfer NSString *)value; - if (number) - { - [phones addObject:number]; - } - } - CFRelease(phonesValueRef); - return phones.copy; -} - @end diff --git a/Classes/APContact.h b/Classes/APContact.h index 9f5949c..92ce8f7 100644 --- a/Classes/APContact.h +++ b/Classes/APContact.h @@ -7,11 +7,19 @@ // #import +#import +#import "APTypes.h" @interface APContact : NSObject -@property (nonatomic, strong) NSString *firstName; -@property (nonatomic, strong) NSString *lastName; -@property (nonatomic, strong) NSArray *phones; +@property (nonatomic, readonly) APContactField fieldMask; +@property (nonatomic, readonly) NSString *firstName; +@property (nonatomic, readonly) NSString *lastName; +@property (nonatomic, readonly) NSString *company; +@property (nonatomic, readonly) NSArray *phones; +@property (nonatomic, readonly) NSArray *emails; +@property (nonatomic, readonly) UIImage *photo; + +- (id)initWithRecordRef:(ABRecordRef)recordRef fieldMask:(APContactField)fieldMask; @end diff --git a/Classes/APContact.m b/Classes/APContact.m index e132aeb..e2c8b05 100644 --- a/Classes/APContact.m +++ b/Classes/APContact.m @@ -10,4 +10,66 @@ @implementation APContact +#pragma mark - life cycle + +- (id)initWithRecordRef:(ABRecordRef)recordRef fieldMask:(APContactField)fieldMask +{ + self = [super init]; + if (self) + { + _fieldMask = fieldMask; + if (fieldMask & APContactFieldFirstName) + { + _firstName = [self stringProperty:kABPersonFirstNameProperty fromRecord:recordRef]; + } + if (fieldMask & APContactFieldLastName) + { + _lastName = [self stringProperty:kABPersonLastNameProperty fromRecord:recordRef]; + } + if (fieldMask & APContactFieldCompany) + { + _company = [self stringProperty:kABPersonOrganizationProperty fromRecord:recordRef]; + } + if (fieldMask & APContactFieldPhones) + { + _phones = [self arrayProperty:kABPersonPhoneProperty fromRecord:recordRef]; + } + if (fieldMask & APContactFieldEmails) + { + _emails = [self arrayProperty:kABPersonEmailProperty fromRecord:recordRef]; + } + if (fieldMask & APContactFieldPhoto) + { + NSData *imageData = (__bridge_transfer NSData *)ABPersonCopyImageData(recordRef); + _photo = [UIImage imageWithData:imageData scale:UIScreen.mainScreen.scale]; + } + } + return self; +} + +#pragma mark - private + +- (NSString *)stringProperty:(ABPropertyID)property fromRecord:(ABRecordRef)recordRef +{ + CFTypeRef valueRef = (ABRecordCopyValue(recordRef, property)); + return (__bridge_transfer NSString *)valueRef; +} + +- (NSArray *)arrayProperty:(ABPropertyID)property fromRecord:(ABRecordRef)recordRef +{ + ABMultiValueRef multiValue = ABRecordCopyValue(recordRef, property); + NSUInteger count = (NSUInteger)ABMultiValueGetCount(multiValue); + NSMutableArray *array = [[NSMutableArray alloc] init]; + for (NSUInteger i = 0; i < count; i++) + { + CFTypeRef value = ABMultiValueCopyValueAtIndex(multiValue, i); + NSString *string = (__bridge_transfer NSString *)value; + if (string) + { + [array addObject:string]; + } + } + CFRelease(multiValue); + return array.copy; +} @end diff --git a/Classes/APTypes.h b/Classes/APTypes.h new file mode 100644 index 0000000..4cef5be --- /dev/null +++ b/Classes/APTypes.h @@ -0,0 +1,37 @@ +// +// APTypes.h +// AddressBook +// +// Created by Alexey Belkevich on 1/11/14. +// Copyright (c) 2014 alterplay. All rights reserved. +// + +#ifndef AddressBook_APTypes_h +#define AddressBook_APTypes_h + +@class APContact; + +typedef enum +{ + APAddressBookAccessUnknown = 0, + APAddressBookAccessGranted = 1, + APAddressBookAccessDenied = 2 +} APAddressBookAccess; + +typedef BOOL(^APContactFilterBlock)(APContact *contact); + +typedef enum +{ + APContactFieldFirstName = 1 << 0, + APContactFieldLastName = 1 << 1, + APContactFieldCompany = 1 << 2, + APContactFieldPhones = 1 << 3, + APContactFieldEmails = 1 << 4, + APContactFieldPhoto = 1 << 5, + APContactFieldDefault = APContactFieldFirstName | APContactFieldLastName | + APContactFieldPhones, + APContactFieldAll = APContactFieldDefault | APContactFieldCompany | + APContactFieldEmails | APContactFieldPhoto +} APContactField; + +#endif