Archiving and UnArchiving Your App Data

If you are a new visitor to our site, please read the Getting Started guide.

In this workshop, you will learn how to use the NSKeyedArchiver and NSKeyedUnarchiver class to save and restore your application’s data in a binary file. You will also learn how to create a binary file in the application’s sandbox.

iOS provides several mechanism for saving and restoring your application’s data in its sandbox. One method available is to use the NSKeyedArchiver and NSKeyedUnarchiver class. These classes do not provide the scalability of a database, but they are easy to use. Also, they can archive/unarchive all kinds of objects, not just strings, arrays, and dictionaries.

The NSKeyedArchiver Class
This class provides the ability to encode data into binary data that is written to a binary file. The binary file must already exist in the application sandbox. The process of converting an object into binary data is called encoding.

By the way, the NSKeyedArchiver class encodes the entire content of the object (an NSArray for example) before writing it to the binary file.

The NSKeyedUnarchiver Class
This class decode a binary file’s data. Once the binary data have been decoded, you can place it your view’s controls; for example, a textView control or a pickerView control. The process of transforming binary data into a usable object is called decoding.

By the way, the NSKeyedUnarchiver class decode the entire content of the binary file. This mean you’d have to use a for or while loop and an if statement to access a specific object and its properties.

Download The Workshop Project

Now you know the purpose of the NSKeyedArchiver and NSKeyedUnarchiver class, I will show you how to use them in an Xcode project I’ve already created for this workshop; so, click the link below to download it.
download-excodeproj
After unzipping the file, use Finder to drag-and-drop the PlistApp folder in the iOS Apps folder you’ve created on your Mac.
plistworkshop-fig01
Use Finder to locate the file, PlistApp.xcodeproj then double-click it to launch it in Xcode.
plistworkshop-fig02

Take The App for a Spine

plistworkshop-fig03In Xcode, click the viewController.xib file to launch it in Interface Builder. Take a look at the view. As you can see, I’ve already placed these controls on it for you:

  • 1 textField control
  • 2 button controls (Save and Delete)
  • 1 textView control that display some descriptive text
  • 1 pickerView control

I’ve added code in the viewController.h file and the viewController.m file. I’ve connected the view’s controls in Interface Builder for you too. So go ahead, run the application, and try out the view’s control, except the pickerView control. The app will crash if you try to use it. Notice how the keyboard is dismissed when you click the view’s background or the return key. That’s because I’ve added code in the viewController.m file to handle these events. When you are ready, terminate the app by simply returning to Xcode, then press the (command + .) keys on your keyboard; or click the toolbar’s Stop button.

What Will The App Do?

The big question is, what will the app do? Well, controls on the viewController.xib file pretty much answer that question. In a nutshell, the app will allow the user to do these tasks:

  1. Add books in a binary file
  2. View a listing of books in a pickerView control
  3. Delete books from the binary file

You’ll have to add code in the ViewController class and the AppDelegate class to implement above user requirements.

Create The Binary File

Before the user can add books in the binary file, you’ll have to add code in the AppDelegate (.h and .m) files to create a binary file called BooksOwned.archive in the Documents directory. As you already know, that directory is located in the Plist App’s sandbox. Here’s a snap shot of what the sandbox currently look like on my computer.
plistworkshop-fig04
As you can see, the Documents directory is empty. Now is a good time to use Finder to access the Plist App sandbox. Take a look at the file path shown in above image. It shows the path to the PlistApp sandbox. Once you’re there, expand the Documents folder, so you can see the binary file created there later on.

Now, I want you to click the AppDelegate.h file add highlighted code.

Next, click the AppDelegate.m file and add highlighted code.

The next thing I want you to do, is add this statement in the AppDelegate.m file’s didFinishLaunchingWithOptions method.

In a nutshell, you set up two custom methods in the AppDelegate class. The first one, getPathToDocumentsDir, gets the full path to the sandbox’s Documents directory and return it to the caller of the method. The second method, createBinaryFile, creates a binary file in the sandbox’s Documents directory, only if it haven’t been created there yet. The name of the file the method creates is passed as a parameter.

Ok, run the application in Xcode by clicking the Run button on the toolbar button. As Xcode build and run the app in the iPhone Simulator, you should keep your eyes on the Plist App sandbox’s Documents directory, which you should have already expanded in Finder. In seconds, the BooksOwned.archive file is created right before your eye.
plistworkshop-fig05
The arrow in above snap shot shows the Objective-C statement responsible for creating the empty binary file in the sandbox’s Documents directory. The statement is a message, which says this:

AppDelegate (self), create a binary file called, BooksOwned.archive in the PlistApp sandbox’s Documents directory.

The Save Button Code

