9.21.2012

[iOS] Saving the Singleton Object's State to File

Here's a way to save a singleton object's state into a file.
TestSingleton.h:
@interface TestSingleton : NSObject

@property (nonatomic, retain) NSString *testString;

+ (id)sharedInstance;
- (BOOL)saveState;

@end

TestSingleton.m:
#import "TestSingleton.h"

static TestSingleton *sharedInstance = nil;

@interface TestSingleton()

@property (nonatomic, retain) NSString *file;

@end

@implementation TestSingleton

@synthesize testString = _testString;
@synthesize file = _file;

- (void)dealloc
{
    [_testString release];
    [_file release];
    [super dealloc];
}

+ (id)sharedInstance
{
    @synchronized(self){
        if(sharedInstance == nil){
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *documentsDirectory = [paths objectAtIndex:0];
            NSString *testFile = [documentsDirectory stringByAppendingPathComponent:@"testfile.sav"];
            Boolean fileExists = [[NSFileManager defaultManager] fileExistsAtPath:testFile];
            
            if(fileExists) {
                sharedInstance = [NSKeyedUnarchiver unarchiveObjectWithFile:testFile];
            }
            else{
                sharedInstance = [[super allocWithZone:NULL] init];
            }
            sharedInstance.file = testFile;
        }
    }
    return sharedInstance;
}

- (BOOL)saveState
{
    return [NSKeyedArchiver archiveRootObject:self toFile:sharedInstance.file];
}

- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:_testString forKey:@"test"];
}

- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
    if(self){
        _testString = [[NSString alloc] initWithString:[aDecoder decodeObjectForKey:@"test"]]; 
    }
    return self;
}

@end


Now, in the app delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    TestSingleton *singleton = [TestSingleton sharedInstance];
    NSLog(@"PREVIOUS STATE: %@", singleton.testString);
    //Update testString
    singleton.testString = [[NSDate date] description];
    NSLog(@"NEW STATE: %@", singleton.testString);
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    //This will save the state of the singleton object when the object tries to go the background
    [[TestSingleton sharedInstance] saveState];
}

No comments:

Post a Comment