Presenting UIImagePickerController in camera mode causes crash in iOS 7 - ios

At the time of presenting UIImagePickerController in camera mode using the code below, Xcode 5 memory view shows that my app consumes about 20 MB. When I present the controller, I receive memory warning in the overrode didReceiveMemoryWarning. But even without a chance to release any resources in there, the app just crashes without leaving any log messages. I am running the code in an iPhone 4S. I see other similar questions but the symptoms are slightly different than mine and I don't see any clear answers that led to resolving my issue. The same code does not cause a problem in iOS 6 or when I present the controller in photo library mode. My specific questions are:
Would it be normal to get memory warning with about 20 MB memory usage when presenting UIImagePickerController in camera mode?
Should I deal with this problem by reducing the memory consumption level further before I present the UIImagePickerController?
===
- (IBAction)cameraClicked:(id)sender
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.navigationBarHidden = YES;
imagePicker.toolbarHidden = YES;
imagePicker.allowsEditing = NO;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:imagePicker animated:YES completion:nil];
}

What is the error you are getting is it ? EXC_BAD_ACCESS
Try to debug with NSZombieEnabled available in instruments and also Symbolic and exceptional breakpoints so that you can trace the reason for the crash.

Related

Using Instruments to trace memory leak Xcode5 and iOS7

I developed my first app and still learning. Just updated Xcode 5 yesterday and my iPhone 5 is running iOS 7.1. I am now working on understanding the Instruments tool to analyze my app. I am using the Leak profile in Instruments and have come across a retain cycle and leak which I can't figure out. Appreciate any help I can get to understand a) how to pinpoint the bug and b) what I did wrong and how to avoid it in the future.
In my app, I am using the camera to take a pic. While the camera is up, I tapped on the screen to focus and that is when I noticed the leak pop up in Instruments. Looks like there is a retain cycle not in my code (if I understand correctly) and a root leak in my code which I don't understand.
I am using ARC, so I should not have to release "picker" in the part of my code that Instruments is pointing me to (part 2 below, with code).
What can I do about the retain cycle. It is not in my code, but am I still the cause of it? Does it stem from the "root leak?" If I am NOT responsible for it, what's should I do about it?
My only code in this stack trace does not help me understand where the leak is coming from. The line is Instruments points me to in my code is [picker dismissViewControllerAnimated:YES completion:nil]; in my imagePickerController:didFinishPickingMediaWithInfo: method. I am pasting the code below.
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *pickerImage = [info objectForKey:
UIImagePickerControllerOriginalImage];
_imageView.image = pickerImage;
[picker dismissViewControllerAnimated:YES completion:nil]; // <--- mem-leak
}
EDIT - Code where I create my UIImagePickerController.
- (IBAction)snapPicture:(id)sender
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// If the camera button was tapped AND we have a camera, use it...
if ((sender == _cameraButton) && [UIImagePickerController
isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
} else {
[imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
}
imagePicker.delegate = self;
// bring up the image picker view
[self presentViewController:imagePicker animated:YES completion:nil];
}
Here's my theory: what you've encountered is evidently a bug (or flaw) in Apple's own code, and all you can do is laugh maniacally and forget about it.
To test my theory, I ran my own code, written totally separately and at a different time. It does almost the same thing your code does: it lets the user take a picture, and puts the image into the interface. Here's my code:
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch17p702takeAPicture/ch30p962takeAPicture/ViewController.m
I ran my code under Instruments with the Leaks instrument, and guess what? I saw the same issues you did.
Naturally, I then started searching on Stack Overflow, and all of this turns out to be old ground. For example:
UIImagePickerController memory leak on iOS5
Even Apple's own sample code, called PhotoPicker (or Using UIImagePickerController to Select Pictures and Take Photos) has the same leak.

Laggy presentation of SLServiceTypeFacebook

so I'm making a post to Facebook and want the user to select an image before doing that.
Once the image is picked and I show Facebook. Problem is, when I show Facebook straight away, without the image picking part, it looks fine. When I show it after picking the image, Facebook sharing appears animated, but laggy. As if the action has a very low framerate or something.
Here's my code:
self.portraitPicker = [[UIImagePickerController alloc] init];
#if !(TARGET_IPHONE_SIMULATOR)
self.portraitPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
#endif
[self.portraitPicker setDelegate:self];
self.portraitPicker.allowsEditing = YES;
[self presentViewController:self.portraitPicker animated:YES completion:nil];
Now when this is complete, I show the Facebook posting modally:
[picker dismissViewControllerAnimated:YES completion:^{
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook])
{
self.facebookController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[self.facebookController setInitialText:#"Some text"];
[facebookController addImage:pickedImage];
[self presentViewController:self.facebookController animated:NO completion:nil];
}
}];
I can do this in the didFinishPickingMediaWithInfo or the imagePickerControllerDidCancel, doesn't matter, the problem still comes up.
Being desperate, I tried:
Showing it on the main thread delayed
Showing it async
Showing it outside the dismiss-block
Showing it from the AppDelegate's rootviewcontroller instead
This is not Facebook-related as it happens with SLServiceTypeTwitter as well as with MFMessageComposeViewController.
Can't seem to do away with the laggy animation that ONLY happens showing the image picker. Does anyone know what's causing this?
Given the lack of response and similar issues, I figured the cause was my own architecture.
It turns out that one of my viewcontrollers' ViewDidAppear was called after the camera picker was displayed (as it became the active viewcontroller and consequently the inactive one, giving control back to the original viewcontroller).
Blocking the background calls and animation that happened in this viewDidAppear resolved the issue. I still don't know why calling it delayed (i.e. 10 seconds, or even 100 seconds into the future, when nothing was going on) still had the laggy appearence show up, but there it is.

App Terminated due to Memory Pressure when using camera in iOS 7

