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