ABAddressBookRequestAccessWithCompletion iOS 7和信号量

mic*_*ckm 3 semaphore objective-c contacts ios

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

在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;
}
Run Code Online (Sandbox Code Playgroud)

在尝试使用它时,我只需将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);
}
Run Code Online (Sandbox Code Playgroud)

dav*_*oze 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];
Run Code Online (Sandbox Code Playgroud)

这与Apple在其文档中所做的非常相似(搜索ABAddressBookRequestAccessWithCompletion).此外,ABAddressBookRequestAccessWithCompletion异步并等待它的重点是什么(见这里)..