iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides) (80 page)

Read iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides) Online

Authors: Aaron Hillegass,Joe Conway

Tags: #COM051370, #Big Nerd Ranch Guides, #iPhone / iPad Programming

BOOK: iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides)
5.14Mb size Format: txt, pdf, ePub
More on Storyboards

In this exercise, you created a storyboard, set up a few view controllers, laid out their interfaces, and created some segues between them. This is the basic idea behind storyboards, and while there are a few more flavors of segues and types of view controllers you can set up, you get the idea. A storyboard replaces lines of code.

 

For example, the push segues in this application replace this code:

 
- (void)tableView:(UITableView *)tableView
    didSelectRowAtIndexPath:(NSIndexPath *)ip
{
    UIViewController *vc = [[UIViewController alloc] init];
    [[self navigationController] pushViewController:vc];
}
 

While this seems nice, storyboarding, in our opinion, is not very useful. Let’s go through the pros and cons. First, the pros:

 
  • Storyboards can be used to easily show off the flow of an application to a client or a colleague.
 
  • Storyboards remove some simple code from your source files.
 
  • Tables with static content are easy to create.
 
  • Storyboards sure do look pretty.
 

The cons, unfortunately, outweigh the pros:

 
  • Storyboards are difficult to work with in a team. Typically, a team of iOS programmers breaks up the work by having each member focus on a particular view controller. With a storyboard, everyone has to do their work in the same storyboard file. This can quickly lead to clutter.
 
  • Storyboards screw up version control. If two people are working on the storyboard at the same time – which happens every day in a team environment – your version control system, like
    Subversion
    , will find conflicts that you must resolve manually.
 
  • Storyboards disrupt the flow of programming. Let’s say you are writing a view controller and adding the code for a button that presents a view controller modally. We can do that pretty easily in code –
    alloc
    and
    init
    the view controller, and send
    presentViewController:animated:completion:
    to
    self
    . With storyboards, you have to load up the storyboard file, drag some stuff onto the canvas, set the
    Class
    in the identity inspector, connect the segue, and then configure the segue.
 
  • Storyboards sacrifice flexibility and control for ease of use. When you need to get your hands dirty, which is often, a storyboard is more of a wall than a trampoline. The work required to add advanced functionality to the basic functionality of a storyboard is often more than the work required to put together the advanced and basic functionality in code.
 
  • Storyboards always create new view controller instances. Each time you perform a segue, a new instance of the destination view controller is created. Sometimes, though, you’d like to keep a view controller around instead of destroying it each time it disappears off the screen. Storyboarding does not allow you to do this.
 

Overall, storyboards make easy code easier and difficult code more difficult. We won’t be using them in this book, and we do not use them when writing our own applications. It is up to you to decide if a particular application would benefit from storyboarding. Of course, your opinion may change as your project gets more complex. Don’t say we didn’t warn you!

 
25
Web Services and UIWebView

In this chapter, you will lay the foundation of an application that reads the RSS feed from the Big Nerd Ranch Forums (
Figure 25.1
). Forum posts will be listed in a table view, and selecting a post from the table will display it from the site.
Figure 25.1
shows the
Nerdfeed
application at the end of this chapter.

 

Figure 25.1  Nerdfeed

 

We will divide the work into two parts. The first is connecting to and collecting data from a web service and using that data to create model objects. The second part is using the
UIWebView
class to display web content.
Figure 25.2
shows an object diagram for
Nerdfeed
.

 

Figure 25.2  Nerdfeed object diagram

 
Web Services

Your handy web browser uses the HTTP protocol to communicate with a web server. In the simplest interaction, the browser sends a request to the server specifying a URL. The server responds by sending back the requested page (typically HTML and images), which the browser formats and displays.

 

In more complex interactions, browser requests include other parameters, like form data. The server processes these parameters and returns a customized, or dynamic, web page.

 

Web browsers are widely used and have been around for a long time. So the technologies surrounding HTTP are stable and well-developed: HTTP traffic passes neatly through most firewalls, web servers are very secure and have great performance, and web application development tools have become easy to use.

 

You can write a client application for iOS that leverages the HTTP infrastructure to talk to a web-enabled server. The server side of this application is a
web service
. Your client application and the web service can exchange requests and responses via HTTP.

 

Because the HTTP protocol doesn’t care what data it transports, these exchanges can contain complex data. This data is typically in XML or JSON (JavaScript Object Notation) format. If you control the web server as well as the client, you can use any format you like; if not, you have to build your application to use whatever the server supports.

 

In this chapter, you will create a client application that will make a request to the
smartfeed
web service hosted at
http://forums.bignerdranch.com
. You will pass a number of arguments to this service that determine the format of the data that is returned. This data will be XML that describes the most recent posts at our developer forums.

 
Starting the Nerdfeed application

Create a new
Empty Application
for the
iPad
Device Family. Name this application
Nerdfeed
, as shown in
Figure 25.3
. (If you don’t have an iPad to deploy to, use the iPad simulator.)

 

Figure 25.3  Creating an iPad Empty Application

 

Let’s knock out the basic UI before focusing on web services. Create a new
NSObject
subclass and name it
ListViewController
. In
ListViewController.h
, change the superclass to
UITableViewController
.

 
@interface ListViewController : NSObject
@interface ListViewController : UITableViewController
 

In
ListViewController.m
, write stubs for the required data source methods so that we can build and run as we go through this exercise.

 
- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
    return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return nil;
}
 

