I want my app to check if it has permissions to use the device contacts or not.
This is the code i'm using:
- (void)isContactsAutherizedWithCompletion:(void(^)(BOOL granted))completion {
self.addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
ABAddressBookRegisterExternalChangeCallback(self.addressBookRef, MyAddressBookExternalChangeCallback, (__bridge_retained void *)self);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(self.addressBookRef, ^(bool granted, CFErrorRef error) {
if (granted) {
completion(YES);
} else {
completion(NO);
}
});
} else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
completion(YES);
} else {
completion(NO);
}
}
But with this code i'm automatically being asked if I want to give permissions. I don't want to be asked, I just want to know if it's has permissions or not.
Anyone has a solution?
Thanks
There are three states for permission based access.
You have been granted access.
You have been denied access.
The user hasn't been asked yet.
The first time you open the app and try to access something that requires permission it will ask. No way around this.
If you are given permission then it will never ask again and it will work.
If you are denied access then it will also never ask again and the request will fail.
The user will only be asked once for each system. That is how it has to work.
In this case it is in state 3. So it neither has not doesn't have permission. So the check cannot complete. It has to fall into either state 1 or 2 to be able to work out if the app has permission or not.
i.e. Everything seems to be working correctly here.
well from the doc:
typedef CF_ENUM (CFIndex, ABAuthorizationStatus ) {
kABAuthorizationStatusNotDetermined = 0,
kABAuthorizationStatusRestricted,
kABAuthorizationStatusDenied,
kABAuthorizationStatusAuthorized
};
So check if the status is kABAuthorizationStatusAuthorized
and you are sure that you have the permission, in all the other cases you have no permission either because the user did not accept or because you did not ask for the permission yet
Related
I need to reload the music list in my app when the user allows the access to media library, and I would like to show a notification when the user disallows the access. How can I get the two callbacks?
For requesting access, I just added this line into the info.plist NSAppleMusicUsageDescription
You need to ask for the permission for accessing MPMediaLibrary, this is how you can request for it
Objective-C
[MPMediaLibrary requestAuthorization:^(MPMediaLibraryAuthorizationStatus authorizationStatus) {
if ( authorizationStatus == MPMediaLibraryAuthorizationStatusAuthorized ) {
// Reload your list here
} else {
// user did not authorize
} }];
Swift
MPMediaLibrary.requestAuthorization { (status) in
if status == .authorized {
// Reload your list here
} else {
// user did not authorize
}
}
I am using AppleHealthKit in my application. Everything is working correctly. The problem is that I am not able to detect if the user taps "Don't Allow" button when asking for permission.
With this method, my application uses HealthKit, even though the user doesn't allow this.
requestAuthorizationToShareTypes(healthKitTypesToWrite, readTypes: healthKitTypesToRead) { (success, error) -> Void in
if( completion != nil ) {
completion(success:success,error:error)
}
Apple Documentation:
So basically my question is how to detect this?
You cannot detect it, by design:
To help prevent possible leaks of sensitive health information, your app cannot determine whether a user has granted permission to read data. If you are not given permission, it simply appears as if there is no data of the requested type in the HealthKit store.
(from HKHealthStore)
You can do this but only for one specific type and only for write data(u can do the same with other type too if u have to check them)
HKHealthStore *_healthStore;
HKQuantityType *stepsType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKAuthorizationStatus status = [_healthStore authorizationStatusForType:stepsType];
BOOL isActive;
switch (status) {
case HKAuthorizationStatusSharingAuthorized:
isActive = YES;
break;
case HKAuthorizationStatusSharingDenied:
isActive = NO;
break;
case HKAuthorizationStatusNotDetermined:
isActive = NO;
break;
default:
break;
}
NSLog(#"STATUS-------%#", isActive ? #"yes" : #"no");
I have an iOS app developed in Xamarin. When the app does not have permission to access the microphone, if the user tries to access the microphone from the app, I check the settings using AVAudioSession.SharedInstance().RequestRecordPermission (delegate(bool granted)) and display a message.
Now I need to do the same if the app does not have permission to access the camera. I need to check if permission is granted for camera and display a message accordingly. How can I do this?
I have got the answer. Here is what I have done:
AVCaptureDevice.RequestAccessForMediaType (AVMediaType.Video, (bool isAccessGranted) => {
//if has access
if(isAccessGranted)
{
//do something
}
//if has no access
else
{
//show an alert
}
});
Did you checked this answer?
Detect permission of camera in iOS
I think that's the solution you are looking for :).
EDIT:
Here is the highest voted answer's code ported to C#
// replace the media type to whatever you want
AVAuthorizationStatus authStatus = AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video);
switch (authStatus)
{
case AVAuthorizationStatus.NotDetermined:
break;
case AVAuthorizationStatus.Restricted:
break;
case AVAuthorizationStatus.Denied:
break;
case AVAuthorizationStatus.Authorized:
break;
default:
throw new ArgumentOutOfRangeException();
}
I'm able to log in to Twitter through my app using this Twitter Fabric code:
let logInButton = TWTRLogInButton(logInCompletion: {
(session: TWTRSession!, error: NSError!) in
// play with Twitter session
if (session != nil) {
println("signed in as \(session.userName)");
self.TWUsernameLabel.text = "Logged in as #" + session.userName
} else {
println("error: \(error.localizedDescription)");
}
})
When I click the login button, it prompts me to approve the login and then logs me in, or it knows I already approved the login and it logs me in. This works like a charm and took all of ten minutes to set up. Amazing.
I already have an email-based login to access the app. I'd like to store a user's logged in Twitter account in that same database, so when a user logs in with their email, I already know their Twitter (if they have logged in before) and they don't need to log in again. The reason I do the email login is because Twitter is an important feature in my app, but not a total requirement.
The issue is that I have no idea how to access session outside of when the button is clicked and logInCompletion fires, and I don't know what variables to store upon initial login/check upon using the app.
I've read through the Twitter Fabric documentation numerous times, but it isn't written in swift, so it's pretty confusing. Any ideas? Thanks
If there is currently an active session you should be able to access it just like the docs say to
Twitter.sharedInstance().session()
If the user isn't logged in that method will return nil. If you want to know if someone is already authenticated just check to see if that method returns a value or not.
Twitter kit automatically present a login screen if user has not logged in (no session exist..).
But, before calling any future API, just check whether session is valid or not. In some APIs, you may required to pass this session too.
if ([[Twitter sharedInstance] session]) {
TWTRShareEmailViewController *shareEmailViewController =
[[TWTRShareEmailViewController alloc]
initWithCompletion:^(NSString *email, NSError *error) {
NSLog(#"Email %# | Error: %#", email, error);
}];
[self presentViewController:shareEmailViewController
animated:YES
completion:nil];
} else {
// Handle user not signed in (e.g. attempt to log in or show an alert)
}
}
You even don't need to worry about storing and managing access token and access token secret.
To access the authToken, userName or the userID for the logged in user session in Swift 4 is:
Twitter.sharedInstance().logIn(completion: { (session, error) in
if (session != nil) {
print(session!.authToken)
print(session!.userName)
print(session!.userID)
} else {
print(error?.localizedDescription)
}
})
Is there a way to programatically reject/disable/disallow/reject permissions to access the calendar?
I'm using the following code to ask for / determine permissions:
//request access
[[MyCalendarUtil sharedManager] requestAccess:^(BOOL granted, NSError *error) {
/* This code will run when uses has made his/her choice */
if(error)
{
// display error message here
_calendarLabel.text = #"Calendar OFF";
}
else
if(!granted)
{
// display access denied error message here
_calendarLabel.text = #"Calendar OFF";
}
else
{
// access granted
_calendarLabel.text = #"Calendar ON";
}
}];
Can I disable the permission later on upon a user pressing a button ... ?
No way, its impossible. Take it granted. I will give 1 Million dollars even if you find a private API. :)
Its a privacy concern.
All you can do is, programmatically launching your application's preferences in the Settings App, and again its users wish to disable or enable the access.