gone
gone

Reputation: 1129

Saving contents of NSMutableArray containing custom class objects

I have a custom class "Bookmark" which contains an NSString. I use a NSMutableArray to store instances of this class thus making a bookmark list which I display in a UITableView with a UITableViewCell prototype.

Would someone please give some advice/example on how to save the instances within the NSMutableArray to a file (and perhaps an example how to load them). I can't get any examples I've searched to work. I've tried converting the array to NSData and using NSKeyedArchiver without success. I've also tried converting to an NSArray but can't get it to work.

Within the custom class I've implemented encodeWithCode and initWithCoder.

I need to save before the app closes and I want to load the list when the app is started.

I'm stuck... :(

EDIT: At the request of Ageektrapped, here are the code snippets:

Inside the implementation of my Bookmark class:

- (void) encodeWithCoder: (NSCoder *) encoder
{
  [encoder encodeObject:self.address forKey:@"Address"];
}

- (id) initWithCoder: (NSCoder *) decoder
{
  self = [super init];
  if (self != nil)
  {
    self.address = [decoder decodeObjectForKey: @"Address"];
  }
  return self;
}

In my MasterViewController

self.bookmarks is a NSMutableArray containing bookmark objects. (When the code below is called, there is at least one entry in the bookmarks array.)

NSString *docFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory,NSUserDomainMask,YES) lastObject];
NSString *filename = [docFolder stringByAppendingPathComponent:@"data.plist"];
NSLog(@"File : %@", filename);
NSLog(@"Bookmarks : %d", self.bookmarks.count);

NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self.bookmarks ];
if ([data writeToFile: filename atomically: YES])
{
  NSLog(@"Successful write");
} else {
  NSLog(@"Failed write");
}

Upvotes: 0

Views: 216

Answers (1)

gone
gone

Reputation: 1129

I finally figured out what my problem was. Because I'm debugging on my iPhone device, some folders are not writable. The code I was using was asking for a location in such an area (NSDocumentationDirectory):

After finally finding => How can I get a writable path on the iPhone? I understood my problem and got it working.

What I needed to do was replace:

NSString *docFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory,NSUserDomainMask,YES) lastObject];
NSString *filename = [docFolder stringByAppendingPathComponent:@"data.plist"];

with:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask,YES);
NSString *libFolder = [paths objectAtIndex: 0];
NSString *filename = [libFolder stringByAppendingPathComponent: @"data.archive"];

I also changed these lines (to be consistent with the example) from:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self.bookmarks ];
if ([data writeToFile: filename atomically: YES])
{
  NSLog(@"Successful write");
} else {
  NSLog(@"Failed write");
}

to:

BOOL success = [NSKeyedArchiver archiveRootObject: self.bookmarks toFile: filename];
if (success)
{
  NSLog(@"Successful write");
} else {
  NSLog(@"Failed write");
}

.

The code to read the file into the NSMutableArray on application startup is:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask,YES);
NSString *libFolder = [paths objectAtIndex: 0];
NSString *filename = [libFolder stringByAppendingPathComponent: @"data.archive"];
self.bookmarks = [NSKeyedUnarchiver unarchiveObjectWithFile: filename];

Upvotes: 1

Related Questions