In
NerdfeedAppDelegate.m
, create an instance of
ListViewController
and set it as the root view controller of a navigation controller. Make that navigation controller the root view controller of the window.

 
#import "NerdfeedAppDelegate.h"
#import "ListViewController.h"
@implementation NerdfeedAppDelegate
@synthesize window;
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    ListViewController *lvc =
        [[ListViewController alloc] initWithStyle:UITableViewStylePlain];
    UINavigationController *masterNav =
        [[UINavigationController alloc] initWithRootViewController:lvc];
    [[self window] setRootViewController:masterNav];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

Build and run the application. You should see an empty
UITableView
and a navigation bar.

 
NSURL, NSURLRequest, and NSURLConnection

The
Nerdfeed
application will fetch data from a web server using three handy classes:
NSURL
,
NSURLRequest
, and
NSURLConnection
(
Figure 25.4
).

 

Figure 25.4  Relationship of web service classes

 

Each of these classes has an important role in communicating with a web server:

 
  • An
    NSURL
    instance contains the location of a web application in URL format. For many web services, the URL will be composed of the base address, the web application you are communicating with, and any arguments that are being passed.
 
  • An
    NSURLRequest
    instance holds all the data necessary to communicate with a web server. This includes an
    NSURL
    object, as well as a caching policy, a limit on how long you will give the web server to respond, and additional data passed through the HTTP protocol. (
    NSMutableURLRequest
    is the mutable subclass of
    NSURLRequest
    .)
 
  • An
    NSURLConnection
    instance is responsible for actually making the connection to a web server, sending the information in its
    NSURLRequest
    , and gathering the response from the server.
 
Formatting URLs and requests

The form of a web service request varies depending on who implements the web service; there are no set-in-stone rules when it comes to web services. You will need to find the documentation for the web service to know how to format a request. As long as a client application sends the server what it wants, you have a working exchange.

 

The Big Nerd Ranch Forum’s RSS feed wants a URL that looks like this:

 
http://forums.bignerdranch.com/smartfeed.php?limit=1_DAY&sort_by=standard
&feed_type=RSS2.0&feed_style=COMPACT
 

You can see that the base URL is
forums.bignerdranch.com
, the web application is
smartfeed
, and there are five arguments. These arguments are required by the
smartfeed
web application.

 

This is a pretty common form for a web service request. Generally, a request URL looks like this:

 
http://baseURL.com/serviceName?argumentX=valueX&argumentY=valueY
 

At times, you will need to make a string

URL-safe.

For example, space characters and quotes are not allowed in URLs; They must be replaced with escape-sequences. Here is how that is done.

 
NSString *search = @"Play some \"Abba\"";
NSString *escaped =
      [search stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// escaped is now "Play%20some%20%22Abba%22"
 

When the request to the Big Nerd Ranch forums is processed, the server will return XML data that contains the last 20 posts. The
ListViewController
, who made the request, will populate its table view with the titles of the posts.

 

In
ListViewController.h
, add an instance variable for the connection and one for the data that is returned from that connection. Also add a new method declaration.

 
@interface ListViewController : UITableViewController
{
    NSURLConnection *connection;
    NSMutableData *xmlData;
}
- (void)fetchEntries;
@end
 
Working with NSURLConnection

An
NSURLConnection
instance can communicate with a web server either synchronously or asynchronously. Because passing data to and from a remote server can take some time, synchronous connections are generally frowned upon because they stall your application until the connection completes. This chapter will teach you how to perform an asynchronous connection with
NSURLConnection
.

 

When an instance of
NSURLConnection
is created, it needs to know the location of the web application and the data to pass to that web server. It also needs a delegate. When told to start communicating with the web server,
NSURLConnection
will initiate a connection to the location, begin passing it data, and possibly receive data back. It will update its delegate each step of the way with useful information.

 

In
ListViewController.m
, implement the
fetchEntries
method to create an
NSURLRequest
that connects to
http://forums.bignerdranch.com
and asks for the last 20 posts in RSS 2.0 format. Then, create an
NSURLConnection
that transfers this request to the server.

 
- (void)fetchEntries
{
    // Create a new data container for the stuff that comes back from the service
    xmlData = [[NSMutableData alloc] init];
    // Construct a URL that will ask the service for what you want -
    // note we can concatenate literal strings together on multiple
    // lines in this way - this results in a single NSString instance
    NSURL *url = [NSURL URLWithString:
        @"http://forums.bignerdranch.com/smartfeed.php?"
        @"limit=1_DAY&sort_by=standard&feed_type=RSS2.0&feed_style=COMPACT"];
    // For Apple's Hot News feed, replace the line above with
    // NSURL *url = [NSURL URLWithString:@"http://www.apple.com/pr/feeds/pr.rss"];
    // Put that URL into an NSURLRequest
    NSURLRequest *req = [NSURLRequest requestWithURL:url];
    // Create a connection that will exchange this request for data from the URL
    connection = [[NSURLConnection alloc] initWithRequest:req
                                                 delegate:self
                                         startImmediately:YES];
}
 

Kick off the exchange whenever the
ListViewController
is created. In
ListViewController.m
, override
initWithStyle:
.

 
- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        [self fetchEntries];
    }
    return self;
}
 

Build the application to make sure there are no syntax errors.

 

Other books

A Second Chance by Shayne Parkinson
Gladiator by Kate Lynd
House of Silence by Gillard, Linda
The Missing Person by Alix Ohlin
The Railway Station Man by Jennifer Johnston
Eat Him If You Like by Jean Teulé
Rock of Ages by Walter Jon Williams
Moonlight by Felicity Heaton