Day 7 - First functional app

Sep 04, 2015 at 08:34 am, by Pierre Liard

I realized eventually today my first really functional app, a To Do List. It may seem a bit lame - they are thousand of To Do List apps out there - but it was a very nice respite after yesterday's difficulties. It summarized almost everything I have learned so far. The Table View was as easy as it was difficult yesterday, and it made be realized it may be worth to create a kind of personal library with all these boiler plate pieces of code to retrieve them quickly.

To make this To Do List app running, it is necessary to store permanently the data in order to retrieve them each time this app starts, and to edit them. Storing data is done in two steps: record the data and get them back. They are many way to save data in an app. Rob uses a method called NSUserDefaults. It has some limits, but it is pretty easy to use to save numbers and strings. It's not the first time that we encounter a method's name starting with NS. What does it stand for? When Steve Jobs left Apple in 1985, he created a company called NeXSTEP that developed a objected oriented operating system based on UNIX. This code is now at the base of iOS and OX X systems. The NS abbreviation is a reminiscence of this past (there is more to the story, and a simple internet search will return a lot of information).

This NSUserDefaults is intended to save standard defaults of a user by creating an object and giving it a value and a key:

NSUserDefaults.standardUserDefaults().setObject(toDoList, forKey: "toDoList")

The "toDoList" refers to a table view with the same name, but the key can be named as wished. In a similar way, NSUserDefault will retrieve the data by searching by the key defined above:

toDoList = NSUserDefaults.standardUserDefaults().
           objectForKey("toDoList")! as! [String]

The ending of this statement may seem odd. Why forced the unwrapping of the variable and precise its type, when this has already be done (not shown here)? When the data are saved in the first step, the type (string, integer) is not kept and the saved data need be converted to the type prior the storage. It is what ! as ! [String] is for. The square brackets indicate that the string is inside an array. That's it. As said before, they are more "evolved" ways to save data in iOS, but this method is sufficient for now.

The To Do List app introduced me also to the world of multiple view controllers. As you may remember from Day 1, we have so far always worked with a single view application. As you can imagine, there are probably very few apps with a single view, so it was time to get in touch with multiple views. It can be done inside the project you're working on, but the easiest way, at least for a beginner, is to start a new project and to select "Tabbed Application" instead of a single view:

tabbed app

It creates two view controllers with of course two related Swift files, and a tab bar controller that allows simply to go back and forth from the first controller to the second, when they are loaded:

Two controllers view

The arrows going from the bar controllers to the two controllers are called segues (pronounced "seg-way"). They represent connections and allow transition from one display to another. A segue changes what is on the screen: for example in the To Do List app, by clicking on a button, you can navigate from one controller to another. A segue is generally triggered by taps on buttons, table view cells, gestures etc.

The last element I would like to explain is how to edit data in a table view. It's probably one of the most used iOS features: the right to the left swipe. This gesture can produce various responses: modify the content, change the style, move and delete data. We will focus on how to delete one cell in the table view. The process is pretty similar to creating a table view. At first we need to call the UITableViewDelegate and to search for a function allowing to edit an item in the table:

func tableView(tableView: UITableView, commitEditingStyle editingStyle:  
     UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){...}

Then a method specific to editing has to be inserted between the curly brackets. It is called "editingStyle" and needs to check at first what kind of editing is desired:

if editingStyle == UITableViewCellEditingStyle.Delete { ... }

If the swipe to the left matches the action of delete, the corresponding row will be deleted. As the To Do List data are saved into an array, the corresponding row's index has to be removed as follows:

if editingStyle == UITableViewCellEditingStyle.Delete {
     toDoList.removeAtIndex(indexPath.row) .... }

What is left now is to update the data. It is done by the same command NSUserDefaults we have seen before:

NSUserDefaults.standardUserDefaults().setObject(toDoList, forKey: "toDoList")

Finally the To Do List in the table view needs to be reloaded to reflect all the changes made during the editing process. Here is the complete sequence to delete a cell, to update the data and eventually to reload the view:

func tableView(tableView: UITableView, commitEditingStyle editingStyle:
     UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
            if editingStyle == UITableViewCellEditingStyle.Delete { 
               NSUserDefaults.standardUserDefaults().setObject(toDoList, forKey: "toDoList")

Let's have a final look at the finished product:

deleted cell

A lot of material has been covered in this chapter 5: Navigation and menu bars, Table View, permanent storage, multiple views controllers and segues, and at last a fully useful app. Downloading content from the web and displaying it to users in their apps is what is coming next. It lets already anticipate some intricate string manipulation from the web extracted data. It's the case of apps that agglomerate news, posts, or simply weather forecasts. Manipulation of data is an essential task for any developer: without it, the modern IT ecosystem wouldn't be possible. Who said that information was power? probably some IT guy!

Leave a comment

Login to comment a post