Difference between revisions of "IPhone OS Directory Handling and File I/O – A Worked Example"

From Techotopia
Jump to: navigation, search
m (Text replacement - "<hr> <table border=" to "<htmlet>ezoicbottom</htmlet> <hr> <table border=")
m (Text replacement - "<table border="0" cellspacing="0">" to "<table border="0" cellspacing="0" width="100%">")
 
Line 1: Line 1:
<table border="0" cellspacing="0">
+
<table border="0" cellspacing="0" width="100%">
 
<tr>
 
<tr>
 
<td width="20%">[[Working with Files on the iPhone|Previous]]<td align="center">[[iPhone App Development Essentials|Table of Contents]]<td width="20%" align="right">[[iPhone Data Persistence using Archiving|Next]]</td>
 
<td width="20%">[[Working with Files on the iPhone|Previous]]<td align="center">[[iPhone App Development Essentials|Table of Contents]]<td width="20%" align="right">[[iPhone Data Persistence using Archiving|Next]]</td>
Line 175: Line 175:
 
<htmlet>ezoicbottom</htmlet>
 
<htmlet>ezoicbottom</htmlet>
 
<hr>
 
<hr>
<table border="0" cellspacing="0">
+
<table border="0" cellspacing="0" width="100%">
 
<tr>
 
<tr>
 
<td width="20%">[[Working with Files on the iPhone|Previous]]<td align="center">[[iPhone App Development Essentials|Table of Contents]]<td width="20%" align="right">[[iPhone Data Persistence using Archiving|Next]]</td>
 
<td width="20%">[[Working with Files on the iPhone|Previous]]<td align="center">[[iPhone App Development Essentials|Table of Contents]]<td width="20%" align="right">[[iPhone Data Persistence using Archiving|Next]]</td>

Latest revision as of 20:01, 27 October 2016

PreviousTable of ContentsNext
Working with Files on the iPhoneiPhone Data Persistence using Archiving


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


In the Working with Directories on iPhone OS and Working with Files on the iPhone chapters of this book we discussed in some detail the steps involved in working with the iPhone OS file system in terms of both file and directory handling from within applications. The goal of this chapter is to put this theory into practice by working through the creation of a simple application that demonstrates some of the key concepts outlined in the preceding chapters.


Contents


The Example Application

The steps in this chapter walk through the creation of a simple iPhone application that consists of a text field and a button. When the user touches the button after entering text into the text field, that text is saved to a file. The next time the application is started, the contents of the file is read by the application and pre-loaded into the text field.

Setting up the Application project

The first step in creating the application is to set up a new project. To do so, start the Xcode environment and select the option to create a new project (or select the File -> New Project menu option if Xcode is already running or the welcome screen does not appear by default).

Select the View-based Application template, click the Choose… button and name the project FileExample.


Defining the Actions and Outlets

The application user interface is going to consist of a text field and a button. Before we design the user interface, however, we need to declare the outlet and action that correspond to these visual components.

Begin by selecting the FileExampleViewController.h file from the file list in the main Xcode project window and modify the view controller interface declaration as follows to add the action and outlet:

#import <UIKit/UIKit.h>

@interface FileExampleViewController : UIViewController {
        UITextField             *textBox;
        UIButton                *saveButton;
}
@property (nonatomic, retain) IBOutlet UITextField *textBox;
- (IBAction)saveText:(id)sender;
@end

The next step is to synthesize the accessors for the textBox outlet and to create a template method for the saveText action method. This, of course, is performed within the FileExampleViewController.m implementation file, the top section of which should be modified as follows:

#import "FileExampleViewController.h"

@implementation FileExampleViewController
@synthesize textBox;

- (void)saveText:(id)sender
{
}
.
.
.
- (void)viewDidUnload {
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
        self.textBox = nil;
}
- (void)dealloc {
        [textBox release];
        [super dealloc];
}

@end

We will return to the code later to add the required functionality, but before doing so, we need to design the user interface for our application.

Designing the User Interface

As previously described, our application is going to consist of a button and a text field. To begin the user interface design process, double click on the FileExampleViewController.xib file to launch the Interface Builder tool. Once the tool has started, drag a UIButton and then a UITextField from the Library window (Tools -> Library) onto the view. Double click on the button and change the text to Save. Position the components and resize the width of the text field so that the layout appears as illustrated in the following figure:

The layout of the iPhone file I/O example user interface


