ABAddressBookRequestAccessWithCompletion在iOS 7和信号量中的应用

3

这段代码以前发布过并且被使用过,据我所知。但在我的情况下,我需要让代码在确认是否能够访问联系人之前不继续执行。

在Xcode 5.0.2和iOS 6上,这个代码可以正常运行。但在iOS 7上,它会一直卡住,直到我强制关闭应用程序后才会出现对话框询问是否允许访问联系人。

ABAddressBookRef addressBook = ABAddressBookCreate();

__block BOOL accessGranted = NO;

if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
dispatch_semaphore_t sema = dispatch_semaphore_create(0);

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    accessGranted = granted;
    dispatch_semaphore_signal(sema);
});

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
}
else { // we're on iOS 5 or older
     accessGranted = YES;
}

在尝试使用这个方法时,我只需将BOOL设置为NO,然后在块中将其设置为YES。在块之后,我放置了一个while循环来检查变量是否为YES,然后睡眠1秒钟。在6上完美运行,在7上我永远无法到达块中的NSLog语句,并且我会一直卡在打印日志语句的while循环中。

我在这里做了什么愚蠢的事情吗?还是这种方法在7上出了问题?

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    if (granted)
    {
        self.myAddressBook = addressBook;
    }

    done = YES;
    NSLog(@"in block, done is %@", done ? @"YES" : @"NO");
    didGrant = granted;

    //dispatch_semaphore_signal(sema);
});

while (!done)
{
    NSLog(@"done is %@", done ? @"YES" : @"NO");
    sleep(1);
}
1个回答

5

我曾经遇到同样的问题,后来发现请求访问联系人的对话框会阻止应用程序,可能会导致死锁。所以我放弃了信号量,改为像这样做(在iOS 7.1.1上测试通过):

ABAddressBookRef addressBook = ABAddressBookCreate();

MyController * __weak weakSelf = self;

if (ABAddressBookRequestAccessWithCompletion != NULL)
{ // we're on iOS 6
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
    {
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf accessGrantedForAddressBook];
            });
        });    
    }
    else
        if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized); //Maybe add something here to handle kABAuthorizationStatusRestricted
            [self accessGrantedForAddressBook];
    }
}
else // we're on iOS 5 or older
     [self accessGrantedForAddressBook];

这类似于苹果在他们的文档中所做的(搜索ABAddressBookRequestAccessWithCompletion)。此外,ABAddressBookRequestAccessWithCompletion异步运行并等待它(请参见这里)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接