I think this is a beginner's question about data management.
I have an app which loads and saves different txt files. I would like to give each txt file certain characteristics which are not saved in the txt file, such as name, style, colour etc.
What I did so far was to have a NSMutableArray *myLibrary where I would save all these references. The array looks like this:
- for each txt file one object is added to myLibrary
- each object holds several NSStrings, NSUInteger, BOOLs, and some NSMutableArrays
in my subclass for these objects, I work with
-(id)initWithCoder:(NSCoder *)aDecoder; -(void)encodeWithCoder:(NSCoder *)aCoder;
Now, my big question is what the best and safest way is to persevere this data. So far, I've worked with NSKeyedArchiver, but users have reported data loss and there has been one weird case in which the iTunes sync allegedly caused data to be messed up. Is NSUserDefaults any saver? I am saving the myLibrary.dat every time the user has made a change, so I don't really understand why it shouldn't be 100% save. Any advice / suggestions / explanations would be very much appreciated!
Here is the code with which I write and read myLibrary.Dat:
-(NSString*)documentsDirectory
{
NSLog(@"documentsDirectory");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents directory
return documentsDirectory;
}
-(void)saveLibraryDat {
NSLog(@"Saving myLibrary.dat...");
NSString *filePath = [[self documentsDirectory] stringByAppendingPathComponent:@"myLibrary.dat"];
BOOL succeed = [[NSKeyedArchiver archivedDataWithRootObject:myLibrary] writeToFile:filePath atomically:YES];
if (!succeed){ // do something }
}
-(void)loadLibraryDat {
NSLog(@"loadLibraryDat");
NSString *filePath = [[self documentsDirectory] stringByAppendingPathComponent:@"myLibrary.dat"];
self.myLibrary = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
if (self.myLibrary == nil) {
NSLog(@"myLibrary.dat empty... set up new one");
[self setupLibrary];
} else { NSLog(@"Loading myLibrary.dat successful."); }
}
EDIT: My coder methods look like this:
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
self.titleName = [aDecoder decodeObjectForKey:@"titleName"];
self.fileName = [aDecoder decodeObjectForKey:@"fileName"];
self.fileFont = [aDecoder decodeObjectForKey:@"fileFont"];
self.tabTitles = [aDecoder decodeObjectForKey:@"tabTitles"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:titleName forKey:@"titleName"];
[aCoder encodeObject:fileName forKey:@"fileName"];
[aCoder encodeObject:fileFont forKey:@"fileFont"];
[aCoder encodeObject:tabTitles forKey:@"tabTitles"];
}
@end
in the header these are defined as:
NSString *titleName;
NSString *fileName;
NSString *fileFont;
NSMutableArray *tabTitles;