9.22.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];
}

9.14.2012

String Representation of Date from UIDatePicker

In iOS, there's this UI element that allows the user to select the date and time. This is called the Date Picker.

Here's a way of getting the text from the iOS' Date Picker:


/*_datePicker is the current UIDatePicker object. Set the mode of the date picker. In this example, setting the time is disabled.*/
[_datePicker setDatePickerMode:UIDatePickerModeDate];
/*Initialize a NSDateFormatter object. This object will get the string representation of the NSDate object.*/
_dateFormatter = [[NSDateFormatter alloc] init];
/*Set the locale of the NSDateFormatter object.*/
NSLocale *locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_EN"] autorelease];
[_dateFormatter setLocale:locale];
/*Set the date style and the time style of the formatter. Note that the next two lines of code are important. Without them, when NSDateFormatter's instance function/method - stringFromDate: is used, the returned string is empty. It is not stated in the NSDateFormatter class reference that the default value of dateStyle and timeStyle are set to NSDateFormatterNoStyle but I think they are.*/
[_dateFormatter setDateStyle:NSDateFormatterLongStyle];
[_dateFormatter setTimeStyle:NSDateFormatterNoStyle];

...

/*This is the code for getting the string representation of the selected date*/
NSString *selectedDate = [_dateFormatter stringFromDate:_datePicker.date];


Note: Automatic Reference Counting (ARC) is not used in this example.