ABAddressBookRequestAccessWithCompletion iOS 7和信号量

时间:2013-11-13 23:03:30

标签: ios objective-c contacts semaphore

此代码之前已经发布,并且已经被用于我可以收集的内容中。我处于这样一种情况,我需要代码不要继续,直到我知道我是否有权访问联系人。

在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 个答案:

答案 0 :(得分: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];

与Apple在documentation中的行为非常相似(搜索ABAddressBookRequestAccessWithCompletion)。此外,ABAddressBookRequestAccessWithCompletion异步并等待它的意义(见here)..