Ok, I've been over this a million times in the last week and I just am not getting it. (And yes, I've read Apple's docs.)
I am archiving my object and it appears to be archiving correctly (I can see the file written to the file system and if I examine it I can see my data within). However, when I relaunch my app my data is not being restored. Every example I read tells me how easy this is but I'm just not getting it. One unique thing is that my object is a singleton, it's used for passing data between view controllers.
I'd really appreciate some sage advice. Thanks in advance.
Here's my header:
#import <Foundation/Foundation.h>
@interface SharedAppDataObject : NSObject <NSCoding>
{
NSMutableDictionary *apiKeyDictionary;
NSString *skuFieldText;
NSIndexPath *checkmarkIndex;
}
+ (SharedAppDataObject *)sharedStore;
@property (nonatomic, copy) NSString *skuFieldText;
@property (nonatomic, copy) NSIndexPath *checkmarkIndex;
@property (nonatomic, copy) NSMutableDictionary *apiKeyDictionary;
-(void)setValue:(NSString *)apiKey forKey:(NSString *)name;
-(void)setSkuField:(NSString *)s;
-(void)setCheckmarkIndex:(NSIndexPath *)p;
-(NSMutableDictionary *)apiKeyDictionary;
-(BOOL)saveChanges;
@end
Here's my implementation:
#import "SharedAppDataObject.h"
@implementation SharedAppDataObject
@synthesize skuFieldText;
@synthesize checkmarkIndex;
@synthesize apiKeyDictionary;
//create our shared singleton store
+(SharedAppDataObject *)sharedStore {
static SharedAppDataObject *sharedStore = nil;
if (!sharedStore) {
sharedStore = [NSKeyedUnarchiver unarchiveObjectWithFile:[SharedAppDataObject archivePath]];
if(!sharedStore)
sharedStore = [[super allocWithZone:NULL] init];
}
return sharedStore;
}
-(id) init {
self = [super init];
if (self) {
}
return self;
}
-(void)setValue:(id)apiKey forKey:(NSString *)name {
[apiKeyDictionary setObject:apiKey forKey:name];
}
-(void)setSkuField:(NSString *)s {
skuFieldText = s;
}
-(NSMutableDictionary *)apiKeyDictionary {
return apiKeyDictionary;
}
-(void)setCheckmarkIndex:(NSIndexPath *)p {
checkmarkIndex = p;
}
-(void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:skuFieldText forKey:@"skuFieldText"];
[aCoder encodeObject:checkmarkIndex forKey:@"checkmarkIndex"];
[aCoder encodeObject:apiKeyDictionary forKey:@"apiKeyDictionary"];
}
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
[self setSkuFieldText:[aDecoder decodeObjectForKey:@"skuFieldText"]];
[self setCheckmarkIndex:[aDecoder decodeObjectForKey:@"checkmarkIndex"]];
[self setApiKeyDictionary:[aDecoder decodeObjectForKey:@"apiKeyDictionary"]];
}
return self;
}
+(NSString *)archivePath {
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [documentDirectories objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent:@"bbyo.archive"];
}
-(BOOL)saveChanges {
return [NSKeyedArchiver archiveRootObject:self toFile:[SharedAppDataObject archivePath]];
}
@end
Save method from App Delegate:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
BOOL success = [[SharedAppDataObject sharedStore] saveChanges];
if (success) {
NSLog(@"Saved all the data");
} else {
NSLog(@"Didn't save any of the data");
}
}
Initialize sharedStore = [NSKeyedUnarchiver unarchiveObjectWithFile:[SharedAppDataObject archivePath]];
in application:didFinishLaunchingWithOptions:
. This method is used to initialize data structures and restore previous app state.
Also, take out static SharedAppDataObject *sharedStore = nil;
from sharedStore
. If the save file exists, [ShareAppDataObject sharedStore]
will always unarchive the file which is not necessary. It can be unarchived once during initialization.
Here's a post that can answer your problem: http://bit.ly/PJO8fM