iOS App Development For Dummies (2014)
Part II. Building RoadTrip
Visit www.dummies.com/extras/iosappdevelopment for more tips on building a great iOS app interface.
In this part …
· Getting to know storyboards
· Developing a user interface
· Managing memory and using properties
· Working with the source editor
Chapter 4. Storyboards and the User Experience
In This Chapter
Introducing the storyboard
Exploring the RoadTrip app
Understanding the Model-View-Controller design pattern
Knowing what’s available in UIKit and the other frameworks
Examining how the Model-View-Controller design pattern is implemented in your app
As I mention in the Introduction, my goal for this book is for you to understand the right way to develop apps for the iPhone and iPad. Because you’ll be using the knowledge I impart to you to develop my RoadTrip app, now is probably a good time to explain the app — what it actually does, how it is organized, and what the program architecture looks like.
One thing that makes iOS software development so appealing is the richness of the tools and frameworks provided in the iOS Software Development Kit (SDK). In this regard, the frameworks are especially important. Each one is a distinct body of code that actually implements your app’s generic functionality — in other words, frameworks give the app its basic way of working. This is especially true of one framework in particular: the UIKit framework, which is the heart of the user interface.
In this chapter, you get an overview of the iOS user interface architecture, meaning you’ll find out what the various pieces are, what each does, and how they interact with each other. The idea here is for this chapter to lay the groundwork for developing the RoadTrip app’s user interface, while succeeding chapters take you to the next level(s).
I also go through what classes and frameworks are available in the SDK — well, at least the main ones you’ll need to know about in order to build the RoadTrip app, as well as a number of other classes and frameworks any self-respecting app developer would need to know in order for her to build her own apps. For added measure, I also talk about something Apple calls design patterns, or programming paradigms that the frameworks are based on.
But the place I want to start is a feature that is typical of Apple in its development process: a way to visually lay out your app’s interface and the sequencing of screens. The technology is called storyboarding or storyboards, depending on whether you want to focus on the process or the tool.
Apple didn’t invent storyboards. According to Wikipedia, storyboards were used by Constantin Stanislavski in preparing his production of Anton Chekhov’s The Seagull in 1898 and were popularized by Walt Disney in the 1930s. Storyboards moved from live theater to animated films and on to Gone with the Wind in 1939. The engineers and designers at Apple recognize an efficient tool when they find it. True to form, they adopted storyboards and improved on the basic concept.
Introducing the Storyboard
I really like Xcode’s Storyboard feature. When I saw a storyboard for the first time, it was like a dream come true. (Well, okay, not quite.) To me, the Storyboard feature represented exactly what I needed — not only for building my own apps, but also for teaching other people how to build their own apps.
Using a storyboard is analogous to sketching the user interface and app flow on a white board, and then having that sketch turn into something your app can use. This last part is what’s really important to you. Your sketch is not a free-form drawing. Rather, you assemble graphical elements such as buttons and views using the library of such objects in the Utility area. At build time, these graphical elements turn into their corresponding functional elements on the screen. As you proceed through this chapter, you’ll see how you make the connection between the graphical element and the code-based element. That’s where the magic of storyboards happens.
Working with a storyboard can save you lots of time and effort by reducing the code you have to write. Moreover, it can really help when it comes to fully understanding the app flow. If you haven't developed before, you'll find that using a storyboard makes it easier to get a more complex app up and running.
The idea behind a storyboard is that you’d use it to lay out the entire flow of your app. Figure 4-1 shows you what the iPad storyboard for a finished app would look like. You’ll find that when you lay out an app in a storyboard, you can actually run your program before you even add any content, so you can get a sense of how the user experience will unfold.
Figure 4-1: The completed RoadTrip storyboard.
To get to the storyboard so you can actually edit it, you use the Project navigator and select the storyboard file you're interested in. Doing so brings up the Interface Builder editor. You’ll use the Utility area as well to add user interface elements, use the inspectors to set attributes, and so on.
Telling your story
As you develop your app, you use Interface Builder to graphically add user interface elements to each one of your views in the storyboard. (I tell you more about views in the “Working with Windows and Views” section, later in this chapter; for now just think of views as containers for displaying what you see on the device screen.) In this context, user interface elements include things like controls, images, and placeholders for content you’ll display. After you’ve added the elements you need, all you have to do is fill in code where it’s needed. If you've used Xcode to program in the past, you’ll find that you have to write a lot less plumbing code — code that is specifically designed to do things like launch view controllers — and, in some cases, no plumbing code at all.
Typically, I try to lay out the entire flow of my app early on in the development process, but for the example app developed for this book, I decided not to do that because I wanted to first show you all the basics of developing an app with Xcode. That means you’ll see some of the storyboard stuff now, but will have to wait until Chapter 14 to storyboard the rest of the RoadTrip app. This actually is not far from the way most apps are developed. If you have an experienced team and a large budget, you can work out everything in advance and then code from beginning to end. In many cases, though, the app evolves as you work on it. Xcode and particularly storyboards make it easy to handle these evolutions as you change the sequence of screens and the ways in which the transitions occur.
Ready for a storyboard tour? To follow along with me, go back to Xcode and select the Main_iPad.storyboard file for your sample project in the Project navigator. This is the iPad storyboard, one of the storyboards that Xcode created for you when you used the Master-Detail Application template and selected the Universal Device Family. (See Chapter 3 for more on the specifics of the Master-Detail Application template.) The name Main in the Main_iPad.storyboard file implies that, of course, there can be other storyboards. (In this case, you’ll notice there are twoMainStoryboards — one for iPad and one for iPhone.)
Selecting the Main_iPad.storyboard file in the Project navigator opens that file in the Interface Builder editor, as shown in Figure 4-2. Although all this may look a bit daunting at first, I promise you that by the time you’re finished with this book, it will seem like old hat. (For a detailed explanation of what’s going on in Figure 4-2, see Chapter 13.)
Figure 4-2: RoadTrip Main_iPad.story board.
In the olden days (pre-storyboards), you used nib files to define your user interface one view controller at a time. The term nib (with its corresponding file extension .xib) is an acronym for NeXT Interface Builder, a bit of software originally developed at NeXT Computer, whose OPENSTEP operating system was used as the basis for creating OS X and iOS. A nib file is a special type of resource file that you use to store the user interface you create with the Interface Builder editor. Storyboards are actually just a series of connected nib files.
View controllers manage what you see on the iPad or iPhone screen — the views themselves. Views are visible objects (images, buttons, and the like), while view controllers are just what the name suggests: controllers of the visible objects. If this terminology reminds you of the Model-View-Controller design pattern previously mentioned, you’re right. The model is the data, and we’ll get to that in Part IV. For more specifically on view controllers, check out the section “View Controllers — the Main Storyboard Players,” later in this chapter.
Working with object graphs
Continuing with the storyboard tour, note that as you create your storyboard, you create an object graph that is then archived when you save the file. When you load the file, the object graph is unarchived.
So, what’s an object graph? Here’s the short answer: Object-oriented programs are made up of complex webs of interrelated objects. They are linked to one another in a variety of ways. One object can contain another object, for example, or it can own it, or it can reference it. All the items that you see in your storyboard (and some items that you don’t see) are all objects and are part of that web of objects. The Interface Builder editor allows you to create this network graphically and then, at runtime, it makes the connections for you.
A storyboard file can capture your entire user interface in one place and lets you define both the individual view controllers and the transitions between those view controllers. As a result, storyboards capture the flow of your overall user interface in addition to the content you present.
In the app you build in this book, you use just one storyboard file to store all the view controllers and views for each device. Behind the curtain, however, Interface Builder takes the contents of this one storyboard file and divides it into discrete pieces that can be loaded individually for better performance.
That’s the 100-yard-dash tour of the storyboard and its purpose. For you to truly get a feel for the essence of the storyboard, however, you need to see how the storyboard replicates the way an iOS app is structured — in other words, you need an in-depth look at the iOS app architecture. The best way to do that is within the context of a real app. So, before I get into even more detail about working in the storyboard, I want to give you a sense of the basic functions and purpose of the app developed throughout this book — the app I’ve affectionately named RoadTrip.
Defining What You Want an App to Do: The RoadTrip App
A year ago, my friend Skippy got a new job which necessitated him moving from California to New York. He decided to drive his car across the country and see what some people refer to as “flyover country”— the land between the two coasts. He started surfing the web and soon had a whole collection of web pages bookmarked on his iPad. Sorting through them was starting to take more time than the trip was going to take. He asked me if I couldn’t do something on the iPad that would organize the information and even collect it for him so that he didn’t have to spend time using a search engine over and over. That’s how RoadTrip started.
To make RoadTrip a useful app, I had to move from Skippy’s problem — all those searches and web bookmarks — to the app’s solution, which is to present information that’s relevant to the following questions:
· Where are you?
· Where do you plan to be?
· What do want to do, or where do you want to go when you get there?
By concentrating on what is truly relevant, you reduce the app to the amount of information you need to deal with at any one time.
Guided by the app's purpose — as well as by what the iPad or iPhone does best — I developed a clearer picture of what Skippy would want the app to do. That clearer picture comes into focus in Figure 4-3, where — there on the left side — you can see the app functionality in what Xcode calls the Master view. The pane on the right — displaying the appropriately named Detail view — gives Skippy the chance to watch his car go back and forth onscreen (with sound effects, no less). That animation is included in the app and this book as a demonstration of what’s possible to do on the iOS devices. It’s also there to get you started with animation techniques that are frequently used in games. (For more on Master and Detail views, check out Chapter 13.)
Figure 4-3: A real-live example of the Master view/Detail view combination.
The iPad’s split-view interface allows the user to sometimes see a Master view and a Detail view at the same time. The iPhone’s smaller screen requires that you design your user interface to only show one or the other at a given time. I use the iPad storyboard file as the example in this chapter, but the storyboard for the iPhone is basically similar — it just differs in some of the details. You’ll see how to manage both iPad and iPhone user interfaces in later chapters.
This division into Master view and Detail view is an elegant way of allowing the user to pick a task from the navigation list on the left and see the content associated with that task on the right. The tasks I came up with for my RoadTrip app are as follows:
· Get real-time weather access. Snow in New York in August? Not likely, but these days you never can tell. You can see real-time weather access at work in Figure 4-4.
· Find out what’s going on wherever you are. Figure 4-5 shows an event that Skippy might be interested in.
Figure 4-4: The weather in New York on the iPad screen.
Figure 4-5: RoadTrip describes some things for you to do while in a city.
· Bring up a map based on the destination. The map shows Skippy’s destination and points of interest, and even allows him to zero in on his current location. (See Figure 4-6.)
· Find some place on a map. If Skippy has an address that he wants to find on the map, he should be able to do that and get its GPS coordinates as well. Figure 4-7 gives an example of finding a point of interest on a map.
There are of course a lot of other features you’d want to add to this app to make it worth the $.99 you’ll be charging, and I talk about some of those in Chapter 21. When you start thinking of pricing and features, browse the App Store to see what other apps are doing. You may wind up creating several versions of your app such as a low-priced (or free) “Lite” version along with the full-featured version. In addition, the freemium model has become popular in certain categories of apps (most particularly games). The app itself is typically free in these cases. It may generate a revenue stream from ads inside the app, but it also generates revenue from in-app purchases of advanced game levels, new content, and the like. In the case of RoadTrip, new destinations might be in-app purchases, but the overall structure of the app should be independent of which destinations are included, and that is how it is built in this book.
Given the user interface described in this section, the big questions are a) how do you create an app from your knowledge of the problem, and b) how do you want the app to help solve it?
Figure 4-6: Finding your way with pinpoint accuracy.
Figure 4-7: Where is Radio City Music Hall, anyway?
The answers to those questions can be found in the application architecture.
In the Apple Human Interface Guidelines, Apple suggests the current selection in the Master view (left pane) should be indicated. In Chapter 13, I give you the option of having the current Master View selection remain highlighted, but until then, I won’t bother with that.
Creating the Application Architecture
At a basic level, the RoadTrip app is made up of the following:
· Models: Model objects encapsulate the logic and content (data) of the app.
· Views: Data content is useless if your user never sees it. Views are the windows to your content — the pathway to the user experience — and it's up to you to decide what information to display and how to display it. Part of the decision will involve what kind of view best serves your content. (Xcode offers you a number of different ways to display both information and navigation choices.)
· View controllers: View controllers manage the user experience. They connect the views that present the user experience with the models that provide the necessary content. View controllers also manage the way the user navigates the app.
The MVC (Model-View-Controller) model is pretty much the basis for all iOS app development projects. I explain MVC in more detail in the “The Model-View-Controller (MVC) design pattern” section, later in this chapter. The trick here is to come up with just the right views, view controllers, and model objects to get your project off the ground.
What You Add Where
Table 4-1 summarizes the chapters in which you will add new Objective-C classes and new view controller scenes to your project. The Chapter 3 classes and storyboard scenes are built with Apple’s Master-Detail template, but the rest are up to you as you work through this book.
Table 4-1 Classes and Scenes by Chapter
Create Objective-C Class
Add Storyboard Scene
Master View controller
Detail View controller
Test Drive controller
But before you decide what you need to build your app, you’ll need to understand what’s available. Frameworks supply the classes you have to work with in your app — classes like UIView, UIViewController, UIControl, and a whole lot more.
A framework offers common code that provides generic functionality. The iOS SDK provides a set of frameworks for incorporating technologies, services, and features into your apps. For example, the UIKit framework gives you event-handling support, drawing support, windows, views, and controls that you can use in your app.
A framework is designed to easily integrate the code that runs, say, an app or game or that delivers the information your user wants. A framework is similar to a software library, but with an added twist: It can also implement a program’s flow of control (in contrast to a software library, whose components are arranged by the programmer into a flow of control). So, when working within a framework, the programmer may not have to decide the order in which things should happen — such as which messages are sent to which objects and in what order when an app launches, or when a user touches a button on the screen. Instead, the order of those events, or flow of control, may be a part of the framework.
When you use a framework, it provides your app with a ready-made set of basic functions; essentially you’ve told it “Here’s how to act,” and it’s in a position to take the ball and run with it. With the framework in place, all you need to do is add the specific functionality that you want in the app — the content as well as the controls and views that enable the user to access and use that content.
The frameworks and iOS provide pretty complex functionality, such as
· Launching the app and displaying a window on the screen
· Displaying controls on the screen and responding to a user action — changing a toggle switch, for example, or scrolling a view, such as the list of your contacts
· Accessing sites on the Internet, not just through a browser but also from within your own program
· Managing user preferences
· Playing sounds and movies
Some developers talk in terms of “using a framework” — but in reality, your code doesn’t use the framework so much as the framework uses your code. Your code provides the functions that the framework accesses; the framework needs your code to become an app that does something other than start up, display a blank window, and then end. This perspective makes figuring out how to work with a framework much easier.
If this seems too good to be true, well, okay, it is — all that complexity (and convenience) comes at a cost. It can be really difficult to get your head around the whole thing and know exactly where (and how) to add your app’s functionality to the functionality that the framework supplies. That’s where design patterns, which I discuss next, come in. Understanding the design patterns behind the frameworks gives you a way of thinking about a framework — especially UIKit because it's based on the MVC design pattern — that doesn’t make your head explode.
Using Design Patterns
When it comes to iOS app development, the UIKit framework does a lot of the heavy lifting for you. That’s all well and good, but working with that framework is a little more complicated than just letting it do its work on its own. The framework is designed around certain programming paradigms, also known as design patterns. The design pattern is a model that your own code must be consistent with.
To understand how to take best advantage of the power of frameworks — or (better put), figuring out how the framework objects want to best use your code — you need to understand design patterns. If you don’t understand them or if you try to work around them because you’re sure that you have a “better” way of doing things, your job will actually end up being much more difficult. (Developing apps can be hard enough, so making your job more difficult is definitely something you want to avoid.) Getting a handle on the basic design patterns that the framework uses (and expects) will help you develop an app that makes the best use of the framework. This means doing the least amount of work in the shortest amount of time.
The design patterns can help you to understand not only how to structure your code but also how the framework itself is structured. They describe relationships and interactions between classes or objects, as well as how responsibilities should be distributed among classes, so that the iOS device does what you want it to do. In programming terms, a design pattern is a commonly used template that gives you a consistent way to get a particular task done.
The iOS design patterns
To develop an iOS app, you need to be comfortable with the following basic design patterns:
· Model-View-Controller (MVC)
· Block Objects
· Managed Memory Model
Of these, the Model-View-Controller design pattern is the key to understanding how an iPad or iPhone app works and is the focus of the following section. I explain the remainder of the patterns as they’re put to use in this book.
Another basic design pattern exists as well: Threads and Concurrency. This pattern enables you to execute tasks concurrently (including the use of Grand Central Dispatch, that aiding-and-abetting feature introduced in OS X Snow Leopard for taking full advantage of all that processing power available, even on the smaller iPad and much smaller iPhone). Particularly with the advent of 64-bit multi-core processors in some of the iOS devices, the ability to use that power with tools such as Grand Central Dispatch is increasingly important. Unfortunately, the Threads and Concurrency design pattern — as well as Grand Central Dispatch — is beyond the scope of this book.
The Model-View-Controller (MVC) design pattern
The iOS frameworks are object oriented. An easy way to understand what that really means is to think about a team working in an office. The work that needs to get done is divided up and assigned to individual team members (in this case, objects). Each team member has a job and works with other team members to get things done. What’s more, a good team member doesn’t care how other members do their work, just that they do it according to the agreed upon division of labor. Likewise, an object in object-oriented programming takes care of its own business and doesn’t care what the object in the virtual cubicle next door is doing, as long as it will do what it's supposed to do when asked to do it.
Object-oriented programming was originally developed to make code more maintainable, reusable, extensible, and understandable by encapsulating all the functionality behind well-defined interfaces. The actual details of how something works (as well as its data it uses to do that work) are hidden, which makes modifying and extending an app much easier.
Great — so far — but a pesky question still plagues programmers:
Exactly how do you decide on the objects and what each one does?
Sometimes the answer to that question is pretty easy — just use the real world as a model. (Eureka!) In the RoadTrip app, for example, some of the classes of model objects are Trip, Events, Destination, and so on. But when it comes to a generic program structure, how do you decide what the objects should be? That may not be so obvious.
The MVC pattern is a well-established way to group app functions into objects. Variations of it have been around at least since the early days of Smalltalk, one of the very first object-oriented languages. MVC is a high-level pattern — it addresses the architecture of an app and classifies objects according to the general roles they play in an app, rather than drilling down into specifics.
The MVC pattern creates, in effect, a miniature universe for the app, populated with three distinct kinds of objects. It also specifies roles and responsibilities for all three types of objects and specifies the way they’re supposed to interact with each other. To make things more concrete (that is, to keep your head from exploding), imagine a big, beautiful, 60-inch, flat-screen TV. Here’s the gist:
· Model objects: These objects together comprise the content “engine” of your app. They contain the app’s data and logic — making your app more than just a pretty face. In the RoadTrip app, for example, the model maintains a list of events and sights, as well as the name and location of the destination and a background image to use.
You can think of the model (which may be one object or several that interact) as a particular television program, one that, quite frankly, doesn't give a hoot about what TV set it's shown on.
In fact, the model shouldn’t give a hoot. Even though it owns its data, it should have no connection to the user interface and should be blissfully ignorant about what's done with its data.
· View objects: These objects display things on the screen and respond to user actions. Pretty much anything you can see is a kind of view object — the window and all the controls, for example. Your views know how to display information they receive from the model object and how to get any input from the user the model may need. But the view itself should know nothing about the model. It may handle a request to display some events, but it doesn’t bother itself with what that request means.
You can think of the view as a television screen that doesn’t care about what program it's showing or what channel you just selected.
The UIKit framework provides many different kinds of views, as you find out in the next section.
If the view knows nothing about the model, and the model knows nothing about the view, how do you get data and other notifications to pass from one to the other? To get that conversation started (Model: “I’ve just updated my data.” View: “Hey, give me something to display,” for example), you need the third element in the MVC triumvirate, the controller.
· Controller objects: These objects connect the app’s view objects to its model objects. They supply the view objects with what they need to display (getting it from the model) and also provide the model with user input from the view.
You can think of the controller as the circuitry that pulls the show off of the cable and then sends it to the screen or requests a particular pay-per-view show.
With Xcode, both the model and view objects are often built with graphical user interfaces such as Interface Builder for views and view controllers and the Data Model Editor for Core Data objects. Controllers are almost always built with code. Building a controller object is the part of MVC that, for many developers, “feels” like traditional coding.
The basic application architecture looks like Figure 4-8.
Figure 4-8: The Model-View-Controller.
When you think about your app in terms of model, view, and controller objects, the UIKit framework starts to make sense. Understanding the framework this way also begins to lift the fog hanging over where to make at least part of your app-specific behavior go. Before you delve into that topic, however, you need to know a little more about the classes that the UIKit provides, because these are the guys you will task with implementing the MVC design pattern — window classes, view classes, and view controller classes.
Throughout this book, I’ll be talking about both classes and objects, and now is as good a time as any to remind you of the difference between the two.
In Objective-C, classes include instance variables, properties, and methods (that can access the instance variables of a class). Classes are about files in your project that contain code. Classes are types in your program.
Objects, on the other hand, exist at runtime and are instances of a class. You can think of a class as a blueprint to build an object of that type.
Working with Windows and Views
iOS apps have a single window, so you won’t find additional document windows for displaying content as you do an a Mac. When your app is running — even though other apps may be hibernating or running in the background — your app’s interface takes over the entire screen.
Looking out the window
The single window that you see displayed on an iPad or iPhone is an instance of the UIWindow class. This window is created at launch time, either programmatically by you or automatically by UIKit when you use a storyboard. In general, after you create the Window object (that is, if you create it instead of having it done for you by the framework, which is the most common case), you never really have to think about it again.
A user can’t directly close or manipulate an iOS window. It's your app that programmatically manages the window.
Although your app never creates more than one window at a time, iOS can support additional windows on top of your window. The system status bar is one example. You can also display alerts on top of your window by using the supplied Alert views.
Admiring the view
In an iOS app world, view objects are responsible for the view functionality in the Model-View-Controller architecture. A view is a rectangular area on the screen (it appears to be on top or within a window).
In the UIKit framework, windows are really a special kind of view, but for the purpose of this discussion, I’m referring to views that sit on top of the window.
What views do
Views are the main way for your app to interact with a user. This interaction happens in two ways:
· Views display content. This happens, for example, by making drawing and animation happen onscreen. The view object displays the data from the model object.
· Views handle touch events. Views respond when the user touches a button, for example. Handling touch events is part of a responder chain (which I explain in Chapter 6).
The view hierarchy
Views and subviews create a view hierarchy. You have two ways of looking at it (no pun intended this time): visually (how the user perceives it) and programmatically (how you create it). You must be clear about the differences or you’ll find yourself in a state of confusion that resembles the subway at rush hour.
Looking at it visually, the window is at the base of this hierarchy with a Content view on top of it (a transparent view that fills the window’s Content rectangle). The Content view displays information as well as allowing the user to interact with the app, using (preferably standard) user interface items such as text fields, buttons, toolbars, and tables.
In your program, that relationship is different. The Content view is added to the window view as a subview. But the Content view can also have its own subviews, and so on. Possible relationships include
· Views added to the Content view become subviews of it.
· Views added to the Content view become the superviews of any views added to them.
· A view can have one (and only one) superview and zero or more subviews.
It seems counterintuitive, but a subview is displayed on top of its parent view (that is, on top of its superview). Think about this relationship as containment: A superview contains its subviews. Figure 4-9 shows an example of a view hierarchy.
Figure 4-9: The view hierarchy is both visual and structural.
Controls — such as buttons, text fields, and so on — are actually view subclasses that become subviews. So are any other display areas that you may specify. The view must manage its subviews, as well as resize itself with respect to its superviews. Fortunately, much of what the view must do is already coded for you. The UIKit framework supplies the code that defines view behavior.
The view hierarchy also plays a key role in both drawing and event handling. I explain event handling in Chapter 6.
You create or modify a view hierarchy whenever you add a view to another view, either programmatically or with the help of the Interface Builder. The UIKit framework automatically handles the relationships associated with the view hierarchy.
Developers typically gloss over this visual-versus-programmatic-view-hierarchy stuff when starting out — and without understanding these concepts, it's really difficult to get a handle on what’s going on.
The kinds of views you use
The UIView class defines the basic properties of a view, and you may be able to use it “as is” — as you’ll do in the Test Drive screen of the RoadTrip app — by simply adding an image view and some controls.
In the Detail view shown back in Figure 4-3, the user can take a test drive by tapping the Test Drive button. (Later in the book, in Chapter 10, I show you how to animate the car so that it leisurely drives to the other side of the screen, turns around, drives back, and then turns around one more time so that it’s back to where it started on the screen.)
The UIKit framework also provides you with a number of other views that are subclassed from UIView. These views implement the kinds of things that you as a developer need to do in the user interface.
It’s important to think about the view objects that are part of the UIKit framework. When you use an object such as a UISlider or UIButton, your slider or button behaves just like a slider or button in any other iOS app. This enables the consistency in appearance and behavior across apps that users expect.
Container views are a technical (Apple) term for content views that do more than just lie there on the screen and display your controls and other content. The UIScrollView class, for example, adds scrolling without you having to do any work. Most of the time, Container views just do their thing in the background (as part of other views you use — Table views, for example), and I don’t explain any more about them in this book because you won’t need to use or manage them explicitly.
UITableView inherits this scrolling capability from UIScrollView and adds the ability to display lists and respond to the selections of an item in that list. Think of the Contacts app on your iPad (and a host of others, come to think of it). UITableView is one of the primary navigation views on the iPad.
Table views are used a lot in iOS apps to do these two things:
· Display hierarchal data: For an example, think of the Music app, which gives you a list of albums and, if you select one, a list of its songs.
· Act as a table of contents: Now, think of the Settings app, which gives you a list of apps that you can set preferences for. When you select one of those apps from the list, it takes you to a view that lists what preferences you’re able to set as well as a way to set them.
In the RoadTrip app, the List views — such as the ones in the Master view shown earlier in Figure 4-3 — are Table views. The List view shown in the figure acts as an introduction to the app; it provides the user with a way to decide where he wants to go, for example, by selecting Destination in the Table view.
Another Container view, the UIToolbar class, contains button-like controls, which you find everywhere on an iOS device. In the Mail app, for example, you tap an icon on the bottom toolbar to respond to an e-mail. In RoadTrip, you find such controls at the top of the Map view (refer to Figure 4-6) to allow you to decide on how you want the map to be displayed.
Controls are the fingertip-friendly graphics that are used extensively in a typical app’s user interface. Controls are actually subclasses of the UIControl superclass, a subclass of the UIView class. They include touchable items such as buttons, sliders, and switches, as well as text fields in which you enter data. You use them in your views, including, as you just saw, in a toolbar.
Controls make heavy use of the Target-Action design pattern, which is used when you touch the Test Drive button, as shown in Figure 4-10.
I explain the Target-Action pattern in detail in Chapter 9.
Think of Display views as controls that look good but don’t really do anything except, well, look good. These include the following: UIImageView (check out the background to the Master view shown earlier in Figure 4-3 for an example); UILabel (for adding labels to buttons and other controls); UIProgressView; and UIActivityIndicatorView. I like to add an activity indicator to those views where I download data so folks have something to watch while waiting.
Figure 4-10: A button is the tip of the Target-Action design pattern.
Text and Web views
Text and Web views provide a way to display formatted text in your app. The UITextView class supports the display and editing of multiple lines of text in a scrollable area. The UIWebView class provides a way to display HTML content. These views can be used as the Main view, or as a subview of a another view. (You encounter UIWebView in the RoadTrip app as Weather views.) UIWebView is also the primary way to include graphics and formatted text in Text Display views.
The views that display content — such as the Detail views shown previously in Figures 4-4 and 4-5 — are Web views, for some very good, practical reasons:
· Some views must be updated regularly. Web views, in that context, are the perfect solution; they make it easy to access data from a central repository on the Internet. (Client/server is alive and well!)
· Web views can easily display formatted data that’s locally stored. Real-time access isn’t always necessary — sometimes it’s perfectly fine to store some data on the iPad or iPhone. Web views have no problem with locally stored data, which is very handy.
· Web views can access websites! Don’t overlook the obvious: Web views open the door to websites, which means you have the whole Internet at your beck and call. If users want more detailed weather information, for example, they can get to the ten-day forecast by simply touching a link.
Alert views and Action sheets
Alert views and Action sheets present a message to the user, along with buttons that allow the user to respond to the message. In the case of an alert, the response may be yes or no or a simple OK to indicate that the user has read the alert. An action sheet can present multiple buttons. I have you add an Alert view to the RoadTrip app in Chapter 8 to inform the user when the Internet isn't available. Figure 4-11 shows what the user would see if no Internet connection is available.
Tab bars and Navigation bars work in conjunction with view controllers to provide tools for navigating in your app. (For more on navigation bars, see Chapter 5.) Normally, you don’t need to create a UITabBar or UINavigationBar directly — it’s easier to let Interface Builder do the job for you or configure these views through a Tab bar or Navigation controller, respectively.
You’ll remember this one: The window provides the surface for drawing content and is the root container for all other views.
Figure 4-11: Users need the Internet alert, so be sure to include it.
View Controllers — the Main Storyboard Players
Early in this chapter, I provide an overview of the storyboard — the whiteboard, so to speak, on which you lay out the flow of the elements, or design pattern, of your app. In this book, the example app developed throughout — RoadTrip — uses the Model-View-Controller (MVC) design pattern, and in this particular design pattern, it's the view controllers that implement the pattern’s controller component. These controller objects contain the code that connects the app’s view objects to its model objects. Whenever the view needs to display something, the view controller goes out and gets what the view needs from the model. Similarly, view controllers respond to controls in your Content view and may do things like tell the model to update its data (when the user adds or changes text in a text field, for example), compute something (the current value of, say, your U.S. dollars in British pounds), or change the view being displayed (like when the user presses the Detail Disclosure button on the Music app to find out more about a song).
View controllers, as you can see in Figure 4-12, are the objects that control what is displayed and that respond to user actions. They are the heart and soul of the storyboard.
Figure 4-12: It’s all about the view controller.
As I explain in more detail in Chapter 9, a view controller is often the (target) object that responds to the onscreen controls. The Target-Action mechanism is what enables the view controller to be aware of any changes in the view, which can then be transmitted to the model.
Imagine that an iPad user launches the RoadTrip app. On the left side (or in a popover), she sees a Table view and on the right side a Detail view (the Weather, for example). (Refer to Figure 4-4.) The user may tap an entry (cell) in the Table view to display events. The Events controller is then launched and sends a message to the appropriate method in the model to get the events. The model object returns a list of URLs, and so on. The controller then delivers that information to the view, which promptly displays the information to the user.
If your imaginary user now launches the RoadTrip app on the iPhone (or iPod touch), the user will see a full-screen table view. The screen will shift to a detail view when the user taps a cell in the table. The same information is available in the iPhone version as in the iPad version, but the user interface has to be slightly different.
You will be pleased to know that you can build one set of Objective-C classes that works with both the iPhone and iPad storyboard files, so you only need one set of code to build your Universal app.
The sequence of events is as follows:
1. A message is sent to that view’s view controller to handle the request.
2. The view controller’s method interacts with the Trip model object.
3. The model object processes the request from the user for the current events.
4. The model object sends the data back to the view controller.
5. The view controller sends the data to the view to display the information.
View controllers have other vital iOS responsibilities as well, such as the following:
· Managing a set of views: This includes creating the views as well as flushing them from memory during low-memory situations.
· Responding to a change in the device’s orientation: If, say, the user causes the iPad to switch from landscape to portrait orientation, the view controller responds by adjusting its views to match the new orientation.
· Creating a Modal (not model) view: A Modal view is a child window that displays a dialog that requires the user to do something (tap the Yes or Cancel button, for example) before returning to the app.
You use a Modal view to ensure that the user has paid attention to the implications of an action (for example, “Are you sure you want to delete all your contacts?”).
· Display a popover: A popover is a transient view that is shown when people tap a control or an onscreen area. Popovers are used in a variety of ways, including displaying the Master view when a Split View app (like RoadTrip) is in Portrait orientation, or displaying additional information about a selection. They are only available on the iPad.
· Respond to user input and navigation: While the view processes a touch using the Target-Action pattern, it is almost always the view that is the target of the action — responding to the touch appropriately (like having the image of a ’59 Cadillac Eldorado Biarritz convertible drive right up the center of the screen — sound effects included).
View controllers are also typically the objects that serve as delegates and data sources for Table views (more about those in Chapter 19) as well as for other kinds of framework views.
In addition to the base UIViewController class, UIKit includes the following:
· Subclasses such as UITabBarController (to manage the Tab bar)
· UITableViewController (which you use to manage Table views)
· UINavigationController (which implements navigation back and forth between view controllers)
· UIPageViewController (to allow users to navigate between view controllers using the specified transition)
· UIImagePickerController (to access the camera and Photo library on the iPad)
· UISplitViewController (which you’ll be using on the iPad only to display the side-by-side views you see in Figure 4-3, for example)
What About the Model?
As this chapter shows (and as you'll continue to discover), much of the functionality you need in an app is already in the frameworks.
But when it comes to the model objects — the things you build to actually hold the data and carry out the logic for your app — you’re on your own, for the most part. In the RoadTrip app, for example, you’re going to need to create a Trip object that owns the data and logic and uses other objects to perform some of the actions it needs.
I talk about the model and model classes in more detail in Chapter 11. That’s where you’ll also find much more on implementing model objects.
You may find classes in the framework that help you get the nuts and bolts of the model working. But the actual content and specific functionality are up to you.
To implement the structure that enables me to include several destinations in the RoadTrip app, I need to have the data. I use property lists (XML files, in other words) to take care of that because they’re well suited for the job, and (more importantly) support for them is built into the iOS frameworks. (For more on property lists, see Chapter 11.) Property lists are great for relatively small amounts of data. For larger amounts, the Core Data persistent objects framework is a great choice, but it’s not part of this book. You can start with property lists to get a feel for data management on iOS and then move on to Core Data for your next app.
iOS includes a UIDocument class for managing the data associated with a user’s documents. If you're implementing a document-based app, you can use this class to reduce the amount of work you must do to manage your document data. If you're implementing an app that supports iCloud storage, the use of document objects makes the job of storing files in iCloud much easier. I don’t cover the UIDocument class in this book.
Using naming conventions
When creating your own classes, methods, and variables, it’s a good idea to follow a couple of standard naming conventions:
· Class names (such as View) should start with a capital letter.
· The names of methods (such as viewDidLoad) should start with a lowercase letter, and additional words within the name should start with an uppercase letter (viewDidLoad).
· The names of instance variables and properties (such as frame) should start with a lowercase letter.
When you follow these conventions, you can tell from the name what something actually is. A few more such conventions are good to know, and I explain them as they arise in the course of the book.
It’s Not That Neat
It would be nice (not to mention amazing) if everything fit neatly into model, view, or controller, but it doesn’t work that way.
You really need to know about one other kind of class. The UIApplication class handles routing of incoming user events, dispatches action messages from controls, and deals with numerous other basic plumbing functions that aren't the responsibilities of a model, view, or controller. It typically works with an application delegate, a set of methods that allows you to customize how your app responds to events such as app launch, low-memory warnings, and app termination. The app delegate (as it’s often referred to) is also the place where you’ll create your model. I explain the mysteries of the UIApplication class as well as the role of the app delegate in Chapter 6.
Taking a Look at Other Frameworks
So far, almost all the things that I’ve talked about can be found in the UIKit framework, whose sole purpose in life is to provide a developer with all the classes an app needs in order to construct and manage its user interface. The UIKit framework does a majority of the heavy lifting for you, but developers don't live by the UIKit framework alone; quite a few other frameworks get put into play as well. The next few sections give you a rundown of some of the other frameworks you may encounter.
The Foundation framework
The Foundation framework is similar to the UIKit framework in that it defines general-purpose classes. The difference is that whereas UIKit limits itself to classes that implement the user interface, the Foundation framework stakes a claim on all the other stuff — the non–user-interface stuff — you need in your app. In practical terms, this means that the Foundation framework defines basic object behavior, memory management, notifications, internationalization, and localization.
The Foundation framework also provides object wrappers or equivalents (for numeric values, strings, and collections) and utility classes (for accessing underlying system entities and services, such as ports, threads, and file systems as well as networking, and date and time management).
The CoreGraphics framework
The CoreGraphics framework contains the interfaces for the Quartz 2D drawing API and is the same advanced, vector-based drawing engine that's used in OS X. It provides support for path-based drawing, anti-aliased rendering, gradients, images, colors, coordinate-space transformations, and PDF document creation, display, and parsing. Although the API is C based, it uses object-based abstractions to make things easier for you. Although it is the basis for many things you see on the screen, you won’t be using it directly in this book.
Even more frameworks
Besides the UIKit, Foundation, and CoreGraphics frameworks, you use a handful of others in this book’s example app, as well as (I’m sure) in your own apps down the road. They are as follows:
· MapKit: Lets you embed a fully functional map interface into your app. The map support provided by this framework includes many of the features normally found in the Maps app.
· AVFoundation: Provides an Objective-C interface for managing and playing audio-visual media in your iOS app.
· AudioToolbox: Contains the APIs that provide application-level services — for playing sounds, for example.
· MediaPlayer: Provides basic functionality for playing movie, music, audio podcast, and audiobook files, as well as access to the iPod Library.
· SystemConfiguration: Contains interfaces for determining the network configuration of a device.
· CoreLocation: Provides location data to support functionality such as social networking. It also includes classes to do both forward and reverse geocoding (which I explain in Chapter 18).
You can find many, many more frameworks for your apps in iOS Technology Overview Appendix B: iOS Frameworks, which you can find in the iOS Developer Library, at http://developer.apple.com/library/ios/navigation/index.html; then enter iOS Technology Overview. Be advised that if you want to be able to do something, there's probably a framework to support it.
Understanding the MVC in the Project
As one might expect, when you create an Xcode project, any and all classes added to the project by the template correspond to the Model-View-Controller design pattern. No surprises there.
If you look carefully, you can actually see how the features of the MVC model end up getting translated into a real, live project. Start by checking out the Project navigator, where you see MasterViewController.h and .m files, DetailViewController.h and .m files, and AppDelegate.h and .mfiles. (Remember that, because everything in the iPad version is built using a split view, you’re going to see two controllers — one for the Master view and one for the Detail view. I explain that in detail in Chapter 13.)
The interface (.h file) contains the class declaration and the methods and properties associated with the class. But although the interface file has traditionally also included the instance variables, you’re actually going to include all instance variables in the implementation file instead, so you can keep them away from prying eyes. (You can find more on hiding the instance variables in Chapter 6.)
The implementation (.m file) contains the actual code for the methods of the class and — as just mentioned — also includes your instance variables.
The MasterViewController and DetailViewController correspond to the controllers I explain in the “View Controllers — the Main Storyboard Players” section, earlier in this chapter. But where are the classes that correspond to the views?
To find out, select the Main_iPad.storyboard file in the Project navigator and you see two view controllers in the Document Outline. Each view controller in a storyboard file manages a single scene. Select the disclosure triangle to expand the Master View controller and you see its view, shown in Figure 4-13.
Figure 4-13: The view controller highlighted on the Canvas.
When you click the view controller in the Document Outline, you see a (blue) line around the window to represent the view controller.
If you can’t see the Document Outline, you can use the Hide/Show Document Outline control, shown in Figure 4-14. You can also zoom in and out of a storyboard by double-clicking in the Interface Builder editor or using the zoom control shown in Figure 4-14.
Now click the view in the Document Outline, and you’ll see a display of the view itself — waiting for you to add all sorts of interesting images and controls (which you do in the next chapter). You can see that in Figure 4-14.
You see, of course, that the window changes — the view has been highlighted on the Canvas — but I explain more about that when I have you actually add the user interface elements in Interface Builder.
So now that you have controllers and views, what about models? (The design pattern is called Model-View-Controller, after all.) Well, the models aren’t there … at least not yet. For that other shoe to drop, you’ll have to go to Chapter 11, where I explain in great detail all about model classes and how to add them.
Figure 4-14: The view in the storyboard.
You can also see some of the other parts of the application infrastructure I mention earlier in the Project navigator. The AppDelegate.h and .m files in the Project navigation area correspond to the app delegate.
You’ll see one other element in the Document Outline — the first responder: This object is the first entry in an app’s dynamically constructed responder chain (a term I explain along with more about the application infrastructure at runtime in Chapter 6) and is the object designated to be the first handler of events other than touch events, such as motion events and a few other events you won’t be working with in this book.
But because the responder chain of an app can't be determined at design time, the first responder proxy acts as a stand-in target for any action messages that need to be directed at the app’s responder chain.
Although you might use the first responder mechanism quite a bit in your apps, you don’t have to do anything to manage it. It’s automatically set and maintained by the UIKit framework.