Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
等待用户响应iOS中的通讯簿访问请求?_Ios_Permissions_Dialog_Authorization - Fatal编程技术网

等待用户响应iOS中的通讯簿访问请求?

等待用户响应iOS中的通讯簿访问请求?,ios,permissions,dialog,authorization,Ios,Permissions,Dialog,Authorization,我希望我的应用程序仅向用户请求访问联系人通讯簿的权限,直到用户访问我的应用程序中的适当功能为止。我真的不想在应用加载时请求权限 因此,我使用了以下代码: - (IBAction)importClientsButtonPressed:(id)sender { // request access to Contacts address book CFErrorRef addyError = NULL; ABAddressBookRef addressBook = ABAddressBookCreat

我希望我的应用程序仅向用户请求访问联系人通讯簿的权限,直到用户访问我的应用程序中的适当功能为止。我真的不想在应用加载时请求权限

因此,我使用了以下代码:

- (IBAction)importClientsButtonPressed:(id)sender {
// request access to Contacts address book
CFErrorRef addyError = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &addyError);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef addyError) {
    });
}

if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
    _importContactsActionSheet = [[UIActionSheet alloc] initWithTitle:@"Import Client from Contacts"
                                                             delegate:self
                                                    cancelButtonTitle:@"Cancel"
                                               destructiveButtonTitle:nil
                                                    otherButtonTitles:@"Primary Contact", @"Secondary Contact", nil];
    _importContactsActionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;

    [_importContactsActionSheet showFromRect:self.importClientsButton.frame inView:self.importClientsButton.superview animated:YES];
} else {
    // the user has previously denied access - send alert to user to allow access in Settings app
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Settings"
                                                    message:@"This app does not have access to your contacts.  You can enable access in Privacy Settings."
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
}
}

但是,权限对话框不会停止应用程序并等待响应……请求后的代码将继续运行。结果,我收到了一大堆乱七八糟的信息

有没有办法让整个应用程序暂停,直到权限请求对话框返回响应


谢谢

在上面的代码中,您还有:

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef addyError)  {
    if(granted) {
        //Put here your code
    }
});
因此,最后我将以以下方式编写代码:

- (IBAction)importClientsButtonPressed:(id)sender {
    __weak typeof(self) weakSelf = self;

    // request access to Contacts address book
    CFErrorRef addyError = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &addyError);
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef addyError)  {
            if(granted) {
                [weakSelf openImportContact];
            }
        });
    } else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        [weakSelf openImportContact];
    } else {
        // the user has previously denied access - send alert to user to allow access in Settings app
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Settings"
                                                        message:@"This app does not have access to your contacts.  You can enable access in Privacy Settings."
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
    }
}


- (void)openImportContact {
    dispatch_async(dispatch_get_main_queue(), ^{
        _importContactsActionSheet = [[UIActionSheet alloc] initWithTitle:@"Import Client from Contacts"
                                                         delegate:self
                                                cancelButtonTitle:@"Cancel"
                                           destructiveButtonTitle:nil
                                                otherButtonTitles:@"Primary Contact", @"Secondary Contact", nil];
        _importContactsActionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;

        [_importContactsActionSheet showFromRect:self.importClientsButton.frame inView:self.importClientsButton.superview animated:YES];
    });
}

但是,我必须复制一组数据…如果这是第一次,而且他们刚刚授予了访问权限(如您上面的建议),则复制一次,如果之前授予了访问权限,并且未调用此对话框,则复制一次。对吗?别忘了在最后关闭通讯录;)它真的很接近工作!但是,openImportContact方法因以下错误而终止,仅当这是第一次且用户刚刚授予权限时:
***由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:'-[UIKeyboardTaskQueue PerformTaskTask:]只能从主线程调用。'
我认为是因为线程。没问题,现在查看代码。问题是您的代码更改了UI,因此需要在主线程中执行。但是,当用户第一次授权应用程序并输入在另一个线程中执行的块时。现在,我添加了一个dispatch_async块,确保在主线程中执行代码;)格拉齐·马特奥!现在效果很好!我从中学到了很多!