Do something before UIImageWriteToSavedPhotosAlbum function ios - ios

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{
}

Related

iOS: Switch PHPhotoLibrary permissions using settings

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];
}
}];
}
}

iOS: how to link iPhone settings to PHPhotoLibrary permission

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.
}
}];
}

iOS app camera access denied iOS 9.1(black screen)

I want to access camera in my app. I am trying the following code.
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
if(isIOS8SystemVersion)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self presentViewController:picker animated:YES completion:NULL];
}];
}
else
{
[self presentViewController:picker animated:YES completion:NULL];
}
}
This code works on my other app perfectly.But in this app,it is not asking camera permissions or showing it in the settings->privacy->camera.
The app prompts to use the location.But not showing anything for the camera or photos.
The black screen appears and I can't take the picture if I directly use the camera code without the condition check.
I had the exactly same issue for couple of days,
Try this its solved my problem, make sure that there is a value
(Application name as string) in your info.plist > "Bundle display name".
In my case it was empty and because of that it didn't work.
let me know if it helped you.
Use following method to check device camera authorizationStatus. If not it will prompt for Access, if rejected if will show alert to navigate to App settings.
- (void)checkCameraPermission
{
// *** check for hardware availability ***
BOOL isCamera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
if(!isCamera)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:APPName message:#"Camera not detected" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return;
}
// *** Store camera authorization status ***
AVAuthorizationStatus _cameraAuthorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
switch (_cameraAuthorizationStatus)
{
case AVAuthorizationStatusAuthorized:
{
_cameraAuthorizationStatus = AVAuthorizationStatusAuthorized;
// *** Camera is accessible, perform any action with camera ***
}
break;
case AVAuthorizationStatusNotDetermined:
{
NSLog(#"%#", #"Camera access not determined. Ask for permission.");
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
{
if(granted)
{
NSLog(#"Granted access to %#", AVMediaTypeVideo);
// *** Camera access granted by user, perform any action with camera ***
}
else
{
NSLog(#"Not granted access to %#", AVMediaTypeVideo);
// *** Camera access rejected by user, perform respective action ***
}
}];
}
break;
case AVAuthorizationStatusRestricted:
case AVAuthorizationStatusDenied:
{
// Prompt for not authorized message & provide option to navigate to settings of app.
dispatch_async( dispatch_get_main_queue(), ^{
NSString *message = NSLocalizedString( #"My App doesn't have permission to use the camera, please change privacy settings", #"Alert message when the user has denied access to the camera" );
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:APPName message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString( #"OK", #"Alert OK button" ) style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancelAction];
// Provide quick access to Settings.
UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:NSLocalizedString( #"Settings", #"Alert button to open Settings" ) style:UIAlertActionStyleDefault handler:^( UIAlertAction *action ) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}];
[alertController addAction:settingsAction];
[self presentViewController:alertController animated:YES completion:nil];
});
}
break;
default:
break;
}
}
The code works in my app :
UIImagePickerController *picker;
if([self checkForCameraAcess])
{
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:nil];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Camera",nil) message:NSLocalizedString(#"Access to camera seems to be turned off. Please enable it from settings",nil) delegate:self cancelButtonTitle:NSLocalizedString(#"OK",nil) otherButtonTitles:NSLocalizedString(#"Settings",nil), nil];
alert.tag = 101;
[alert show];
}
-(BOOL)checkForCameraAcess
{
BOOL isAccess = YES;
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
{
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
//Here we check condition for AVAuthorizationStatusNotDetermined, because when user install iLeads app first time in device (Nerver before iLeads app install in Device), then setup an event and tap on the scan button, at that time authStatus is AVAuthorizationStatusNotDetermined so its show alert for camera acess first. Then after our custom alert shows if we tap on 'Dont allow' button of the camera acess.
if(authStatus == AVAuthorizationStatusAuthorized || authStatus == AVAuthorizationStatusNotDetermined)
{
isAccess = YES;
}
else
{
isAccess = NO;
}
}
return isAccess;
}
Don't forget to add UIImagePickerControllerDelegate in your .h
I hope it will work.

Is it possible to fallback to AuthorizedWhenInUse when a user doesn't allow AuthorizedAlways in iOS?

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];
}

UIImagePickerController camera type returning black image

I am struggling with UIImagePickerController as when i open camera and take image it show black screen in IOS 7 as this is working fine in ios 6, i have tried some other links what says but its not working, please help me with this...
and i am getting this error too
<Error>: CGAffineTransformInvert: singular matrix.
and now i got something ..
Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
when i just click on take image button
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
dispatch_async(dispatch_get_main_queue(), ^{
if (buttonIndex == 0) {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
NSString *mediaType = AVMediaTypeVideo; // Or AVMediaTypeAudio
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
// This status is normally not visible—the AVCaptureDevice class methods for discovering devices do not return devices the user is restricted from accessing.
if(authStatus == AVAuthorizationStatusRestricted){
NSLog(#"Restricted");
}
// The user has explicitly denied permission for media capture.
else if(authStatus == AVAuthorizationStatusDenied){
NSLog(#"Denied");
}
// The user has explicitly granted permission for media capture, or explicit user permission is not necessary for the media type in question.
else if(authStatus == AVAuthorizationStatusAuthorized){
NSLog(#"Authorized");
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
UIImagePickerController *imagePickerCamera =[[UIImagePickerController alloc] init];
imagePickerCamera.delegate = self;
imagePickerCamera.allowsEditing = YES;
imagePickerCamera.sourceType = UIImagePickerControllerSourceTypeCamera;
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:imagePickerCamera animated:YES completion:^{}];
});
} else {
NSString *errorString = [NSString stringWithFormat:#"This device does not support this feature."];
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Alert" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
// Explicit user permission is required for media capture, but the user has not yet granted or denied such permission.
else if(authStatus == AVAuthorizationStatusNotDetermined){
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
if(granted){
NSLog(#"Granted access to %#", mediaType);
}
else {
NSLog(#"Not granted access to %#", mediaType);
}
}];
}
else {
NSLog(#"Unknown authorization status");
}
}
else {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
dispatch_async(dispatch_get_main_queue(), ^{
UIImagePickerController *imagePickerCamera =[[UIImagePickerController alloc] init];
imagePickerCamera.delegate = self;
imagePickerCamera.mediaTypes = #[(NSString *) kUTTypeImage];
imagePickerCamera.allowsEditing = YES;
imagePickerCamera.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:imagePickerCamera animated:YES completion:nil];
});
} else {
NSString *errorString = [NSString stringWithFormat:#"This device does not support this feature."];
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Alert" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
} else if (buttonIndex == 1) {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *imagePickerAlbum =[[UIImagePickerController alloc] init];
imagePickerAlbum.delegate = self;
imagePickerAlbum.mediaTypes = #[(NSString *) kUTTypeImage];
imagePickerAlbum.allowsEditing = YES;
imagePickerAlbum.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePickerAlbum animated:YES completion:nil];
} else {
NSString *errorString = [NSString stringWithFormat:#"This device does not support this feature."];
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Alert" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
});
}
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
_upLoadimage = info[UIImagePickerControllerEditedImage];
}
I had the same problem with camera. My screen to modify or editing camera image was appearing black. The log showed me same error (CGAffineTransformInvert xx ). I did a lot of checks to determine or know where is the error.
In my application I use the component SVProgessHUD to show alerts and messages. Commenting lines with this use corrects the problem. I have updated to the last version of the component (1.0) and the error CGAffineTransformInvert disappears.

Resources