Recently, I'm a senior in high school, and I'm interested in making apps for iPhone. Recently, one of my apps came out: NBlock. It's a puzzle app and it's very challenging. However, it has a few problems. The high scores are not saved. I've been told to use a plist. Any tips?
- 
                    4You could start by reading [apple's plist tutorial]( http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/PropertyLists/QuickStartPlist/QuickStartPlist.html). – Jon7 Aug 14 '11 at 22:02
 
5 Answers
The URL based method for this:
// Get the URL for the document directory
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *documentDirectoryURL = [[fileManager URLsForDocumentDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0];
// Turn the filename into a string safe for use in a URL
NSString *safeString = [@"scores.plist" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// Create an array for the score
NSMutableArray *array = [[NSMutableArray alloc] init];      
[array addObject:[NSNumber numberWithInt:score]];
// Write this array to a URL
NSURL *arrayURL = [NSURL URLWithString:safeString relativeToURL:documentDirectoryURL];
[array writeToURL:arrayURL atomically:YES];
- 146,289
 - 39
 - 203
 - 257
 
- 
                    1To me it seems much cleaner and clearer to use `-[NSURL URLByAppendingPathComponent:]` for file URLs instead of the relative URL. This would remove the need for percent escaping of the path and is generally less error prone. – Nikolai Ruhe May 27 '13 at 07:06
 
I'd avoid using a plist. The easiest way to save simple data in an application, by far, is NSUserDefaults.
Check out this tutorial for a simple guide on how to use NSUserDefaults. Always be sure to synchronize NSUserDefaults when you're done writing to them.
If you're looking for a more powerful (but more complex) way to save data, check out Apple's guide to using Core Data.
- 
                    I thought NSUserDefaults was recommended for standardised default settings that you want to persist related to language preferences and the like? – cheznead Nov 13 '15 at 15:36
 
Heres what you want:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"scores.plist"];
NSMutableArray *array = [[NSMutableArray alloc] init];      
[array addObject:[NSNumber numberWithInt:score]];        
[array writeToFile:path atomically:YES];
And to add new scores do initWithContentsOfFile:@"scores.plist" instead of init in the declaration of array. You can optionally use NSUserDefaults.
- 9,819
 - 6
 - 41
 - 48
 
- 9,274
 - 12
 - 59
 - 88
 
- 
                    1Can somebody who's on a pc please format the source code in my post right? Its impossible on my ipod.... – JonasG Aug 14 '11 at 22:44
 - 
                    
 - 
                    2But why would you need the URL method if you aren't actually writing to a URL?? – JonasG Aug 15 '11 at 01:31
 - 
                    Just because it's a local file doesn't mean that it is not a URL. IIRC the recommendation is to move away from path based file methods to URL based ones. Your answer is fine and works - I just wanted to show another way of doing the same thing using URLs instead of paths. – Abizern Aug 15 '11 at 01:34
 
Take a look into NSKeyedArchiver/Unarchiver. You can save pretty much anything you want; NSUserDefaults, in my experience, dumps your data if you kill your app from the tray. Core data is really used better if you're managing large amounts of data with databases such as sqlite.
- 1,400
 - 2
 - 11
 - 14
 
- 
                    1I've never had that issue with a properly `synchronize`d `NSUserDefaults`. – mopsled Aug 14 '11 at 22:19
 - 
                    1I'll look into that, thanks. NSUserDefaults is really only good if you're just saving a simple string or something like that (I guess the asker might be a good candidate), as long as it can be permanently saved. – Dylan Reich Aug 14 '11 at 22:23
 - 
                    Check out the link I added in my answer to see how to deal with that issue. – mopsled Aug 14 '11 at 22:27
 
I would say the below code will work and pretty straight forward unless custom object data types(Its a different story again) are used:
NSString* plistPath = nil;
NSFileManager* manager = [NSFileManager defaultManager];
 if ((plistPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"PathTo.plist"])) 
   {
    if ([manager isWritableFileAtPath:plistPath]) 
     {
       NSMutableDictionary* infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
      [infoDict setObject:@"foo object" forKey:@"fookey"];
      [infoDict writeToFile:plistPath atomically:NO];
      [manager setAttributes:[NSDictionary dictionaryWithObject:[NSDate date] forKey:NSFileModificationDate] ofItemAtPath:[[NSBundle mainBundle] bundlePath] error:nil];
     }
   }
setting the date attribute might be helpful to check when is the last time score was updated.
- 140
 - 12