I'm trying to implement an app accessing the camera roll. Here is how I'm checking for permissions:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status != PHAuthorizationStatusAuthorized) {
NSString *accessDescription = [[NSBundle mainBundle]
objectForInfoDictionaryKey:#"NSPhotoLibraryUsageDescription"];
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:accessDescription
message:#"To give permissions tap on 'Change Settings' button"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:nil];
[alertController addAction:cancelAction];
UIAlertAction *settingsAction = [UIAlertAction
actionWithTitle:#"Change Settings"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]
options:#{}
completionHandler:nil];
}];
[alertController addAction:settingsAction];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController
animated:YES
completion:nil];
}
}
I also add it Settings.bundle:
But I haven't figure it out how can link the toggle switch to the permissions. Any of you knows how can I link the toggle switch to the camera roll permissions ?
I'll really appreciate your help.
You can try this code :
if (status == PHAuthorizationStatusNotDetermined) {
// Access has not been determined.
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
// do something
}else {
// Access has been denied.
}
}];
}
Related
Now I have a question that if we don't have the access to save photo into album, the app will crash. So I want to ask for the access at the beginning. But if the Users select NO, the app will crash when the app is saving photos. So I want to judge whether we have the access before using UIImageWriteToSavedPhotosAlbum function. Except adding codes before per UIImageWriteToSavedPhotosAlbum function, any else methods can be used?
It's crashing because you need to set
NSPhotoLibraryUsageDescription
in info.plist file
then after use following code to check access of gallery
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusAuthorized) {
// Access has been granted.
NSLog(#"Access Granted");
UIImage *myImage = [UIImage imageNamed:#"Mobile.png"];
UIImageWriteToSavedPhotosAlbum(myImage, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
else if (status == PHAuthorizationStatusDenied) {
// Access has been denied.
NSLog(#"Access NOT Granted");
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Not Granted"
message:#"You have not granted permission for a gallery to save photos, Please grant it from setting"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}
else if (status == PHAuthorizationStatusNotDetermined) {
// Access has not been determined.
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
UIImage *myImage = [UIImage imageNamed:#"Mobile.png"];
UIImageWriteToSavedPhotosAlbum(myImage, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
else {
// Access has been denied.
}
}];
}
else if (status == PHAuthorizationStatusRestricted) {
// Restricted access - normally won't happen.
}
Don't forget to #import <Photos/Photos.h>
Don't forget to implement this method
- (void) image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(NSDictionary*)info{
}
My question is similar to "How can I prevent iOS apps from resetting after changing Camera permissions?".
But I don't understand the answer very well .
I set the microphone permission by the code as follow:
-(BOOL)canRecord
{
__block BOOL bCanRecord = NO;
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)
{
//prompt
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"setting permission" message:#"need microphone permission" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *settingAction = [UIAlertAction actionWithTitle:#"setting now" style:UIAlertActionStyleDefault handler:^(UIAlertAction * a){
// jump to setting
NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
if ([[[UIDevice currentDevice]systemVersion]floatValue]>10.0) {
[[UIApplication sharedApplication] openURL:url options:#{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:url];
}
}
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"later" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:settingAction];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
}else{
if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 7.0) {
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession performSelector:#selector(requestRecordPermission:) withObject:^(BOOL granted) {
if (granted) {
bCanRecord = YES;
} else {
bCanRecord = NO;
}
}];
// }
}
NSLog(#"bCanRecord %d",bCanRecord);
}
return bCanRecord;
}
then back to my app by clicking the return key in the status bar, my app will force a refresh and I will lose my place in the app.
I'm using an iPhone5 running IOS 9.3.3.
I'm checking for permissions to the camera roll:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status != PHAuthorizationStatusNotDetermined) {
// Access has not been determined.
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
// do something
}else {
// Access has been denied.
}
}];
}
}
And it works fine but the problem is if the user choose "Not Allow" and it wants to switch to "Allow".
How can the user switch the permission to the camera roll?
Your can ask your user to turn on the permission, if they say "yes, I want to turn on this permission" then you can transport them to your app's preferences in the Settings direct using NSURL, and they also can return to your app by click the back button in the status bar's left.
Here is code for transport user to your app's preferences:
NSURL *settingsUrl = [[NSURL alloc] initWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:settingsUrl];
Here is full code I test in iOS10 iPhone6s:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status != PHAuthorizationStatusNotDetermined) {
// Access has not been determined.
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
// do something
}else {
// Access has been denied.
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Need Photo Permission"
message:#"Using this app need photo permission, do you want to turn on it?"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *yesAction = [UIAlertAction actionWithTitle:#"YES" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
NSURL *settingsUrl = [[NSURL alloc] initWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:settingsUrl];
}];
UIAlertAction *noAction = [UIAlertAction actionWithTitle:#"NO" style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
}];
[alert addAction:yesAction];
[alert addAction:noAction];
[self presentViewController:alert animated:YES completion:nil];
}
}];
}
}
I have a UIwebView, it has a few links within the webpage. I want a certain link to open an alert modal like in image #1
Also, how can use the code below to make something like this - (IMAGE #1) http://screenshot.it.sftcdn.net/blog/it/2014/01/Block-user-03-Tasto-Block-378x568.png in objective-c
- (IBAction)showAlert:(id)sender
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Open In..."
message:#"Which app would you like to open?"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *mapsAction = [UIAlertAction actionWithTitle:#"Maps"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
if (![self openURLForString:#"maps://"]) {
NSLog(#"Couldn't Open Maps");
}
}];
UIAlertAction *youtubeAction = [UIAlertAction actionWithTitle:#"YouTube"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
if (![self openURLForString:#"http://www.youtube.com/watch?v=dQw4w9WgXcQ"]) {
NSLog(#"Couldn't Open YouTube");
}
}];
UIAlertAction *messagesAction = [UIAlertAction actionWithTitle:#"Messages"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
if (![self openURLForString:#"sms://"]) {
NSLog(#"Couldn't Open Messages");
}
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:nil];
[alertController addAction:mapsAction];
[alertController addAction:youtubeAction];
[alertController addAction:messagesAction];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
- (BOOL)openURLForString:(NSString *)urlString {
NSURL *url = [NSURL URLWithString:urlString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
return YES;
}
return NO;
}
Where the "report inappropriate" being a link opening in a second UIwebView that opens up OVER the parent webview and the "share" opens up in Safari.
(Disregard the "copy link/URL")
You would need to first register your view controller for the web view protocol.
And then in your view controller implement the delegate method for web view did start loading and check the URL being called and do your tasks accordingly using an if else check
Here's the delegate reference:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWebViewDelegate_Protocol/
Answered from my phone. Pardon syntax.
Hope this helps.
My app uses user location in the background, but sometimes, users don't allow the app to always collect GPS data. The app can handle foreground only locations, and I'd like to set that as a fallback.
Is there a graceful way, once an iOS user has declined my AuthorizedAlways request, to re-prompt the user to give AuthorizedWhenInUse permission ?
You can't force it, but you can:
1) know that user is declined permission
2) and show an alert asking: "Please, go to settings and enable it".
3) go to ios settings ([[UIApplication sharedApplication] openURL:[NSURL URLWithString: UIApplicationOpenSettingsURLString]];)
Something like this:
- (void)checkLocation
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedAlways){
NSLog(#"ok");
} else if(status == kCLAuthorizationStatusDenied ||
status == kCLAuthorizationStatusAuthorizedWhenInUse){
[self showRequestLocationMessage];
} else if(status == kCLAuthorizationStatusNotDetermined){
//request auth
}
}
- (void)showRequestLocationMessage
{
UIAlertAction *action = [UIAlertAction actionWithTitle:#"Settings"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * alertAction){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: UIApplicationOpenSettingsURLString]];
}];
NSString *title = #"Service Enable";
NSString *text = #"Please enable your location.. bla bla bla";
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:title
message:text
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action){
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
[alertController addAction:cancelAction];
[alertController addAction:action];
[self presentViewController:alertController animated:YES completion:nil];
}