I\'m developing an app which will save data to the local file system. The data that will be saved will be mostly NSString and NSDate. The data will not be saved that often,
This kind of data seems to be very simple to store and retrieve and does not have any other dependencies such as a horridly complex object graph.
You should store this data in a flat file or in NSUserDefaults.
I'll give you an example of both, using object archiving with the use of the NSCoding protocol:
@interface ApplicationData {}
@property (nonatomic, strong) NSDate *someDate;
@property (nonatomic, strong) NSDate *someOtherDate;
@property (nonatomic, copy) NSString *someString;
@property (nonatomic, copy) NSString *someOtherString;
@end
@implementation ApplicationData
@synthesize someDate = _someDate, someOtherDate = _someOtherDate, someString = _someString, someOtherString = _someOtherString;
- (NSArray *)keys {
static dispatch_once_t once;
static NSArray *keys = nil;
dispatch_once(&once, ^{
keys = [NSArray arrayWithObjects:@"someString", @"someOtherString", @"someDate", @"someOtherDate", nil];
});
return keys;
}
- (id) copyWithZone:(NSZone *) zone {
ApplicationData *data = [[[self class] allocWithZone:zone] init];
if(data) {
data.someString = _someString;
data.someOtherString = _someOtherString;
data.someDate = _someDate;
data.someOtherDate = _someOtherDate;
//...
}
return data;
}
- (void) encodeWithCoder:(NSCoder *) coder {
[super encodeWithCoder:coder];
NSDictionary *pairs = [self dictionaryWithValuesForKeys:[self keys]];
for(NSString *key in keys) {
[coder encodeObject:[pairs objectForKey:key] forKey:key];
}
}
- (id) initWithCoder:(NSCoder *) decoder {
self = [super initWithCoder:decoder];
if(self) {
for(NSString *key in [self keys]) {
[self setValue:[decoder decodeObjectForKey:key] forKey:key];
}
}
return self;
}
@end
Then, say in your application delegate, you can do this:
@interface AppDelegate (Persistence)
@property (nonatomic, strong) ApplicationData *data;
- (void)saveApplicationDataToFlatFile;
- (void)loadApplicationDataFromFlatFile;
- (void)saveApplicationDataToUserDefaults;
- (void)loadApplicationDataFromUserDefaults;
@end
@implementation AppDelegate (Persistence)
@synthesize data;
- (NSString *)_dataFilePath {
static NSString *path = nil;
static dispatch_once_t once;
dispatch_once(&once, ^{
path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) stringByAppendingPathComponent:@"xAppData.dat"];
});
return path;
}
- (void)loadApplicationDataFromUserDefaults {
NSData *archivedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"appData"];
self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}
- (void)saveApplicationDataToUserDefaults {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data];
[[NSUserDefaults standardUserDefaults] setObject:archivedData forKey:@"appData"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)loadApplicationDataFromFlatFile {
NSData *archivedData = [NSData dataWithContentsOfFile:[self _dataFilePath]];
self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}
- (void)saveApplicationDataToFlatFile {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data];
[archivedData writeToFile:[self _dataFilePath] atomically:YES];
}
@end
Disclaimer: I have not tested this code.