Home > 2011 Winter DPS913 > DPS913 APD601 Lab 3

DPS913 APD601 Lab 3

February 4, 2011 Leave a comment Go to comments

Lab 3 enables you to extend your Lab 2 effort in a few ways. You will create a tab bar style app, re-use your Lab 2 view controller, and add tabs to display a list of “buy” transactions, and to reset the app’s data. It is due on Friday, February 11.


DPS913 APD601 Lab 3 – due Fri Feb 11

Assigned: During Week 4

Due date: Friday, February 11, 2011, at 9:50am

Grade value: 3% of your final course grade

Grading method: The following will be checked:

  • Completeness and adherence to iOS app coding principles
  • Correct interactive operation of the app’s logic
  • Accurate numerical calculations


Before you begin

Configure your Xcode environment as described in the “Before you begin” section of Lab 1. This will ensure that your work can be uploaded for grading.



Work with a tab bar style application.

Modify an existing app to work in a tab bar app style (or add existing components to a new app).

Persist data / state.


Concepts that you will learn

  • Tab bar app style
  • Data persistence
  • Configuring view controllers with properties to expose data (to enable data sharing)
  • Modal view controller (alert)


Introduction to the problem that you will solve

The Red Dog Bus Company needs three enhancements to its “BusTickets” app:

  1. Display a list of “buy” transactions
  2. Save and restore its operating state
  3. Enable the user to reset the app’s data back to its initial state


You will create a “BusTicketsV2” iPhone OS app. It will use your Lab 2 view controller, but in a tab bar style application – it will be one of the tabs (probably the first/left-most tab).

Another tab will be used to display a list of “buy” transactions.

A third tab will enable the user to reset the app’s data back to its initial first-launch state.

You may want to name your view controllers as follows:

History – the list of “buy” transactions

Reset – the reset operation


As noted above, the application will save state/data. That is, if the user presses the “Home” button on the device, its current state will be saved. When the app is relaunched, the app’s state (i.e. the number of tickets still available on each bus route, and the list of transactions) will be preserved.

There are at least two ways of persisting and restoring your data.

One way, mentioned above, is to place your “save” code in the method that handles app shutdown.

The other way is to place your “save” code in the “buy tickets” button tap handler method.


The following images are examples of its user interface (yours may look different):

Lab 3 example, first tab Lab 3 example, second tab

Lab 3 example, third tab Lab 3 example, third tab, with alert



Create a new iOS app, using the “Window-based Application” template. Name it “BusTicketsV2”.

This will become a tab bar style application. There will be three tabs in your application:

  1. Your existing view controller (and view nib) from your BusTickets Lab 2
  2. A view with a UITextView that will (or a UITableView) show a list of transactions
  3. A view with a “reset” button, that uses an alert view to confirm the reset operation


Use Xcode to add existing files to your project – the existing files will be your Lab 2 view and view controller that handled the bus route ticketing functions (three files – .h, .m, and .xib).

The list of “buy” transactions must include:

  • A timestamp
  • Text that identifies the bus route
  • Text that indicates the purchase details


During usage, the application must now survive termination and re-launch, with no loss of data. We suggest that you use simple property list persistence.

For guidance on how to complete this lab, read the next section.


Lab 3 guidance

We suggest that you ensure that your BusTicketsViewController still works in this new iOS app, before you go on to make any additional changes.

For the next step, you may want to consider implementing the list of “buy” transactions. As you learned in the lecture, and through the “Tab update” example app, you configure a property on your “History” view controller. Then, it can be accessed at the right time by the “BusTickets” view controller.

Note: If you expose the “History” view controller’s UITextView as a property, it will be available for reading and writing by external objects.


To persist the data, we suggest saving the required array and the “buy” transaction string in a dictionary. Then, you can save the dictionary as a simple and uncomplicated plist, and restore it when the app (re)launches.

Dictionary structure:

  • A key-value pair for the array of available seats
  • A key-value pair for the list-of-transactions string


We don’t need to persist the array that is the picker’s data source, because we can rebuild that on demand.

Note: To ensure that your persistence scheme is working, configure this app for single-tasking. There is a new property that you must add to your <appname>-Info.plist file for this. (Hint: It begins with “Application…”)


How to access and update another view controller in a tab bar style app

In this app, the user will “buy” bus tickets, using the “BusTickets” view controller. In the “buy” button tap handler method, you need to access the UITextView that’s in the “History” view controller.

How do you do this?

Your view controller (i.e. “self”) has a tabBarController property, which is its tab bar controller. This tab bar controller has a viewControllers property, which is its array of view controllers.

In our app, the tab bar controller’s array of view controllers has three (3) elements:

  • Element 0 (…objectAtIndex:0) is (or should be!) the “BusTickets” view controller
  • Element 1 is the “History” view controller
  • Element 2 is the “Reset” view controller


OK so far? Check the UIViewController Class Reference for complete coverage.

When you want access to another view controller, you follow this pattern:

  1. Make sure that the “other” view controller has a property that you can (and want to) work with
  2. Get a reference to the other view controller
  3. Access its property – read or write as necessary


How do you get a reference to the other view controller? First, import the other view controller’s header (in your implementation):

#import “History.h”

Then, when you need to, you can get a reference to the other view controller:

History *historyVC = [self.tabBarController…

(I am going to leave the rest of the coding of that line to you. Check the reference material. Don’t use Google search results, because they’re typically crap, unless they’re from StackOverflow.)

Now that you have a reference to the other view controller (in “historyVC”), you can do “whatever”:

historyVC.propertyName = whateverYouWantToGetOrSet;

Note: Some readers will assert that we should use the delegation pattern to do this. For this Lab 3, we have specific teaching and learning goals for suggesting the above approach. Later in the course, we will prefer and recommend delegation to solve similar problems.


What about initializing other view controllers and their views?

Study the “Events 3” example app. In it, you will see the events that happen during the lifetime of a typical tab bar style app.

You will notice that each view controller is sent the awakeFromNib message. The result is that each view controller gets loaded into memory. That’s good, but it may not be enough. Specifically, the view controller’s “view” has not yet been loaded into memory.

Assume that you launch this BusTicketsV2 app for the first time. The first view controller (“BusTickets”) loads, and its view comes on to the screen. Assume that the user performs a “buy” operation.

At this point in time, as noted above, the “History” view controller has loaded into memory, but its view has not yet loaded into memory. We will need access to the view, because it contains the UITextView that will show the list of transactions.

How do we ensure that a view is loaded into memory, before we access it? Well, the documentation shows a “loadView” method. However, it says that “You should never call this method directly.” The answer to this problem is in the next line: The view will load when the view controller’s “view property is requested but is currently nil.”

Therefore, an easy way to deal with this is simply to wrap the code that updates the view in an “if” block:

if (historyVC.view) {
// code that updates a historyVC property


Additional challenge (for no marks)

Challenge: Persist the last-viewed bus route. This means adding another key-value pair to the dictionary to hold the segmented control’s selected index, and then using this value when the app launches to programmatically select that segment.


Send me your work

Make sure that you have configured your Xcode environment to avoid sending the intermediate build files. This will ensure that your uploads to me are the right size.

Follow these instructions to send me your work:

  1. Make sure your project works correctly
  2. Locate your BusTicketsV2 project folder in Finder
  3. Right-click the folder, and choose Compress “BusTicketsV2”, which creates a zip file
  4. Visit this page: http://matrix.senecac.on.ca/~peter.mcintyre/dps913/, and upload BusTicketsV2


Categories: 2011 Winter DPS913
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: