Build an iOS slideshow application for the iPad

Use XML, XCode, and the iOS APIs

Learn to build an iOS slideshow application as you walk through the process step-by-step in this article. The example application will communicate with a web server to retrieve an XML slideshow definition and display the images contained in the slideshow.

Share:

Jack D. Herrington, Senior Software Engineer, Leverage Software Inc.

Photo of Jack HerringtonJack Herrington is an engineer, author, and presenter who lives and works in the Bay Area. You can keep up with his work and his writing at http://jackherrington.com.



29 November 2011

Also available in Chinese Russian Japanese Vietnamese Portuguese Spanish

Introduction

Frequently used abbreviations

  • IDE: Integrated Development Environment
  • iOS: Apple's mobile operating system
  • OS X: Apple's operating system for Macintosh computers

It's no mystery why writing applications for an iOS device, such as the iPad or iPhone, is a very popular activity: The devices are gorgeous and easy to use. With millions of users, the devices are very lucrative for application development. People enjoy viewing their photos on the beautiful display on iPads and iPhones.

In this article, learn to build an iOS photo slideshow application from scratch. You'll put some XML code and photos on the server, build the iOS application, add an image view, get the XML, and do the slideshow animation.

Building the back end

The back end of the example slideshow application is really just an XML file that you can drop on your server. Listing 1 shows the example XML, with some sample images.

Listing 1. photos.xml
<photos>
<photo url="http://localhost/photos/CRW_0675.jpg" />
<photo url="http://localhost/photos/CRW_1488.jpg" />
<photo url="http://localhost/photos/CRW_3273.jpg" />
<photo url="http://localhost/photos/CRW_3296.jpg" />
<photo url="http://localhost/photos/CRW_3303.jpg" />
<photo url="http://localhost/photos/CRW_3359.jpg" />
<photo url="http://localhost/photos/CRW_3445.jpg" />
<photo url="http://localhost/photos/CRW_3752.jpg" />
<photo url="http://localhost/photos/CRW_3754.jpg" />
<photo url="http://localhost/photos/CRW_4525.jpg" />
<photo url="http://localhost/photos/CRW_4547.jpg" />
<photo url="http://localhost/photos/CRW_4700.jpg" />
<photo url="http://localhost/photos/CRW_4860.jpg" />
</photos>

The XML is remarkably simple. The <photos> tag contains multiple <photo> tags. Each <photo> tag has the URL of the image you want to display. The URL needs to be fully qualified and absolute; the client application will load the URL directly—not through any type of browser that handles relative URLs.

To complete the back end, modify the XML to include references to your photos and upload that XML to a known location on your server. If everything goes as planned, you should be able to browse to the XML using Safari (or whatever browser you choose) and see something like Figure 1.

Figure 1. XML on the server
Screen capture of XML file (Lisitng 1) in browser

Figure 1 shows the XML from Listing 1 formatted as text. The result will be different from browser to browser, as this is just simple XML (and there is no standard among browsers).

To test that the URLs are correct:

  1. Select one of the URLs.
  2. Copy and paste it into the browser URL area.
  3. Press the Return key.

You should see something similar to Figure 2.

Figure 2. One of the photos on the server
Screen capture of sample photo CRW_1488.jpg, showing face of young girl

A photo, located on the server, is referenced by one of the URLs in the XML. If you don't see the XML, or don't see the photos, then you need to check your web server configuration and your URLs. If you can't see a photo in the browser, then your new iOS application can't see it either.


Building the client slideshow application

After the server is configured and the photos are uploaded, you can start to build the iOS application. The first step is to install the Apple Developer Tools (see Resources for a link). If you are:

  • Pre-Lion, you need to download the developer tools from the Apple Developer Site (see Resources for a link).
  • Running Lion, you can use the Mac App Store to download the tools (see Resources for a link).

After you install the developer tools, run the XCode environment, which is Apple's IDE for both iOS and Mac OS X development. From the XCode environment, select the menu option for a New Project. You should see the first page of the application wizard that you'll use to build iOS or Mac OS X applications, as in Figure 3.

Figure 3. Application wizard
Screen capture of page where you select a template for a new project

You can choose from several different application templates. For this example, select View-based Application and click Next. You should see the final page of the wizard, as in Figure 4.

Figure 4. Project options
Screen capture of page where you select options for a new project