The next step is to establish the connections between the user interface components and the action and outlet created in the view controller code. Open the Connections Inspector window by selecting the Tools -> Connections Inspector menu option, or by pressing Command+2 on the keyboard, and select the button object in the view window so that the available events for that object are listed in the connections inspector window. Click in the small circle to the right of the Touch Up Inside event and drag the blue line to the File’s Owner entry in the documents window. Release the mouse button and select the saveText action method from the resulting menu to create the connection.

To connect the text field to the textBox outlet declared in the view controller interface file, press and hold the control key, click with the mouse over the File’s Owner and drag the blue line to the text field object in the view window. Release and select the textBox entry from the resulting menu.

The user interface design is now complete and the connections are now established. Save the design (File -> Save) and exit from Interface Builder (Interface Builder -> Quit Interface Builder).

Checking the Data File on Application Startup

Each time the application is launched by the user we need to check to see if the data file already exists (if the user has not previously saved any text the file will not have been created). If the file does exist, the contents need to be read by the application and displayed within the text field. A good place to put initialization code of this nature is in the viewDidLoad method of the view controller. With this in mind, select the FileExampleViewController.m file and scroll down to the viewDidLoad method. Remove the comment markers from around the method and edit it as follows:

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {

        NSFileManager *filemgr;
        NSString *dataFile;
        NSString *docsDir;
        NSArray *dirPaths;

        filemgr = [NSFileManager defaultManager];

        // Identify the documents directory
        dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        docsDir = [dirPaths objectAtIndex:0];

        // Build the path to the data file
        dataFile = [docsDir stringByAppendingPathComponent: @"datafile.dat"];

        // Check if the file already exists
        if ([filemgr fileExistsAtPath: dataFile])
        {
                // Read file contents and display in textBox
                NSData *databuffer;
                databuffer = [filemgr contentsAtPath: dataFile];

                NSString *datastring = [[NSString alloc] initWithData: databuffer encoding:NSASCIIStringEncoding];

                textBox.text = datastring;
                [datastring release];
        }

        [filemgr release];
        [super viewDidLoad];
}

Before proceeding we need to take some time to talk about what the above code is doing. First, we declare some variables that will be used in the method and then create an instance of the NSFileManager class. Because each application on an iPhone device has its own Documents directory, we next make the appropriate calls to identify that directory and assign the result to the docsDir. Once we know where the documents directory is located we construct the full path to our file (which is named datafile.dat) before checking whether the file already exists. If it exists, we read the contents of the file and it assign to the text property of our text field object so that it is visible to the user. Finally, we release the file manager object.

Now that we have the initialization code implemented we need to write the code for our action method.

Implementing the Action Method

When the user enters text into our text field component and touches the save button, the text needs to be saved to the datafile.dat file located in the application’s Documents directory. In order to make this happen we need, therefore, to implement the code in our saveText action method. Select the FileExampleViewController.m file if it is not already open and modify the template saveText method we created previously so that it reads as follows:

- (void)saveText:(id)sender
{
        NSFileManager *filemgr;
        NSData *databuffer;
        NSString *dataFile;
        NSString *docsDir;
        NSArray *dirPaths;

        filemgr = [NSFileManager defaultManager];

        dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        docsDir = [dirPaths objectAtIndex:0];

        dataFile = [docsDir stringByAppendingPathComponent: @"datafile.dat"];

        databuffer = [textBox.text dataUsingEncoding: NSASCIIStringEncoding];

        [filemgr createFileAtPath: dataFile contents: databuffer attributes:nil];

        [filemgr release];
}

This code creates a file manager instance, identifies the documents directory and constructs the full path to our data file. It then converts the text containing in the text field object and assigns it to an NSData object the contents of which, in turn, are written to the data file by calling the createFileAtPath method of the file manager object.

Building and Running the Example

<google>IOSBOX</google> Once the appropriate code changes have been made, test the application by clicking on the Build and Run button located in the toolbar of the main Xcode project window. Assuming no compilation errors are encountered, the application should run within the iPhone Simulator.

When the application has loaded, enter some text into the text field and click on the Save button. Press the round button at the bottom of the device to exit the application and then restart it by selecting the FileExample icon on the simulator screen. On loading for a second time the text field will be primed with the text saved during the previous session:

The iPhone file I/O example app running


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book



PreviousTable of ContentsNext
Working with Files on the iPhoneiPhone Data Persistence using Archiving