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

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

can you post your header file as well

Added.

6 Answers

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

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.

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.

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?

He has it in the viewDidLoad method.

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

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

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.

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.

set self.image == nil for viewDidDissAppear.

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

Ben can we get your solution?