UIImagePickerController crash on iOS 5 - objective-c

UIImagePickerController *ii_picker= [[UIImagePickerController alloc] init];
ii_picker.delegate=self;
ii_picker.sourceType=UIImagePickerControllerSourceTypeCamera;
add_photo=NO;
[self presentModalViewController:ii_picker animated:YES];
[ii_picker release];
This used to work fine till I updated to iOS 5 on my iPhone. Something strange...
Problem isn't in the code. It's working in blank project! If I paste it to any place in my project's code, it's crashing. If I change UIImagePickerControllerSourceTypeCamera to UIImagePickerControllerSourceTypeSavedPhotosAlbum, it's working in iOS5.
Does anybody know where the problem is?

If app is crashes in iOS 5 , then try to use
[self dismissModalViewControllerAnimated:YES];
picker = nil ;
In place of
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[picker release];

If your app crashes as below, need to change the app's product name in English.
In my case product name was written in Korean, this led to the crash in ios5 when UIImagePickerController's source type is UIImagePickerControllerSourceTypeCamera.

Note, on the simulator, there's no camera, so it could cause this.

Related

iOS 8 Snapshotting a view that has not been rendered results in an empty snapshot

In iOS 8 I am having problem capturing images from camera till now I am using this code for
UIImagePickerController *controller=[[UIImagePickerController alloc] init];
controller.videoQuality=UIImagePickerControllerQualityTypeMedium;
controller.delegate=(id)self;
controller.sourceType=UIImagePickerControllerSourceTypeCamera;
[self presentViewController:controller animated:YES completion:nil];
But in iOS 8 I am getting this:
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.
I have tried with the solution provided by This Post with
#property (strong,nonatomic)UIImagePickerController *controller;
_controller=[[UIImagePickerController alloc] init];
_controller.videoQuality=UIImagePickerControllerQualityTypeMedium;
_controller.delegate=(id)self;
_controller.sourceType=UIImagePickerControllerSourceTypeCamera;
_[self presentViewController:controller animated:YES completion:nil];
and this
...
controller.modalPresentationStyle=UIModalPresentationFullScreen;
or
controller.modalPresentationStyle=UIModalPresentationCurrentContext;
...
and this
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self presentViewController:controller animated:YES completion:nil];
});
and this
[self presentViewController:controller animated:YES completion:NULL];
and this
[self presentViewController:controller animated:YES completion:^{
}];
any idea?
I'm pretty sure this is just a bug in iOS 8.0. It's reproducible with the simplest of POC apps that does nothing more than attempt to present a UIImagePickerController like you're doing above. Furthermore, there's no alternative pattern to displaying the image picker/camera, to my knowledge. You can even download Apple's Using UIImagePickerController sample app, run it, and it will generate the same error out of the box.
That said, the functionality still works for me. Other than the warning/error, do you have issues with the functioning of your app?
I was struggling with this issue for several hours, i have read every relevant topic and found out that the error was caused because under the privacy settings of my device, the camera access to my app was blocked!!! I have never denied access to camera and i don't know how it was blocked but that was the problem!
I don't have enough reputation points to comment on #greg's answer above, so will add my observations here. I have a Swift project for both iPad and iPhone. I have a method inside my main view controller (relevant bit below). When I test this on a phone, everything works properly and no warnings are generated. When I run it on an iPad, everything works properly but I see the warning about snapshotting the view. The interesting bit, however, is that when I run on an iPad without using the popover controller, everything works properly with no warning. Unfortunately, Apple mandates that the image picker must be used within a popover on iPad, if the camera is not being used.
dispatch_async(dispatch_get_main_queue(), {
let imagePicker: UIImagePickerController = UIImagePickerController();
imagePicker.sourceType = UIImagePickerControllerSourceType.SavedPhotosAlbum;
imagePicker.mediaTypes = [kUTTypeImage];
imagePicker.allowsEditing = false;
imagePicker.delegate = self;
if(UIDevice.currentDevice().userInterfaceIdiom == .Pad){ // on a tablet, the image picker is supposed to be in a popover
let popRect: CGRect = buttonRect;
let popover: UIPopoverController = UIPopoverController(contentViewController: imagePicker);
popover.presentPopoverFromRect(popRect, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Up, animated: true);
}else{
self.presentViewController(imagePicker, animated: true, completion: nil);
}
});
I ran into this after calling UIImagePickerController presentViewController: from the callback to a UIAlertView delegate. I solved the issue by pushing the presentViewController: call off the current execution trace using dispatch_async.
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
dispatch_async(dispatch_get_main_queue(), ^{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
if (buttonIndex == 1)
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
else
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController: imagePickerController
animated: YES
completion: nil];
});
}
I had this issue when animating some views and the app would go into background mode and come back. I handled it by setting a flag isActive. I set it to NO in
- (void)applicationWillResignActive:(UIApplication *)application
and YES in
- (void)applicationDidBecomeActive:(UIApplication *)application
and animate or not animate my views accordingly. Took care of the issue.
I had this with an UIAlertControllerStyleActionSheet giving the user the option to take a photo with the camera or use one from library.
I tried a symbolic breakpoint on the error message
That showed me the error is produced by the intern use of a UICollectionView during presentation
[self presentViewController:alert animated:YES completion:nil];
I fixed this by explixitly setting the frame before presenting
[alert setPreferredContentSize: alert.view.frame.size];
Here is the complete methode that is working without the error
-(void)showImageSourceAlertFromSender:(id)sender{
UIButton *senderButton = (UIButton*)sender;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:#"Camera" style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self takePhoto];
}];
UIAlertAction *libraryAction = [UIAlertAction actionWithTitle:#"Library" style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self selectPhotoFromLibraryFromSender:sender];
}];
[alert addAction:cameraAction];
[alert addAction:libraryAction];
alert.popoverPresentationController.delegate = self;
alert.popoverPresentationController.sourceRect = senderButton.frame;
alert.popoverPresentationController.sourceView = self.view;
[alert setPreferredContentSize: alert.view.frame.size];
[self presentViewController:alert animated:YES completion:^(){
}];}
You can silence the "Snapshotting a view" warning by referencing the view property before presenting the view controller. Doing so causes the view to load and allows iOS render it before taking the snapshot.
UIAlertController *controller = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.popoverPresentationController.barButtonItem = (UIBarButtonItem *)sender;
... setup the UIAlertController ...
[controller view]; // <--- Add to silence the warning.
[self presentViewController:controller animated:YES completion:nil];
For anyone that is seeing an issue with a black preview after image capture, hiding the status bar after the UIPickerController is shown seems to fix the issue.
UIImagePickerControllerSourceType source = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypeSavedPhotosAlbum;
UIImagePickerController *cameraController = [[UIImagePickerController alloc] init];
cameraController.delegate = self;
cameraController.sourceType = source;
cameraController.allowsEditing = YES;
[self presentViewController:cameraController animated:YES completion:^{
//iOS 8 bug. the status bar will sometimes not be hidden after the camera is displayed, which causes the preview after an image is captured to be black
if (source == UIImagePickerControllerSourceTypeCamera) {
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
}
}];
I found the same issue and tried everything. I have two different apps, one in objective-C and one in swift - both have the same problem. The error message comes in the debugger and the screen goes black after the first photo. This only happens in iOS >= 8.0, obviously it is a bug.
I found a difficult workaround. Shut off the camera controls with imagePicker.showsCameraControls = false and create your own overlayView that has the missing buttons. There are various tutorials around how to do this.
The strange error message stays, but at least the screen doesn't go black and you have a working app.
This might be a bug of built-in ImagePickerController. My code is working, but occasionally crashes on iPhone 6 Plus.
I've tried all solutions suggested by other answers but there were no luck. Problem finally solved after switching to JPSImagePickerController.
I've tried everything, my problem was that the image picker for the camera and photo library disappeared right after they showed. I solved it with the following line (swift)
imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
I'm pretty sure this is just a bug in iOS 8.0. It's reproducible with the simplest of POC apps that does nothing more than attempt to present a UIImagePickerController like you're doing above. Furthermore, there's no alternative pattern to displaying the image picker/camera, to my knowledge. You can even download Apple's Using UIImagePickerController sample app, run it, and it will generate the same error out of the box.
That said, the functionality still works for me. Other than the warning/error, do you have issues with the functioning of your app?
If we are using the UIImagePickerController as a property, then this warning will disappear. xcode assume that we are not using the result from the UIImagePickerController , if we are instantiating the UIImagePickerController within a function.
Calling this method worked for me. Place it after presenting your view.
[yourViewBeingPresented.view layoutIfNeeded];
I also encounter the same problem and I resolved it by checking if the camera is available:
BOOL cameraAvailableFlag = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
if (cameraAvailableFlag)
[self performSelector:#selector(showcamera) withObject:nil afterDelay:0.3];
I have came across with this issue. When we call the camera and release the views produced this issue. For an example call an camera and set view nil in viewDidDisappear method this error will come since there is not callback for camera event. Make sure about this case too for this error.
I got the same bug,getting bellow message in console while opening camera.
'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.'
For me problem was with the Bundle display name in Info.plist file.it was empty some how,i put my app name there and now it working fine.i did't received any camera permission alert because of empty Bundle display name.it blocked the view from rendering.
the problem was't with view but by presenting it without a permission.you can check it on settings-->privacy-->Camera,if your app not listed there problem might be same.
I'm using Phonegap, but this thread keeps coming as the first one when Googling about the error message.
For me this issue went away by defining the imagetype to PNG.
encodingType : Camera.EncodingType.PNG
So the whole line being:
navigator.camera.getPicture(successFunction, failFunction, { encodingType : Camera.EncodingType.PNG, correctOrientation:true, sourceType : Camera.PictureSourceType .PHOTOLIBRARY, quality: 70, allowEdit : false , destinationType: Camera.DestinationType.DATA_URL});
Your mileage may vary, but that did the trick for me.
Alternatively, consider using drawViewHierarchyInRect:
Swift:
extension UIImage{
class func renderUIViewToImage(viewToBeRendered: UIView) -> UIImage
{
UIGraphicsBeginImageContextWithOptions(viewToBeRendered.bounds.size, true, 0.0)
viewToBeRendered.drawViewHierarchyInRect(viewToBeRendered.bounds, afterScreenUpdates: true)
viewToBeRendered.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return finalImage
}
}
Objective-C:
- (UIImage *)snapshot:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Also see:
https://developer.apple.com/library/ios/qa/qa1817/_index.html
How to capture UIView to UIImage without loss of quality on retina display
In my case ( XCode 7 and iOS 9 ), I use UINavigationController "hidden", so Ihave to add UINavigationControllerDelegate to present camera or roll and it work like it is supposed to! And pickerControllerDelegate.self doesn't display error either!

App crash on iOS7 but runs fine with iOS6

While troubleshooting a crash that was only happening on iOS7 (iOS6 was fine), the application crashed several times on a line that wasn't helping with the troubleshooting, but eventually crashed once on a line like [object release].
After I removed the offending line, the crash disappeared.
Old code:
[imageView removeFromSuperview];
[imageView release];
imageView = nil;
imageView = [[UIImageView alloc] initWithImage:image];
[self addSubview:imageView];
New code:
[imageView removeFromSuperview];
//[imageView release];
imageView = nil;
imageView = [[UIImageView alloc] initWithImage:image];
[self addSubview:imageView];
The stack was showing the crash here: objc_msgSend ()
I would appreciate if someone could explain why it was crashing on iOS7 with the old code and what I was doing wrong?
Also I'd like to understand why it was not crashing with iOS6.
Try enabling NS Zombies to check that your aren't trying to over release it which it sounds like you are.. You should do a check to see if the imageView isn't nil before releasing it :)
I would recommend moving to ARC if you can though.