On the second page of the wizard, name your application and select the default device family (iPad or iPhone). The Product Name of the example application is slideshow. The value in the Company Identifier field indicates the application is in the com.jherrington namespace. (Of course, you can choose whatever name and company identifier you like.) Choose iPad for the Device Family and click Next.

The project is created. At this point it's always best to select the big Play button at the upper left of the interface to run your application for the first time. This step compiles everything and brings up the iPad emulator.


Adding the image view

The next step is to add the image view for displaying the images. The iOS framework comes with a rich set of built-in controls that you can use to build your application. For the example, you'll use the UIImageView control. With UIImageView you can display images that are compiled into the application, stored locally on the device, or, as in the example, downloaded from a website.

To add the UIImageView, open the slideshowControllerView.XIB file, which is the user interface definition file for the slideshowControllerView. With the XIB open, go to the object palette and select Image View, as in Figure 5.

Figure 5. Add a UIImageView object to the view controller XIB
Screen capture of the Image View option selected

With the Image View selected, drag and drop it onto the slideshowControllerView. Usually the IDE auto-scales the control to fit the available space. If it doesn't, simply drag the control to adjust its size until it fills the entire display area.

After the control is on the view, set some of the parameters to get the optimal look and feel for the application. Figure 6 shows the settings on the attributes screen for the Image View control.

Figure 6. Configure the UIImageView
Screen capture of the attributes screen for the Image View control

The two modifications you need to make are to the Mode and the Background. Set the Mode to Aspect Fit so the image is scaled but still preserves the aspect ratio of the original. If you don't use Aspect Fit, your images will stretch and scale to match the display area of the image view—and that can end up looking fairly funky.

Because the image might not always fit the available area, you also need to set the Background attribute to Dark Text Color or use the color picker to select a deep black. By default, this value is white. Most photos don't look good when bracketed in a brilliant white.

Save the XIB file and move over to the SlideshowViewController.h file. Make the small modification in Listing 2.

Listing 2. SlideshowViewController.h
#import <UIKit/UIKit.h>

@interface slideshowViewController : UIViewController {
    IBOutlet UIImageView *imgView;
}

@end

You need to add an Outlet to the slideshowViewController that allows the control defined in the XIB to connect to the view controller class.

After the outlet is added, return to the XIB file, select the UIImageView, and use the connections inspector to hook the UIImageView object to the imgView variable in the slideshowViewController class.

After that connection is made, then make the code modifications to the slideshow view controller class itself to load an image. Listing 3 shows the complete first version of the class.

Listing 3. SlideshowViewController.m
#import "slideshowViewController.h"

@implementation slideshowViewController

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

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURL *imageURL = [NSURL URLWithString:@"http://localhost/photos/CRW_0675.jpg"];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];
    [imgView setImage:image];
}

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

- (BOOL)shouldAutorotateToInterfaceOrientation:
   (UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

The serious work in the slideshowViewController class is done in the viewDidLoad method, which now:

  • Loads the data from a URL.
  • Turns that into an image.
  • Uses the setImage method on the image view to display the image.

At this point, you should run the application to test whether an image comes up. You should see something similar to Figure 7, which shows an image displayed in the iPad emulator.

Figure 7. First image from the server
Screen capture of image (face of girl) as displayed in a browser

If you don't see the image, the problem is likely with the setImage method call to imgView. Verify that the UIImageView object is properly connected to the imgView variable. If the application fails before that, you might not have the correct URL, or something isn't correct on the server.


Parsing the XML

Now that you have a way to display the images on an iPad, the next step is to load the XML to get a list of all of the images to display. The iOS framework has a built-in XML parser, so you simply need to create the parser object and listen for the callbacks for the various tags.

Extend the class itself with the NSXMLParserDelegate interface, which tells the iOS framework that this class is capable of receiving callbacks from the XML parser. You also need to add an array called photos that holds the list of URLs that are extracted from the XML. Listing 4 shows the updates.

Listing 4. SlideshowViewController.h with photos
#import <UIKit/UIKit.h>

@interface slideshowViewController : UIViewController<NSXMLParserDelegate> {
    IBOutlet UIImageView *imgView;
    NSMutableArray *photos;
}

@end

As you write more iOS applications, you'll find that you use more and more delegates to connect to various APIs. There are data callbacks for tables, UI elements, GPS callbacks, and more. You can even create your own custom interfaces for your own libraries.

To use the XML parser, extend the view controller class, as in Listing 5.

Listing 5. SlideshowViewController.m with photos
- (void)viewDidLoad
{
    [super viewDidLoad];

    photos = [[NSMutableArray alloc] init];

    NSXMLParser *photoParser = [[[NSXMLParser alloc] 
       initWithContentsOfURL:
       [NSURL URLWithString:@"http://localhost/photos/index.xml"]] autorelease];
    [photoParser setDelegate:self];
    [photoParser parse];

    NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:0]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];
    [imgView setImage:image];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
   namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
   attributes:(NSDictionary *)attributeDict { 
    if ( [elementName isEqualToString:@"photo"]) {
        [photos addObject:[attributeDict objectForKey:@"url"]];
    }
}

