I'm newer to Xcode development and am trying to save the state of my app which tracks multiple index sets, integers and strings. I've tried a lot of different code and haven't been able to get it to work saving to a .plist. What is the best approach for saving the following data types, NSMutableIndexSets
and NSUIntegers
? Any direction would be great, Thanks.
3 Answers
Use the following code
//Saving
NSMutableIndexSet *set = [[NSMutableIndexSet alloc] init];
[set addIndex:1];
[set addIndex:2];
NSMutableArray *arrToSave = [[NSMutableArray alloc] init];
NSUInteger currentIndex = [set firstIndex];
while (currentIndex != NSNotFound)
{
[arrToSave addObject:[NSNumber numberWithInt:currentIndex]];
currentIndex = [set indexGreaterThanIndex:currentIndex];
}
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
NSUInteger integer = 100;
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/savePath.txt"];
[dic setValue:arrToSave forKey:@"set"];
[dic setValue:[NSNumber numberWithUnsignedInt:integer] forKey:@"int"];
[dic writeToFile:savePath atomically:YES];
//Loading
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/savePath.txt"];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithContentsOfFile:savePath];
NSArray *arr = [dic valueForKey:@"set"];
NSMutableIndexSet *set = [[NSMutableIndexSet alloc] init];
[set addIndex:[[arr objectAtIndex:0] unsignedIntValue]];
[set addIndex:[[arr objectAtIndex:1] unsignedIntValue]];
NSUInteger integer = [[dic valueForKey:@"int"] unsignedIntValue];

- 21,163
- 5
- 52
- 56
-
Thanks, this works for a set but how do I change the code to use an nsmutableindexset? This is the line I'm not sure how to convert,[dic setValue:[set allObjects] forKey:@"set"];? If I change 'set' to my nsmutableindexset, I get – rossi Jun 16 '12 at 17:27
-
I get an error 'Arc issue, no visible @interface for nsmutableindexset' declares the selector allObjects'. Thanks for the help Omar. Any ideas on converting this line for an indexset? – rossi Jun 16 '12 at 17:36
-
This works for the index set now. Thanks, Omar! – rossi Jun 18 '12 at 01:11
Far as I know there is a set list of items you can archive to a plist file. From memory (which means you should go look it up in the docs) it's NSString, NSArray, NSDictionary, NSData, NSNumber and... a couple of others that i can't remember. THe point is your index set probably isn't one of them so you'll need to convert it to something else, archive it and on wake unarchive it and reconvert back.

- 3,006
- 27
- 30
The short answer to your question is that you can't save index sets to a plist, or to user defaults. There is a very short list of object types that you can write to a plist. Look up the docs on the NSDictionary class in Xcode, and search for the string "property list object" That's where they tell you which objects can be written to a properly list. The object types are NSString, NSData, NSDate, NSNumber, NSArray, or NSDictionary objects.
Omar Abdelhafith posted a very long and complex block of code to convert an index set to an array, which should work.
There is a much simpler way however. NSIndexSet conforms to the NSCoding protocol, which means that you can convert it to NSData with a single call:
NSData *setData = [NSKeyedArchiver archivedDataWithRootObject: mySet];
And to turn it back into an index set:
NSIndexSet *setFromData= [NSKeyedUnarchiver unarchiveObjectWithData: setData];
NSMutableIndexSet *mutableSet = [setFromData mutableCopy];
Note that with all of these approaches, if you start with a mutable object (set, array, dictionary, etc) then when you read it back, the object you get back will be an immutable version. You have to manually convert it to a mutable version. Most objects that have a mutable variant support the method mutableCopy.

- 128,072
- 22
- 173
- 272