180 likes | 311 Views
Chapter 5 Data structures and IO. NSArray, NSDictionary, NSMutableArray, NSMutableDictionary Read from a file, write to a file. Arrays, Hashtables. Before we build the app, we will learn about arrays, hashtables, and file I/O NSArray fixed array NSMutableArray modifyable array
E N D
Chapter 5 Data structures and IO • NSArray, NSDictionary, NSMutableArray, NSMutableDictionary • Read from a file, write to a file
Arrays, Hashtables • Before we build the app, we will learn about arrays, hashtables, and file I/O • NSArray fixed array • NSMutableArray modifyable array • NSDictionary fixed hashtable • NSMutableDictionary modifyable hashtable
Arrays, Hashtables • NSArray fixed array • NSMutableArray inherits from NSArray which inherits from NSObject • NSDictionary fixed hashtable • NSMutableDictionary inherits from NSDictionary which inherits from NSObject • Search for NSMutableDictionary • documentation at developer.apple.com/ ….
Arrays, Hashtables, Files • NSArray and NSDictionary have methods that allow a NSArray object or a NSDictionary object to be written to or read from a file as a whole (as opposed to one piece of data at a time) • The method name, in both cases, is writeToFile
Arrays, Hashtables, Files • We will put keys and values in a NSMutableDictionary object, then write it to a file, then read it from that file • No need for a view to practice, we will put the code in main.m and view the output in the console
NSMutableDictionary NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; • Use the setObject:forKey method to add key/value pairs to dict [dict setObject:@”baltimore” forKey:@”maryland”]; [dict setObject:@”washington” forKey:@”dc”]; • @”stringValue” is a string literal
NSMutableDictionary • Using NSLog, we can output the whole hashtable NSLog( @”dict is %@”, dict ); • outputs all the key value pairs • %@ is the specifyer for an object • The object is dict
File I/O • Apple only allows us to write at specific places in the directory structure of the iPhone for security reasons (otherwise, an app could open every single file for writing and delete everything) • We can write to files inside a “sand box”, i.e. a small portion of the directory structure
File I/O • It is also poor practice to hard code a file path, because in future iPhone releases, the directory structure (and the sand box) might change • So we will decide on the file path dynamically, by asking the OS where we can write to a file and read from it
File I/O • The function NSSearchPathsForDirectoriesInDomain returns an array of possible locations for performing I/O on a file • The method call includes 3 arguments: NSSearchPathsForDirectoriesInDomain( NSDocumentDirectory, NSUserDomainMask, YES )
File I/O • NSDocumentDirectory we are looking for a directory that can store documents • NSUserMask we are looking for a directory relative to the current user (i.e. specific to your app, not shared folders) • YES tells the function to return the whole path by expanding any ~ (used in UNIX to represent the user’s home directory)
File I/O • It turns out that the function returns an array of 1 element (we can output it to confirm that) • We will choose that element, i.e. the one at index 0, for the directory path of the file we will write to
File I/O NSArray *paths = NSSearchPathsForDirectoriesInDomain( NSDocumentDirectory, NSUserDomainMask, YES ); // select the first element of the array // That is the directory where we will put the file NSString *dir = [paths objectAtIndex:0];
File I/O // append the name of the file to the directory path and assign the result to the string filePath NSString *filePath = [[NSString alloc] initWithString: [dir stringByAppendingPathComponent:@”cities.txt”]];
File I/O • We now can write to the file the whole hashtable [dict writeTofFile: filePath atomically: NO]; • Look up the method writeToFile : atomically on apple developer’s web site (in NSDictionary); remember that NSMutableDictionary inherits from NSDictionary
File I/O • atomically:YES we write to a temporary file first, then rename that file • if the system crashes during writing, we still have the old file intact • atomically:NO overwrite file directly
File I/O • Now that the file exists and we know has the contents of a dictionary, we can read those contents into a dictionary object • NSDictionary has a method called initWithContentsOfFile NSMutableDictionary * citiesAndStates = [[NSMutableDictionary alloc] initWithContentsOfFile: filePath];
File I/O • Before we attempt to read from a file, we may want to make sure that the file exists • We can do that with the NSFileManager class and its method fileExistsAtPath NSFileManager *fileManager = [NSFileManager defaultManager]; [fileManager fileExistsAtPath: filePath] /* returns YES or NO can use in an if statement*/