2012-11-09 25 views
1

我一直在使用下面的代码几年,现在它一直工作,但它看起来像iOS 6它现在不再。如何获取iOS 6设备上的所有联系人列表?如何获取iOS 6中的用户联系人列表?

ABAddressBookRef myAddressBook = ABAddressBookCreate(); 
     NSMutableArray *people = (__bridge_transfer NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(myAddressBook); 
     CFRelease(myAddressBook); 

     // repeat through all contacts in the inital array we loaded 
     for(int i=0; i<[people count]; i++) 
     { 
      NSString *aName; 
      NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue((__bridge ABRecordRef)([people objectAtIndex:i]), kABPersonFirstNameProperty); 
      NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue((__bridge ABRecordRef)([people objectAtIndex:i]), kABPersonLastNameProperty); 

      if (([firstName isEqualToString:@""] || [firstName isEqualToString:@"(null)"] || firstName == nil) && 
       ([lastName isEqualToString:@""] || [lastName isEqualToString:@"(null)"] || lastName == nil)) 
      { 
       // do nothing 
      } 
      else 
      { 
       aName = [NSString stringWithFormat:@"%@ %@", firstName, lastName]; 

       if ([firstName isEqualToString:@""] || [firstName isEqualToString:@"(null)"] || firstName == nil) 
       { 
        aName = [NSString stringWithFormat:@"%@", lastName]; 
       } 

       if ([lastName isEqualToString:@""] || [lastName isEqualToString:@"(null)"] || lastName == nil) 
       { 
        aName = [NSString stringWithFormat:@"%@", firstName]; 
       } 

       [self.tableItems addObject:aName]; 
      } 

     } 

     [self.tableItems sortUsingSelector:@selector(compare:)]; 
+0

我认为,代码将s直到工作,只要您授予您的应用程序的联系人权限... – samson

+0

好吧,大概这是希望在其他最终用户设备的应用程序中使用,并迫使他们手动提供权限可能不会发生,除非他们得到提示它......所以请求它应该是iOS 6应用程序实现的一部分。 – foggzilla

回答

4

在ios6中,您需要请求读取AddressBook的权限,否则您将得到零。使用这样的事情:

- (BOOL)askContactsPermission { 
    __block BOOL ret = NO; 
    if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS6 

     dispatch_semaphore_t sema = dispatch_semaphore_create(0); 
     ABAddressBookRef addressBook = ABAddressBookCreate(); 
     ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 
      ret = granted; 
      dispatch_semaphore_signal(sema); 
     }); 
     if (addressBook) { 
      CFRelease(addressBook); 
     } 

     dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
     dispatch_release(sema); 
    } 
    else { // we're on iOS5 or older 
     ret = YES; 
    } 

    return ret; 
} 

如果该方法返回NO,运气不好,你将无法访问AB。我在这里锁定信号量,因为如果用户不允许AB,我不想继续使用我的应用程序。还有其他方法,只需检查API。

+0

完美的解决方案,但它没有要求用户访问地址簿的权限,所以这是正确的方式来获取用户数据? – SAHIL

4

您确实需要询问用户的权限,当您这样做时会触发提示给用户。这是另一种使用执行块来处理结果的方法,如果需要从通用代码查询当前访问状态,还可以使用它执行版本无关。

我实现了,像这样

的访问管理器AppContactsAccessManager.h

#import <AddressBook/AddressBook.h> 

typedef enum 
{ 
    kABAuthStatusNotDetermined = 0, 
    kABAuthStatusRestricted, 
    kABAuthStatusDenied, 
    kABAuthStatusAuthorized, 
    kABAuthStatusPending, 
}AddressBookAuthStatus; 

typedef void (^AddressbookRequestHandler)(ABAddressBookRef addressBookRef, BOOL available); 

@interface AppContactsAccessManager : NSObject 
{ 
    AddressBookAuthStatus status; 
} 
- (void) requestAddressBookWithCompletionHandler:(AddressbookRequestHandler)handler; 
- (AddressBookAuthStatus) addressBookAuthLevel; 

@end 

AppContactsAccessManager.m

@implementation AppContactsAccessManager 

- (BOOL) isStatusAvailable:(AddressBookAuthStatus)theStatus 
{ 
    return (theStatus == kABAuthStatusAuthorized || theStatus == kABAuthStatusRestricted); 
} 

- (void) requestAddressBookWithCompletionHandler:(AddressbookRequestHandler)handler 
{ 
    ABAddressBookRef addressBookRef = NULL; 

    if([self isiOS6]){ 
     addressBookRef = ABAddressBookCreateWithOptions(nil, nil); 
     ABAuthorizationStatus curStatus = ABAddressBookGetAuthorizationStatus(); 
     if(curStatus == kABAuthorizationStatusNotDetermined) 
     { 
      status = kABAuthStatusPending; 
      ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) { 
       status = ABAddressBookGetAuthorizationStatus(); 
       if(handler != NULL){ 
        handler(addressBookRef, [self isStatusAvailable:status]); 
       } 
      }); 
     }else 
     { 
      status = curStatus; 
      dispatch_async(dispatch_get_current_queue(), ^{ 
       if(handler != NULL){ 
        handler(addressBookRef, [self isStatusAvailable:status]); 
       } 
      }); 
     } 
    }else 
    { 
     addressBookRef = ABAddressBookCreate(); 
     status = kABAuthStatusAuthorized; 
     dispatch_async(dispatch_get_current_queue(), ^{ 
      if(handler != NULL){ 
       handler(addressBookRef, [self isStatusAvailable:status]); 
      } 
      }); 
     } 
} 

- (AddressBookAuthStatus) addressBookAuthLevel 
{ 
     return status; 
} 

@end 

用法看起来是这样的:

AppContactsAccessManager* accessMgr = [AppContactsAccessManager new]; 
[accessMgr requestAddressBookWithCompletionHandler:^(ABAddressBookRef theAddressBookRef, BOOL available) { 
    // do your addressbook stuff in here 
}]; 
+0

dispatch_get_current_queue已弃用 – 0x8badf00d

相关问题