MPMediaPickerController - iOS7

I developed test application on iOS 7 that pick the music from music library using MPMediaPickerController.
But when I present the media picker controller,it shows empty screen.
This is the code
(void) pickSong
{
MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];
mediaPicker.delegate = self;
mediaPicker.allowsPickingMultipleItems = NO;
mediaPicker.prompt = NSLocalizedString(#"Select Your Favourite Song!", nil);
[mediaPicker loadView];
[self.navigationController presentViewController:mediaPicker animated:YES completion:nil];
}
#pragma mark - MPMediaPickerController delegate
(void) mediaPicker:(MPMediaPickerController *) mediaPicker2 didPickMediaItems:(MPMediaItemCollection *) mediaItemCollection {
[self dismissViewControllerAnimated:YES completion:nil];
MPMediaItem *mediaItem = [[mediaItemCollection items] objectAtIndex:0];
self.item.soundName = [mediaItem valueForProperty:MPMediaItemPropertyTitle];
self.item.soundUrl = [[mediaItem valueForProperty:MPMediaItemPropertyAssetURL] absoluteString];
}
(void) mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker{
[self dismissViewControllerAnimated:YES completion:NULL];
}
Please help me out.
This is an iOS bug, but it only occurs when running a 32 bit build on a 64 bit (A7) device (Only iPhone 5S for now). To work around it, add a 64 bit architecture to your app. (Open build settings in xcode, and change Architecture from $ARCHS_STANDARD to $ARCHS_STANDARD_INCLUDING_64_BIT.) You will then probably need to fix a number of compile, link and runtime issues. See Apple's 64-Bit Transition Guide.
Seems like there is a bug in ios7 where it doesn't like to be presented inside a uinavigation controller - try presenting it directly from a view controller.
I had the same problem and for me the solution was a combination of two of the solutions presented here. First I had to convert my app to be 64-bit ready by changing Architectures to "standard... (including 64-bit)". Once I corrected all the warnings that caused, I had to change the MPMediaPickerController to be presented modally rather than on the navigation stack:
- (IBAction)didSelectMusicPicker:(id)sender {
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];
picker.delegate = self;
picker.allowsPickingMultipleItems = YES;
picker.prompt = NSLocalizedString (#"Add songs to play", "Prompt in media item picker");
//[self.navigationController pushViewController:picker animated:YES];
[self presentViewController:picker animated:TRUE completion:NULL];
}
Of course, I also needed to change mediaPicker:didPickMediaItems: and mediaPickerDidCancel: to use dismissViewControllerAnimated. Once all that was fixed, the picker worked as expected on both iPhone 4 and iPhone 5S running iOS 7.
a thought: is the presented screen completely empty, or are you getting the navigation bar at the bottom but with no tracks listed? I've noticed that as of iOS 7 the picker now defaults to opening to the Playlist tab (it used to open to Albums, if I recall)… if you have no playlists on the device that would account for the empty screen…
I can see the list of songs and select the songs. But I cannot dismiss the view controller on pressing "Done". I've tried PresentViewController since Modal controller is deprecated.
- (IBAction) showMediaPicker: (id) sender {
picker =
[[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAnyAudio];
picker.delegate = self;
picker.allowsPickingMultipleItems = YES;
picker.prompt = NSLocalizedString (#"AddSongsPrompt", #"Prompt to user to choose some songs to play");
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleDefault animated:YES];
[self.picker removeFromParentViewController];
[self presentViewController:picker animated:YES completion:nil];
// [picker release];
}
// Responds to the user tapping Done after choosing music.
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection {
[self.picker removeFromParentViewController];
[self dismissViewControllerAnimated:YES completion:nil];
//
[self.delegate updatePlayerQueueWithMediaCollection: mediaItemCollection];
// [self.mediaItemCollectionTable reloadData];
// [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque animated:YES];
}
I've tried RemovefromSuperview also, nothing seems to work. I'm testing this on an iPhone 6 simulator and an iPhone 5 with iOS 8.1.3.
Anyone???
I also have the same problem before. But I found out just need to restart the device after upgrade. The music picker appear again.

Content not being added to UIPopoverController?

I'm new to iOS development so please cut me some slack.
I'm trying to learn how to use UIPopoverCotroller and I'm having a problem.
The popover appears correctly but nothing is added to it, its just black.
I'm using this line of code to try to add content to the popover:
self.photosPopover = [[UIPopoverController alloc]initWithContentViewController:self.photosPopoverViewController];
Heres some more code to help:
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController{
self.photosPopover=nil;
}
-(IBAction)photosPopoverButtonPressed:(id)sender{
if([self.photosPopover isPopoverVisible]){
[self.photosPopover dismissPopoverAnimated:YES];
self.photosPopover=nil;
return;
}
self.photosPopoverViewController = [[PhotosPopoverViewController alloc]init];
self.photosPopover = [[UIPopoverController alloc]initWithContentViewController:self.photosPopoverViewController];
[self.photosPopover setDelegate:self];
[self.photosPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[self.photosPopover setPopoverContentSize:CGSizeMake(320, 480)];
}
I'm using Xcode 4.3, ARC, and storyboards.
Thanks for your help!
-Shredder2794
You need to instantiate your view from storyboards. Sorry I didn't see this sooner...
self.photosPopoverViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"photosViewController"];
This is how you connect a customViewController to a viewController object in Storyboards. You build your PhotosPopoverViewController.h and PhotosPopoverViewController.m then you click your viewController object in storyboards and find the Custom Class identifier. Start typing your class name and it will autofill it.

How do I use UIImagePickerController just to display the camera and not take a picture?

I'd like to know how to open the camera inside of a pre-defined frame (not the entire screen). When the view loads, I have a box, and inside it, I want to display what the camera sees. I don't want to snap a picture, just basically use the camera as a viewfinder. I have searched this site and have not yet found what I'm looking for. Please help.
Thanks!
Thomas
Update 1:
Here is what I have tried so far.
1.) I added UIImageView to my xib.
2.) Connect the following outlet to the UIImageView in IB
IBOutlet UIImageView *cameraWindow;
3.) I put the following code in viewWillAppear
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
NSLog(#"viewWillAppear ran");
}
But this method does not run, as evident by the absence of NSLog statement from my console. Please help!
Thanks,
Thomas
Update 2:
OK I got it to run by putting the code in viewDidLoad but my camera still doesn't show up...any suggestions? Anyone....? I've been reading the UIImagePickerController class reference, but am kinda unsure how to make sense of it. I'm still learning iPhone, so it's a bit of a struggle. Please help!
- (void)viewDidLoad
{
[super viewDidLoad];
// Create a bool variable "camera" and call isSourceTypeAvailable to see if camera exists on device
BOOL camera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
// If there is a camera, then display the world throught the viewfinder
if(camera)
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// Since I'm not actually taking a picture, is a delegate function necessary?
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
NSLog(#"Camera is available");
}
// Otherwise, do nothing.
else
NSLog(#"No camera available");
}
Thanks!
Thomas
Update 3:
A-HA! Found this on the Apple Class Reference.
Discussion
The delegate receives notifications
when the user picks an image or movie,
or exits the picker interface. The
delegate also decides when to dismiss
the picker interface, so you must
provide a delegate to use a picker. If
this property is nil, the picker is
dismissed immediately if you try to
show it.
Gonna play around with the delegate now. Then I'm going to read on wtf a delegate is. Backwards? Whatever :-p
Update 4:
The two delegate functions for the class are
– imagePickerController:didFinishPickingMediaWithInfo:
– imagePickerControllerDidCancel:
and since I don't actually want to pick an image or give the user the option to cancel, I am just defining the methods. They should never run though....I think.
add
[picker
dismissModelViewControllerAnimated:YES];
to delegate method bodies.
It will dismiss the view.