Search code examples
iosnskeyedarchivernscoding

Can't restore archived data


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");
    }
}

Solution

  • 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