Ok, the BooksOwned.archive file is created in the sandbox’s Documents directory. We can now turn our attention to adding code in the SaveButtonTapped method. It is connected to the Save button control. When the user tap it, code the SaveButtonTapped is fired. This mean we need to add code in the method to basically save the book title the user enters in the textField control, in the BooksOwned.archive file.
plistworkshop-fig06
In order to figure out what code to add in the saveButtonTapped method, I used this pseudocode to express the method’s algorithm. Pseudocode is basically false code, used by programmers to express the application’s algorithm. An algorithm is like a recipe: it list the steps involved in accomplishing a task. Expressing the saveButtonTapped method’s algorithm in pseudocode, makes it easy to transform the pseudocode into Objective-C code. There is no standard form of pseudocode-you make up your own rules. The only-guideline is that the meaning of the pseudocode should be clear to anyone reading it.

Pseudocode for the SaveButtonTapped Method
BEGIN
  Declare and initialize a string variable bookTitle
  Remove leading and trailing white spaces and blank lines from the textField control
  IF(bookTitle.length > 0) THEN
   Create an object of the AppDelegate so we can use its properties and methods
   Add the bookTitle in the binary file.
   Reinitialize the pickerView control's dataSource object
   Clear out the bookTitle control
   Set the messageLabel control's text color to green
   Display a success message in the messageLabel
   Enable the pickerView control because there's at least one row in its component
   Refresh the pickerView control so the book title the user entered in the textField
   control shows up in the pickerView
   Get the index number of the last row that's in the pickerView control, then place it
   in the lastRowIndex variable
   Highlight the last row of the pickerView control
  ELSE
    Set the messageLabel's text color to red
    Clear out the textField control
    Display an error message in the messageLabel control
  ENDIF
END

Armed with above pseudocode, let us add code in the viewController.m file. First, click the file to load it in the code editor, then add this import statement below existing one. This import statement import the AppDelegate class, so we can use its properties and methods in the viewController class.

Next, scroll down to the saveButtonTapped method and add this code. Notice how I used steps of above pseudocode to document the button’s code.

I want you to add this code in the AppDelegate.h file, which declare methods used on in above code (line 14 and 17 ). While you are there, declare the third method you see below as well.

Next, add this code in the AppDelegate.m file, which implement above methods.

Test The Save Button Code

When you are done, run the application. Test the SaveButtonTapped method’s if() block statement by entering a book title in the textfield control, then click the Save button. You should see output shown in Figure (a) below. Next, test the else block’s code by clicking the Save button without entering text in the textField control. You should see output shown in Figure (b) below.

plistworkshop-fig07
Figure (a)
plistworkshop-fig08
Figure (b)

The pickerView Control Code

You need to add code in the viewController class files to fetch content from the BooksOwnned file, and load the pickerView control with book titles. You’ll have to add code in the class to delete the component row the user selected from the pickerView control and the BooksOwned.archive file as well. In order to fulfill these requirement, you’ll have add this code in the viewDidLoad method, which fetch data from the BooksOwned.archive file and place them in the pickerViewDataSource array variable. This array is known as the pickerView control’s dataSource object. It hold data that’ll be displayed in the pickerView component rows like this:

plistworkshop-fig10

Figure (c)

Here are the pickerView control’s dataSource methods to add in the ViewController.m file, which display data in the pickerView control’s component rows.

Here is the delegate method of the pickerView control to add in the viewController.m file.

The viewDidLoad Method Code

Before testing the pickerView control’s code, you’ll have to add these statements in the viewController.h file’s viewDidLoad method.

Test The PickerView Control Code

You entered code in a delegate method of the pickerView control, which highlight the pickerView component row the user selects and display it in the messageLabel, located below the Save button control.

plistworkshop-fig10

I want you to use the viewController’s textField and Save button to add these books in the BooksOwned.archive file. Notice how the book title appears in the pickerView control and is highlighted, when you click the Save button.

The Fierce Dispute
Simple Program Design
One for The Money
From Dead to Worse
Living Dead in Dallas
Hush
Lasher
Interview with The Vampire
Dead in The Family

Once you’ve entered the last title, terminate the application. When you relaunch it, the book titles you added in the BooksOwned.archive file shows up in the pickerView control-see image above.

The Delete Button Code

The last piece of code you need to add in the viewController.m file will go in the deleteButtonTapped method. It is connected to the Delete button control.

Once you’ve entered above code in the Delete button’s method, run the application and delete one or all book titles from the pickerView control, then terminate the app. When you relaunch the app again, rows you deleted from the pickerView control don’t show up. That’s because you’ve added code in the deleteButtonTapped method to delete a book title from the pickerView’s dataSource object (pickerViewDataSource) and the binary file (BooksOwned.archive).

This concludes this week’s workshop on how to use the NSKeyedArchiver Class and the NSKeyedUnarchiver class.