An Example iOS 5 iPad Camera Application

From Techotopia
Jump to: navigation, search
PreviousTable of ContentsNext
Accessing the iPad Camera and Photo LibraryVideo Playback from within an iOS 5 iPad Application


Purchase the fully updated iOS 10 / Swift 3 / Xcode 8 edition of this book in eBook ($19.99) or Print ($45.99) format.
iOS 10 App Development Essentials Print and eBook (ePub/PDF/Kindle) edition contains over 100 chapters. Learn more...

Buy eBook Buy Print Preview Book


In the chapter entitled Accessing the iPad Camera and Photo Library we looked in some detail at the steps necessary to provide access to the iPad camera, camera roll and photo libraries in an iPad application. The purpose of this chapter is to build on this knowledge by working through an example iPad application designed to access the device’s camera and photo camera roll.




An Overview of the Application

The application user interface for this example will consist of an image view and a toolbar containing two buttons. When selected by the user, the first button will display the camera to the user and allow a photograph to be taken and subsequently displayed in the image view. The second button will provide access to the camera roll where the user may select an existing photo image. In the case of a new image taken with the camera, this will be saved to the camera roll.

Since we will be covering the playback of video in the next chapter (Video Playback from within an iOS 5 iPad Application) the camera roll and camera will be restricted to still images in this example. The addition of video support to this application is left as an exercise for the reader at the end of the next chapter.

Creating the Camera Project

Begin the project by launching Xcode and creating a new iPad iOS application project named camera using the View-based application template.


Adding Framework Support

The application developed in this chapter relies on the MobileCoreServices framework which must be added to the project. This can be achieved by selecting the product target entry from the project navigator panel (the top item named camera) and clicking on the Build Phases tab in the main panel. In the Link Binary with Libraries section click on the ‘+’ button, select the MobileCoreServices.framework entry from the resulting panel and click on the Add button.

Configuring Protocols, Outlets and Actions

The UIImagePickerController class requires a delegate to be declared that conforms to the UIImagePickerControllerDelegate and UINavigationControllerDelegate protocols. Since the camera roll will be presented to the user using a popover, it will also be necessary to implement the UIPopoverControllerDelegate protocol within the view controller.

In addition we will need an outlet that provides access to the UIImageView object in the user interface where photos will be displayed. We also need to declare two action methods that will be called when the user selects the toolbar buttons, a boolean flag to indicate whether the image needs to be saved or not and references to both the toolbar and popover controller objects. We will also need to import the MobileCoreServices.h file. With these requirements in mind, select the cameraViewController.h file in the Xcode project navigator panel and modify it is follows:

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

@interface cameraViewController : UIViewController
<UIImagePickerControllerDelegate,
UINavigationControllerDelegate, UIPopoverControllerDelegate>

@property (nonatomic) BOOL newMedia;
@property (nonatomic, strong) IBOutlet UIImageView *imageView;
@property (nonatomic, strong) UIPopoverController *popoverController;
@property (nonatomic, strong) IBOutlet UIToolbar *toolbar;
- (IBAction)useCamera: (id)sender;
- (IBAction)useCameraRoll: (id)sender;
@end

Designing the User Interface

The next step in this tutorial is to design the user interface. This is a very simple user interface consisting of a UIImageView and a UIToolbar. Select the cameraViewController.xib file and drag and drop components from the Library window (View -> Utilities -> Object Library) onto the view. Position and size the components so that the user interface resembles the following illustration:


The user interface of an ipad iOS 5 camera app

Figure 57-1


Next, Ctrl-click on the File’s Owner object and drag the resulting line to the UIImageView object in the view window. Select the imageView outlet from the resulting menu. Repeat this step to connect the toolbar outlet to the UIToolBar component.

Adding another Button to the Toolbar

When the toolbar was added to the view it also included a single bar button item. Since the application will need two buttons, drag and drop a second bar button item from the Object Library onto the toolbar. Double click on the first button and change the label to Camera. Repeat this step to change the second button to read Camera Roll. Ctrl-click over the Camera button and drag the resulting line to the File’s Owner icon. Release the line and select the useCamera method. Similarly, connect the Camera Roll button to the useCameraRoll method.

Implementing the Camera Action Method

The useCamera method now needs to be implemented. This method first needs to check that the device on which the application is running has a camera. It then needs to create a UIImagePickerController instance, assign the cameraViewController as the delegate for the object and define the media source as the camera. Since we do not plan on handling videos, the supported media types property is set to images only. Finally, the camera interface will be displayed. The last task is to set the newMedia flag to YES to indicate that the image is new (and therefore needs to be saved) and is not an existing image from the camera roll. Bringing all these requirements together, along with the @synthesize directive for the previously declared outlets, gives us the following useCamera method:

#import "cameraViewController.h"

@interface cameraViewController ()

@end

@implementation cameraViewController
@synthesize imageView, popoverController, toolbar, newMedia;


- (IBAction) useCamera: (id)sender
{
    if ([UIImagePickerController isSourceTypeAvailable:
         UIImagePickerControllerSourceTypeCamera])
    {
        UIImagePickerController *imagePicker =
        [[UIImagePickerController alloc] init];
        imagePicker.delegate = self;
        imagePicker.sourceType =
        UIImagePickerControllerSourceTypeCamera;
        imagePicker.mediaTypes = [NSArray arrayWithObjects:
                                  (NSString *) kUTTypeImage,
                                  nil];
        imagePicker.allowsEditing = NO;
        [self presentModalViewController:imagePicker
                                animated:YES];
        newMedia = YES;
    }
}
.
.
@end

