How To Create an App Like Instagram With a Web Service Backend – Part 2/2

This is a blog post by iOS Tutorial Team member Marin Todorov, a software developer with 12+ years of experience, an independent iOS developer and the creator of Touch Code Magazine. Ready to go on building your photo-sharing iPhone app? Last time, in first part of the tutorial, you created the basics of the web […] By Marin Todorov.

Leave a rating/review
Save for later
Share

Learn how to make a cool photo sharing app with a web service backend!

Learn how to make a cool photo sharing app with a web service backend!

Learn how to make a cool photo sharing app with a web service backend!

This is a blog post by iOS Tutorial Team member Marin Todorov, a software developer with 12+ years of experience, an independent iOS developer and the creator of Touch Code Magazine.

Ready to go on building your photo-sharing iPhone app?

Last time, in first part of the tutorial, you created the basics of the web service, and added the ability to login with a username/password and upload files.

In this second and final part of the tutorial, you get to do the cool stuff – taking photos, applying effects and uploading files to the server.

Grab some tasty breakfast like mine, and let’s go!

Getting Started: the Photo Screen

All right, it’s time to fire up the iPhone camera, capture some action and submit the results to the server via the API!

Open the tutorial project in Xcode and take a look at Storyboard.storyboard. What you have (already prepared) on the Photo Screen is a UIImageView where you’ll show the preview of the photo taken, a UITextField where the user can enter a title for the photo, and an action button that displays the screen menu. That’s everything you need for your photo app!

Switch to PhotoScreen.m and find btnActionTapped:. It’s empty, so add the code to show a menu of options when the action button is tapped:

[fldTitle resignFirstResponder];

//show the app menu
[[[UIActionSheet alloc] initWithTitle:nil
                             delegate:self
                    cancelButtonTitle:@"Close"
               destructiveButtonTitle:nil
                    otherButtonTitles:@"Take photo", @"Effects!", @"Post Photo", @"Logout", nil] 
 showInView:self.view];

First you make sure there’s no on-screen keyboard present. Since there’s only one text field, just calling resignFirstResponder on it should be enough.

Then you show an action sheet with all the possible actions the user can perform:

Photo screen menu

  1. Take Photo – Invoke the standard camera dialog of iOS.
  2. Effects! – You’ll borrow some code from my colleague Jacob Gundersen‘s tutorial on applying effects to images in order to apply a Sepia effect to the user’s photo.
  3. Post Photo – Send the photo to the server using an API call.
  4. Logout – End the user session with the server.

You need to implement a UIActionSheet delegate method to handle taps on the different buttons in the sheet. But before you do that, you need to set up a few methods to handle each of the above actions. Above the @implementation directive, add the private definitions for those methods as follows:

@interface PhotoScreen(private)
-(void)takePhoto;
-(void)effects;
-(void)uploadPhoto;
-(void)logout;
@end

Now add this code to the end of the file to implement UIActionSheet:

-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (buttonIndex) {
        case 0:
            [self takePhoto]; break;
        case 1:
            [self effects];break;
        case 2:
            [self uploadPhoto]; break;
        case 3:
            [self logout]; break;
    }
}

Build and run the project, log in and tap on the action button at the right of the tab bar. The menu should look something like this:

Instagram3

Start by implementing the first item: Take Photo.

Be a Photo-Snapping Beast

For those of you who’ve never interacted with the iPhone’s camera programmatically, it’s actually very easy. There’s an Apple standard view controller, which you only need to instantiate, set up and then present modally. Whenever the user takes a photo or cancels the process, callback methods on your class are called to handle the action.

Add the takePhoto method to the end of PhotoScreen.m:

-(void)takePhoto {
    UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
#if TARGET_IPHONE_SIMULATOR
    imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
#else
    imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
#endif
    imagePickerController.editing = YES;
    imagePickerController.delegate = (id)self;
    
    [self presentModalViewController:imagePickerController animated:YES];
}

UIImagePickerController is the view controller that allows the user to use the camera. As with any normal class, you make a new instance.

Next you set up the sourceType property – you can instruct the dialog whether the user should actually use the camera or can choose from the Photos library on the device. In the code above I snuck in some code to detect whether the app is running on the iPhone simulator and if so, the dialog just accesses the Photo library. (Because, you know… there’s no camera on the simulator.)

Setting “editing” to YES allows the user to do simple editing operations on the photo before accepting it.

Finally, you present the camera dialog as a modal view and you leave the user in Apple’s hands. Next time you hear from the user, it’ll be in the methods handling response from the camera dialog.

You will be doing some scaling down and cropping of the images the users take with the camera, so you need to import few handy UIImage categories. Scroll to the top of the file and below the other imports, add this one:

#import "UIImage+Resize.h"

Now implement two UIImagePickerControllerDelegate methods. Add the following to the end of the file:

#pragma mark - Image picker delegate methdos
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
	UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
    // Resize the image from the camera
	UIImage *scaledImage = [image resizedImageWithContentMode:UIViewContentModeScaleAspectFill bounds:CGSizeMake(photo.frame.size.width, photo.frame.size.height) interpolationQuality:kCGInterpolationHigh];
    // Crop the image to a square (yikes, fancy!)
    UIImage *croppedImage = [scaledImage croppedImage:CGRectMake((scaledImage.size.width -photo.frame.size.width)/2, (scaledImage.size.height -photo.frame.size.height)/2, photo.frame.size.width, photo.frame.size.height)];
    // Show the photo on the screen
    photo.image = croppedImage;
    [picker dismissModalViewControllerAnimated:NO];
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [picker dismissModalViewControllerAnimated:NO];
}

Have a look at imagePickerController:didFinishPickingMediaWithInfo: first:

  1. All information about the image is passed via the info dictionary. So you have to first get the image from the dictionary.
  2. Then, you call resizedImageWithContentMode:bounds:interpolationQuality: to get a scaled-down image of the user’s photo. (This method also fixes wrong camera image orientation, as often happens.)
  3. Next you crop the image (which is a rectangle) to a square format by calling croppedImage: on the scaled image. Square photos are all the rage these days and you want only the best for your app :]
  4. You show the scaled and cropped image in the image view.
  5. Finally, you hide the camera dialog.

If the user cancels the process of taking a photo, imagePickerControllerDidCancel: will be invoked. All you actually need to do is dismiss the camera dialog.

That’s it! Fire up the app (either on device or simulator) and try taking some photos.

Note: You’ll only be able to use the camera on a device. If you’re testing the app on the simulator, you need one or more photos in your photo library on the simulator in order to do anything. Plus, if you’ve got your web server on your local machine, you won’t be able to access the web server via the http://localhost URL you specified in API.m. Instead, you’ll have to change the URL to indicate your machine’s IP address.

You can add new photos to the simulator by simply dragging and dropping an image onto the simulator. This will show the image in mobile Safari. Then, simply tap on the image and hold until you get an Action Sheet allowing you to save the image to the simulator’s photo library :]

Note: You’ll only be able to use the camera on a device. If you’re testing the app on the simulator, you need one or more photos in your photo library on the simulator in order to do anything. Plus, if you’ve got your web server on your local machine, you won’t be able to access the web server via the http://localhost URL you specified in API.m. Instead, you’ll have to change the URL to indicate your machine’s IP address.

You can add new photos to the simulator by simply dragging and dropping an image onto the simulator. This will show the image in mobile Safari. Then, simply tap on the image and hold until you get an Action Sheet allowing you to save the image to the simulator’s photo library :]

First photo taken with iReporter

Contributors

Over 300 content creators. Join our team.