CenoX CenoX - 8 months ago 32
iOS Question

How to save data in iOS

I'm making a game and when I close the app (close at multitask manager), all my data is gone! So, My question is very simple: How do I save the data?


Let's say you want to save score and level, which are both properties of an object called dataHolder.

DataHolder can be created as a singleton, so you don't have to worry too much about from where you access it (its sharedInstance actually):

It's code would look a bit like this:


#import <Foundation/Foundation.h>

@interface DataHolder : NSObject 

+ (DataHolder *)sharedInstance;

@property (assign) int level;
@property (assign) int score;

-(void) saveData;
-(void) loadData;



NSString * const kLevel = @"kLevel";
NSString * const kScore = @"kScore";

@implementation DataHolder

- (id) init
    self = [super init];
    if (self)
        _level = 0;
        _score = 0;
    return self;

+ (DataHolder *)sharedInstance
    static MDataHolder *_sharedInstance = nil;
    static dispatch_once_t onceSecurePredicate;
                      _sharedInstance = [[self alloc] init];

    return _sharedInstance;

//in this example you are saving data to NSUserDefault's
//you could save it also to a file or to some more complex
//data structure: depends on what you need, really

    [[NSUserDefaults standardUserDefaults] 
        setObject:[NSNumber numberWithInt:self.score] forKey:kScore];

    [[NSUserDefaults standardUserDefaults] 
        setObject:[NSNumber numberWithInt:self.level] forKey:kLevel];

    [[NSUserDefaults standardUserDefaults] synchronize];

    if ([[NSUserDefaults standardUserDefaults] objectForKey:kScore])
        self.score = [(NSNumber *)[[NSUserDefaults standardUserDefaults] 
            objectForKey:kScore] intValue];

        self.level = [(NSNumber *)[[NSUserDefaults standardUserDefaults] 
            objectForKey:kLevel] intValue];
        self.level = 0;
        self.score = 0;


Don't forget to #import "DataHolder.h" where you need it, or simply put it in ...-Prefix.pch.

You could perform actual loading and saving in appDelegate methods:

- (void)applicationDidEnterBackground:(UIApplication *)application
    [[DataHolder sharedInstance] saveData];

- (void)applicationWillEnterForeground:(UIApplication *)application
    [[DataHolder sharedInstance] loadData];

You can access your score and level data from anywhere with [DataHolder sharedInstance].score and [DataHolder sharedInstance].level.

This might seem like an overkill for a simple task but it sure helps to keep things tidy and it can help you to avoid keeping all the data in appDelegate (which is usually the quick & dirty path to solution).