1

私は数年前から次のコードを使用しており、常に機能していましたが、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:)];
4

2 に答える 2

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
}];
于 2012-11-09T22:38:08.713 に答える
4

iOS6 では、AddressBook を読み取る許可を求める必要があります。そうしないと、nil が返されます。次のようなものを使用します。

- (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を確認してください。

于 2012-11-09T21:16:59.470 に答える