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 Resizing an Image and Getting Ready to Send

Jacob McLaws
Jacob McLaws
1,497 Points

"Reset" method having trouble...

My file seems just about right except for the error showing up on my RESET method lines. I get this message: "No visible @interface for 'CameraViewController' declares the selector 'reset'" or down below in the line

- (void) reset {

I get "Use of undeclared identifier 'reset'".

I can't seem to figure this one out, but it feels like it's right under my nose!

//
//  CameraViewController.m
//  Ribbit
//
//  Created by McLaws, Jacob on 10/8/14.
//  Copyright (c) 2014 McLaws, Jacob. All rights reserved.
//

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

@end

@implementation CameraViewController


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

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    self.friendsRelation = [[PFUser currentUser] objectForKey:@"friendsRelation"]; //Ben says this could go in ViewDidLoad as well...

    self.recipients = [[NSMutableArray alloc] init];

    PFQuery *query = [self.friendsRelation query];
    [query orderByAscending:@"username"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if(error){
            NSLog(@"Error %@ %@", error, [error userInfo]);
        }
        else {
            self.friends = objects;
            [self.tableView reloadData];
        }
    }];


    if (self.image == nil && [self.videoFilePath length] == 0) {
    self.imagePicker = [[UIImagePickerController alloc] init];
    self.imagePicker.delegate = self;
    self.imagePicker.allowsEditing = NO;
    self.imagePicker.videoMaximumDuration = 10;

    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
{
    // Return the number of sections.
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [self.friends count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell =  [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    PFUser *user = [self.friends objectAtIndex:indexPath.row];
    cell.textLabel.text = user.username;
    if ([self.recipients containsObject:user.objectId]) {
        cell.accessoryType =UITableViewCellAccessoryCheckmark;
    }
    else {
        cell.accessoryType =UITableViewCellAccessoryNone;

    }

    return cell;
}

#pragma mark - Table View Delegate

-(void)tableView:(UITableView *) tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.tableView deselectRowAtIndexPath:indexPath animated:NO];

    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    PFUser *user = [self.friends objectAtIndex:indexPath.row];
    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [self.recipients addObject:user.objectId];
    }
    else {
        cell.accessoryType = UITableViewCellAccessoryNone;
        [self.recipients removeObject:user.objectId];
    }
}

#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);
        }
    }
    else {
        //video was filmed or selected
        NSURL *imagePickerURL = [info objectForKey:UIImagePickerControllerMediaURL];
        self.videoFilePath = [imagePickerURL path];
        if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
            //save the video!
            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(self.videoFilePath))
            UISaveVideoAtPathToSavedPhotosAlbum(self.videoFilePath, nil, nil, nil);
        }
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - IB ACTIONS

- (IBAction)cancel:(id)sender {
    [self reset];

    [self.tabBarController setSelectedIndex:0];
}

- (IBAction)send:(id)sender {
    if (self.image == nil && [self.videoFilePath length] == 0){
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Try again!"
                                                            message:@"Please capture or select a photo or video to share!"
                                                           delegate:self
                                                  cancelButtonTitle:@"Got it"
                                                  otherButtonTitles:nil];
        [alertView show];
        [self presentViewController:self.imagePicker animated:NO completion:nil];
    }
    else {
        [self uploadMessage];
        [self reset];

        [self.tabBarController setSelectedIndex:0];

    }
}

#pragma mark - Helper Methods

- (void)uploadMessage {
   //check if image or video
    NSData *fileData;
    NSString *fileName;
    NSString *fileType;


    if (self.image != nil) {
        UIImage *newImage = [self resizeImage:self.image toWidth:320.0f andHeight:480.0f];
        fileData = UIImagePNGRepresentation(newImage);
        fileName = @"image.png";
        fileType = @"image";
    }
    else{
        fileData = [NSData dataWithContentsOfFile:self.videoFilePath];
        fileName = @"video.mov";
        fileType = @"video";
    }

    PFFile *file = [PFFile fileWithName:fileName data:fileData];
    [file saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (error){
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An error occurred!"
                                                                message:@"Please try sending your message again!"
                                                               delegate:self
                                                      cancelButtonTitle:@"Got it"
                                                      otherButtonTitles:nil];
            [alertView show];
        }
        else {
            PFObject *message = [PFObject objectWithClassName:@"Messages"];
            [message setObject:file forKey:@"file"];
            [message setObject:fileType forKey:@"fileType"];
            [message setObject:self.recipients forKey:@"recipientIds"];
            [message setObject:[[PFUser currentUser] objectId] forKey:@"senderId"];
            [message setObject:[[PFUser currentUser]username] forKey:@"senderName"];
            [message saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
                if (error){
                    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An error occurred!"
                                                                        message:@"Please try sending your message again!"
                                                                       delegate:self
                                                              cancelButtonTitle:@"Got it"
                                                              otherButtonTitles:nil];
                    [alertView show];
                }
                else{
                    //everything was successful
                }

            }];

        }
    }
    //could try a third party pop up like MB Progress hub?


- (void) reset {
    self.image = nil;
    self.videoFilePath = nil;
    [self.recipients removeAllObjects];
}

- (UIImage *) resizeImage: (UIImage *) image toWidth: (float)width andHeight:(float)height {
    CGSize newSize =CGSizeMake(width, height);
    CGRect newRectangle = CGRectMake(0,0, width, height);
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:newRectangle];
    UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return resizedImage;
}


@end

1 Answer

Michael Hulet
Michael Hulet
47,913 Points

All you have to do is declare the reset method somewhere in your @interface. Try putting this either in your header file:

@interface
-(void)reset;
@end
Jacob McLaws
Jacob McLaws
1,497 Points

Thanks Michael!

I added - (void) reset; to my header and it eliminated one of the errors, but I still get: "Use of undeclared identifier "reset" on this line???

- (void) reset {
    self.image = nil;
    self.videoFilePath = nil;
    [self.recipients removeAllObjects];
}

and my @end line gets a "Missing '@end'" error.

Puzzling me...

Jacob McLaws
Jacob McLaws
1,497 Points

Any ideas for me here?

Michael Hulet
Michael Hulet
47,913 Points

For the sake of brevity, I didn't make the @interface line exactly how it's supposed to be. It should look something like this:

@interface CameraViewController : SuperclassOfYourClassWhichIDoNotKnow
-(void)reset;
//Any more declarations in your interface should go here
@end
Jacob McLaws
Jacob McLaws
1,497 Points

Sorry. I should've been more clear. I am pretty new with some of this, but I think I have that part right. That's why this is so confusing. Let me know if you see any problems in my header file below that might be resulting in the error "Use of undeclared identifier 'reset'".

//
//  CameraViewController.h
//  Ribbit
//
//  Created by McLaws, Jacob on 10/8/14.
//  Copyright (c) 2014 McLaws, Jacob. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>

@interface CameraViewController : UITableViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

@property (nonatomic,strong) UIImagePickerController *imagePicker;
@property (nonatomic,strong) UIImage *image;
@property (nonatomic, strong) NSString *videoFilePath;
@property (nonatomic,strong) NSArray *friends;
@property (nonatomic,strong) PFRelation *friendsRelation;
@property (nonatomic,strong) NSMutableArray *recipients;


- (IBAction)cancel:(id)sender;
- (IBAction)send:(id)sender;

- (void)uploadMessage;
- (UIImage *) resizeImage: (UIImage *) image toWidth: (float)width andHeight:(float)height;
-(void) reset;

@end