Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Self-Destructing Message iPhone App Capturing Photo and Video Using UIImagePickerController Saving the Media

Jacob McLaws
Jacob McLaws
1,497 Points

Problem with Camera View Controller always reverting back to picker

So my Ribbit app works great except that when I take a photo (or choose one from my library on the simulator) it goes briefly to the camera table view (where I would be able to choose the friends to send to) but then the camera picker opens back up and prompts to take/choose another picture. That's not what happens in Ben's vid. Please advise. Below is my .m code:

#import "CameraViewController.h"
#import <MobileCoreServices/UTCoreTypes.h>
@interface CameraViewController ()

@end

@implementation CameraViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.imagePicker = [[UIImagePickerController alloc] init];
    self.imagePicker.delegate = self;
    self.imagePicker.allowsEditing = NO;

    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
        self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    }

    else{
        self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    }

    self.imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:self.imagePicker.sourceType];

    [self presentViewController:self.imagePicker animated:NO completion:nil];
}


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 0;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return 0;
}

#pragma mark - Image Picker Controller delegate

- (void)imagePickerControllerDidCancel: (UIImagePickerController *)picker {
    [self dismissViewControllerAnimated:NO completion:nil];

    [self.tabBarController setSelectedIndex:0];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        //a photo was taken or selected
        self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
        if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
            //save the image!
            UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
        }
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}

@end

Header File

#import <UIKit/UIKit.h>

@interface CameraViewController : UITableViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

@property (nonatomic,strong) UIImagePickerController *imagePicker;
@property (nonatomic,strong) UIImage *image;
@property (nonatomic, strong) NSString *videoFilePath;
@end
Stone Preston
Stone Preston
42,016 Points

can you post your header file as well

6 Answers

Stone Preston
Stone Preston
42,016 Points

you might try moving the dismissal code outside of the if statement in didFinishPickingMedia

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        //a photo was taken or selected
        self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
        if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
            //save the image!
            UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
        }

    }

[self dismissViewControllerAnimated:YES completion:nil];
}
reardelt
reardelt
8,030 Points

I have the same problem and it still does not work by putting the dissmissl outside the outer most if block.

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Sorry for all of you suffering with an issue here! I haven't seen this thread before. I'll take a look this weekend and post a reply.

Ben Jakuben
Ben Jakuben
Treehouse Teacher

Benjamin McMahan (who pointed me to this thread) found a solution elsewhere in the Forum: https://teamtreehouse.com/forum/build-a-selfdestructing-message-iphone-appadding-recipients

Thanks, Benjamin! I am adding notes about this now. Really sorry for the trouble!

In viewWillAppear, create the imagePicker using the above if block. We also need to implement viewDidDisappear to reset self.image.

Bennett Lin
Bennett Lin
6,238 Points

It looks like you're presenting your UIImagePickerController in your CameraViewController's viewWillAppear method. This method gets called each time you dismiss the UIImagePickerController and return to the CameraViewController.

Jacob McLaws
Jacob McLaws
1,497 Points

Isn't this what Ben uses in the tutorial though? His seems to work just fine. Is there another method I should be presenting the controller in so it only runs when I haven't already selected something?

Bennett Lin
Bennett Lin
6,238 Points

He has it in the viewDidLoad method.

Jacob McLaws
Jacob McLaws
1,497 Points

He instructs to move it to ViewWillAppear about half way through...

Bennett Lin
Bennett Lin
6,238 Points

Oh, okay, you're right. Then Stone's answer is correct.

Jacob McLaws
Jacob McLaws
1,497 Points

I used this and it solved it for now.

if (self.image == nil && [self.videoFilePath length] == 0)

But now there's a problem if I take a picture, navigate away from recipients and then navigate back to camera.

Michael Liquori
Michael Liquori
8,131 Points

That is how I am fixing it, now that we have the cancel button which sets the self.image to nil again.

What is your problem exactly? I don't have a developer account so I'm not seeing the camera interface, but I'm not having any issues. I did use self.videoFilePath.length instead of bracket notation, but that should not make a difference.

reardelt
reardelt
8,030 Points

set self.image == nil for viewDidDissAppear.

brackston mayhall
brackston mayhall
95 Points

had to use if (self.image == nil) {}; in viewWillAppear.

Ben can we get your solution?