Implementing the useCameraRoll Method

The useCameraRoll method is responsible for displaying the camera roll view within a popover, the code for which is as follows:

- (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 =
            UIImagePickerControllerSourceTypePhotoLibrary;
            imagePicker.mediaTypes = [NSArray arrayWithObjects:
                                  (NSString *) kUTTypeImage,
                                  nil];
            imagePicker.allowsEditing = NO;

            self.popoverController = [[UIPopoverController alloc]
                initWithContentViewController:imagePicker];

            self.popoverController.delegate = self;

            [self.popoverController 
                presentPopoverFromBarButtonItem:sender
                permittedArrowDirections:UIPopoverArrowDirectionUp
                animated:YES];

             newMedia = NO;
        }
    }
}

The code begins by checking if the popover is already displayed. If so then this indicates that the user has touched the Camera Roll button a second time after the popover was displayed. Convention dictates that under such circumstances the popover should be dismissed. In the event that the popover is not yet visible an image picker object is created, configured to display the camera roll with images only and editing disabled.

The popover controller is then created passing through the image picker as the view. The view controller is designated as the delegate for the popover object before the popover is displayed to the user. The sender object passed through to this method references the Use Camera button in the toolbar. This object is passed through to the popoverController’s presentPopoverFromBarButtonItem: method so that the popover is positioned directly above, and pointing to, the button when displayed. Finally, the imagePicker object is released and the newMedia flag set to NO so that the selected image does not get re-saved to the camera roll.

Writing the Delegate Methods

As described in Accessing the iPad Camera and Photo Library, in order to fully implement an instance of the image picker controller delegate protocol it is necessary to implement some delegate methods. The most important method is the didFinishPickingMediaWithInfo which is called when the user has finished taking or selecting an image. The code for these methods in our example is as follows:

#pragma mark -
#pragma mark UIImagePickerControllerDelegate

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [self.popoverController dismissPopoverAnimated:true];
    NSString *mediaType = [info
           objectForKey:UIImagePickerControllerMediaType];
    [self dismissModalViewControllerAnimated:YES];
    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        UIImage *image = [info
            objectForKey:UIImagePickerControllerOriginalImage];

        self.imageView.image = image;
        if (newMedia)
            UIImageWriteToSavedPhotosAlbum(image,
               self,  
               @selector(image:finishedSavingWithError:contextInfo:),
               nil);
    }
    else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
    {
                // Code here to support video if enabled
        }
}

-(void)image:(UIImage *)image
finishedSavingWithError:(NSError *)error
 contextInfo:(void *)contextInfo
{
    if (error) {
        UIAlertView *alert = [[UIAlertView alloc]
           initWithTitle: @"Save failed"
           message: @"Failed to save image"
           delegate: nil
           cancelButtonTitle:@"OK"
           otherButtonTitles:nil];
        [alert show];
    }
}

The code in this delegate method dismisses and releases the image picker popover and identifies the type of media passed from the image picker controller. If it is an image it is displayed on the view image object of the user interface. If this is a new image it is saved to the camera roll. The finishedSavingWithError method is configured to be called when the save operation is complete. If an error occurred it is reported to the user via an alert box.

It is also necessary to implement the imagePickerControllerDidCancel delegate method which is called if the user cancels the image picker camera session without taking a picture or making an image selection. In most cases all this method needs to do is dismiss the image picker camera interface:

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

Updating viewDidUnload

The final task before trying out the application is to notify the system that we have finished with the outlet variables:

- (void)viewDidUnload {
    self.imageView = nil;
    self.popoverController = nil;
    self.toolbar = nil;
}

Building and Running the Application

In order to experience the full functionality of this application it will be necessary to install it on a physical iPad device. Steps on performing this are covered in Testing iOS 5 Apps on the iPad – Developer Certificates and Provisioning Profiles.

Assuming certificates and provisioning are configured, click on the Run button to launch the application. Once application loads, select the Camera button to launch the camera interface:


Viewing an image taken from within an iPad iOS 5 app


Once a picture has been taken and selected for use in the application it will appear in the image view object of our application user interface:

Selecting the Camera Roll button will provide access to the camera roll of the device via a popover where an image selection can be made:


Accessing the camera roll from an iPad iOS 5 app

Summary

This chapter has demonstrated the ease with which the iPad built-in camera, photo libraries and camera roll may be integrated into an iPad application through the use of the UIImagePickerController class. The tutorial also demonstrated the use of the UIToolbar, UIBarButtonItem and UIPopoverController classes to present a popover view to the application user.


Purchase the fully updated iOS 10 / Swift 3 / Xcode 8 edition of this book in eBook ($19.99) or Print ($45.99) format.
iOS 10 App Development Essentials Print and eBook (ePub/PDF/Kindle) edition contains over 100 chapters. Learn more...

Buy eBook Buy Print Preview Book



PreviousTable of ContentsNext
Accessing the iPad Camera and Photo LibraryVideo Playback from within an iOS 5 iPad Application