Question

This is somewhat backward to what most people ask. I want to purposely trigger the dialog asking for the users permission to:

  • Connect to bluetooth devices, even when offline.
  • Access there iOS-based Twitter account.

I already have a similar dialog for location working fine. I'm doing this because I want to make the process of asking permission a bit more gentle, like Heyday, by showing a welcome screen explaining why the app needs this service then when the user taps OK, initiating the request and triggering the dialog.

I have tried some things already. For Twitter I have tried the following:

- (void)triggerTwitterApprovalWithCompletion:(void (^)(BOOL, NSError *))completion  {
  self.accountStore = [[ACAccountStore alloc] init]; //setup as a property.
  ACAccountType *twitterAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
  [self.accountStore requestAccessToAccountsWithType:twitterAccountType  options:nil completion:^(BOOL granted, NSError *error) { //completion handling is on indeterminate queue so I force main queue inside
    dispatch_async(dispatch_get_main_queue(), ^{
      completion(granted, error); //triggers displaying the next screen, working
    });
  }];
}

But although the permission is given, it is automatic and not a result of the user being presented with a dialog and approving it.

With the Bluetooth version I am yet to find some code that would trigger it. Both the docs and programming guides are relatively quiet on the issue of asking for permissions. The only one reference I can find is that by having a plist key for bluetooth-peripheral the user will be prompted automagically on app launch. This is too early in the flow to be useful.

Was it helpful?

Solution

Only the peripheral role needs user permission to run. The central can do whatever it wants to. Simply instantiate a CBPeripheralManager when you want the user to give permission and it will trigger the dialog.

pmanager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];

Then you use the peripheralManagerDidUpdateState: delegate method to get informed about the user's decision. You needn't set the bluetooth-peripheral backgrounding mode in the plist if your app does not operate in the background.

Keep in mind that the dialog will be popped only once during the lifetime of the application and the setting won't be reset when the app is deleted and reinstalled.

Note also that in light of this behavior, the

The only one reference I can find is that by having a plist key for bluetooth-peripheral the user will be prompted automagically on app launch.

Is not true.

For the twitter part. I haven't tried to use that API yet but found several answers that suggest authorization is either handled automatically for you or iOS will ask only the first time.

To test the popup questions you should manually reset the settings in
Settings->General->Reset->Reset Location & Privacy

Just a small addition: best practices for asking for user permission

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top