iOS Autosaved object

247 views Asked by At

In my app I have Singleton object, which should save its state through app launches. So I need to save it somehow.

I see only two options: 1) save it on app termination (plus, maybe, going background); 2) save it each time any property changed.

First option looks bad, because app can be killed, for example, because of some bug, memory limits or device power-off (low battery). So I expect state won't be saved.

Second option needs either manual notifications about each change, or KVO + observing of each property.

Seems that I do something wrong here. Maybe, you can give me some advice or there is some well-known pattern (I've tried to google, but found nothing particular).

UPDATE:

Yes, there is NSUserDefaults, but to improve its usability (smth. more than just key-values) I would write wrapper-methords, so I will end with the same problem (lines of manual coding).

UPDATE2:

CoreData is also bad choice for me: just one object to store + inserting there also needs some more lines of code.

UPDATE3:

It's not a question about "how to save". It's about "how to call this saving automatically (or with less of coding)". So in NSUserDefault way we need to manually implement each property as wrapper. In NSCoding - call save or post notification (to catch & save from one place) from each property also.

2

There are 2 answers

5
Daniel On BEST ANSWER

The simplest way to save user states in iOS is through NSUserDefaults.

Here is an example which keeps track of all changed made to your singleton:

@interface MySingleton : NSObject
{
}

+ (MySingleton *)sharedSingleton;

@property (copy) NSString *userName;//the variable to track
@end

@implementation MySingleton
@synthesize userName;
+ (MySingleton *)sharedSingleton
{
  static MySingleton *sharedSingleton;

  @synchronized(self)
  {
    if (!sharedSingleton)
      sharedSingleton = [[MySingleton alloc] init];

    return sharedSingleton;
  }     
}

- (void)setUserName:(NSString*)userName
{
   //update the variable
   self.userName = userName;
   //saves the new value to NSUserDefaults
   [[NSUserDefaults standardUserDefaults] setObject:userName forKey:@"userName"]; 
   //forces instantaneous synchronization, not needed, would be updated after a periodic interval anyways
   [[NSUserDefaults standardUserDefaults] synchronize];
}
@end

Optionally you can implement the NSCoding protocol and save the whole class to NSUserDefaults, take a look at this question.

1
Istvan On

I think the first option is the better way to do it. The OS always informs the app when it will be killed for example for memory warnings the didReceiveMemoryWarning method will be called where you can save the states to the singleton object. (Device power off is same as go to background so the applicationWillEnterForeground method will be called).