The class now creates a parser in the viewDidLoad method and has it request and parse the XML from the server. It also sets the delegate for the parser back to itself so that it gets callbacks.

In the example, you want to listen for the didStartElement callback that is triggered whenever a tag is encountered. The didStartElement function then looks at the tag name to see if it's a photo tag. If it is, didStartElement adds the value of the url attribute to the photos array.

After the array of photos is completed, the viewDidLoad method continues and sets the image to the first image in the array.

Run the application to test your progress. You should see the first image specified in the XML appear in the emulator. If you don't see the first image, you might have an issue with the XML on the server. Set a breakpoint in the didStartElement method to see if it is getting called. If it isn't, then you aren't getting any valid XML back from your sever.


Animating the slideshow

The final step is to use the array of photos to animate a slideshow. You will need two things:

  • A timer
  • A variable to hold your current location in the slideshow

Add both of these items to the class definition, as in Listing 6.

Listing 6. SlideshowViewController.h completed
#import <UIKit/UIKit.h>

@interface slideshowViewController : UIViewController<NSXMLParserDelegate> {
    IBOutlet UIImageView *imgView;
    NSMutableArray *photos;
    NSTimer *timer;
    int currentImage;
}

@end

The timer is an object that will fire off events at an interval that you specify. The currentImage is simply an index into the photos array that you will use to iterate through all of the images.

Listing 7 shows the final version of the slideshow application code.

Listing 7. SlideshowViewController.m completed
#import "slideshowViewController.h"

@implementation slideshowViewController

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

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    photos = [[NSMutableArray alloc] init];

    NSXMLParser *photoParser = [[[NSXMLParser alloc] 
      initWithContentsOfURL:[NSURL URLWithString:
      @"http://localhost/photos/index.xml"]] autorelease];
    [photoParser setDelegate:self];
    [photoParser parse];
    
    currentImage = 0;

    NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:0]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    [imgView setImage:[UIImage imageWithData:imageData]];

    timer = [NSTimer scheduledTimerWithTimeInterval: 5.0
                                             target: self
                                           selector: @selector(handleTimer:)
                                           userInfo: nil
                                            repeats: YES];
}

- (void) handleTimer: (NSTimer *) timer {
    currentImage++;
    if ( currentImage >= photos.count )
        currentImage = 0;

    NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:currentImage]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    [imgView setImage:[UIImage imageWithData:imageData]];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
   namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
   attributes:(NSDictionary *)attributeDict { 
    if ( [elementName isEqualToString:@"photo"]) {
        [photos addObject:[attributeDict objectForKey:@"url"]];
    }
}

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

- (BOOL)shouldAutorotateToInterfaceOrientation:
     (UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

The two new elements in Listing 7 are the creation of the timer in the viewDidLoad method and the addition of the handleTimer method, which is called when the timer fires. The handleTimer method simply increments the currentImage, then rolls the index around if it hits the end of the array. It also uses the standard image fetching logic to get the image at the given index and display it.

Timers have two modes: They can fire once, or they can fire continuously. In the viewDidLoad method, the example specifies YES for repeats so that the handleTimer method is called over and over for the lifetime of the application.


Conclusion

In this article, you created a basic iOS application. You can now take the application in several different directions. The iOS CoreGraphics framework provides a rich set of transitions that you can use to animate the change between the images. You can use PHP on the back end to generate the XML dynamically. Or, you can even use the CoreAudio API to put some music behind the whole slideshow.

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into XML on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Open source, Web development
ArticleID=773607
ArticleTitle=Build an iOS slideshow application for the iPad
publish-date=11292011