I am facing error App Terminated due to Memory Pressure when I capture some images using UIImagePickerController Camera.
I receive memory warnings first and then suddenly app crashes. This issue is in iOS 7 specifically as in iOS 6 it is working fine.
Does someone know why is this memory issue occuring in iOS 7 on using camera.
Note: I tried to minimize RAM usage because it may also be the reason for this memory pressure. But still getting warning.
I just posted this answer on a similar post (iOS 7 UIImagePicker preview black screen). Here's what I said:
About 5 months ago my team discovered a memory leak with UIImagePickerController. Each instantiation slowed down the app exponentially (i.e. first alloc-init had a 1 second delay, second had a 2 second delay, third had a 5 second delay). Eventually, we were having 30-60 delays (similar to what you're experiencing).
We resolved the issue by subclassing UIImagePickerController and making it a Singleton. That way it was only ever initialized once. Now our delay is minimal and we avoid the leak. If subclassing isn't an option, try a class property in your viewController and just lazy load it like so.
-(UIImagePickerController *)imagePicker{
if(!_imagePicker){
_imagePicker = [[UIImagePickerController alloc]init];
_imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
return _imagePicker;
}
Then you can just call it later like:
[self presentViewController:self.imagePicker animated:YES completion:nil];
From what I could tell, this is just an issue with the UIImagePickerController in iOS 7. Previous versions seems to be fine.

UIImagePickerController and External display

I am writing an iPad kiosk-type application that allows a visitor to record a video using the front facing camera and view existing videos in the Camera Roll that are targeting an External monitor. I am just learning XCode, and working in Xcode 4.4.1 targeting iOS 5. It seems like a lot has changed recently and this is making it much harder to learn so I am trying to keep things as simple as possible, that's why I am using UIImagePicker.
Everything is working as I wish, with one exception – I am not able to toggle between the external display and the iPad as I want. When the user records a video, it is full screen on the iPad. That's fine, however after they stop recording, the video is immediately sent to the external display for approval and a placeholder image is left in the UIPopover. What I would rather see/do is either keep the video preview full screen on the iPad, or target the video to the UIPopover.
The reason is that the external display is not easily viewable from where the user is accessing the iPad. Therefore, they are being asked to approve (click Use) on something they can't really see. It would be much better to keep it on the iPad. The code below is what I have used to allow recording.
Everything else works great, I want the user to select videos from the Library and display on the External monitor, and since that's the default behavior it works fine.
The closest answer I could find so far is this: UIImagePickerController in an existing UIPopoverController
Is there a simple way to disable the external display or keep the video preview from being sent?
- (IBAction)useCameraRoll:(id)sender
{
if([self.popoverController isPopoverVisible]) {
[self.popoverController dismissPopoverAnimated:YES];
} else {
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
imagePicker.mediaTypes = [NSArray arrayWithObjects:(NSString *) kUTTypeMovie, nil];
imagePicker.allowsEditing = NO;
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
//self.popoverController = [[UIPopoverController alloc] setContentViewController:animated];
self.popoverController.delegate = self;
[self.popoverController
presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
newMedia = NO;
}
}
}
Coincidentally, I have been working on a similar kiosk app with an iPad. In my case it utilizes some Augmented Reality to show relevant content on the external display. I use the iPad screen as a configuration panel for the augmented reality experience.
Best way, that I found, to approach this, would be to use separate windows with the two UIScreens for each of the displays. This enables you to craft the experience properly. I am not sure if you are using this approach already, but if you aren't, then this is the way to go.
To get started you can read the ExternalDisplay code sample. From the excerpt:
From the ExternalDisplay sample code in the iOS Developer Library:
To display content on an external display, do the following:
Use the screens class method of the UIScreen class to determine if an external display is available.
If an external screen is available, get the screen object and look at the values in its availableModes property. This property contains
the configurations supported by the screen.
Select the UIScreenMode object corresponding to the desired resolution and assign it to the currentMode property of the screen
object.
Create a new window object (UIWindow) to display your content.
Assign the screen object to the screen property of your new window.
Configure the window (by adding views or setting up your OpenGL ES rendering context).
Show the window.
Also, the UIScreen documentation is quitehelpful.

UIImagePickerController appears but camera doesn't start on iOS 5

I have an app where I present a UIImagePickerController with source type UIImagePickerControllerSourceTypeCamera. Everything works fine unless I leave the app and come back (multitasking is enabled so the app comes back right where it left off) and I present the UIImagePickerController again. It appears on screen but the camera never shows, the animation where the camera is revealed never happens, here is a screenshot:
If I press cancel and present the UIImagePickerController again, the camera will show up fine. So the only time this problem occurs is the first time I present the UIImagePickerController after coming back to the app. Anyone know why this is happening? I'm coding for iOS 5
I'm presenting the UIImagePickerController with:
[self presentViewController:capturePhotoPicker animated:YES completion:nil];
and dismissing it with:
[self dismissViewControllerAnimated:YES completion:nil];
I am using the same UIImagePickerController object each time I present it
I had exactly the same problem and then realized I wasn't releasing the UIImagePickerController after presenting it. The camera now works fine first-time after leaving and returning to the app.
So this is my exact code:
UIImagePickerController *takePhotoController = [[UIImagePickerController alloc] init];
takePhotoController.sourceType = UIImagePickerControllerSourceTypeCamera;
takePhotoController.delegate = self;
[self presentModalViewController:takePhotoController animated:YES];
[takePhotoController release];
It's one of those problems you can spend ages on, and the solution is not that obvious (well, it wasn't to me), so I hope this helps some people!
if you change the -(void)viewDidLoad to - (void)viewDidAppear:(BOOL)animated it fixes the problem. I've spent the last 2 weeks trying to figure this out

Resources