0

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.

pasawaya
  • 11,515
  • 7
  • 53
  • 92
rossi
  • 133
  • 3
  • 10

3 Answers3

0

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];
Omar Abdelhafith
  • 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
0

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.

Cocoadelica
  • 3,006
  • 27
  • 30
0

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.

Duncan C
  • 128,072
  • 22
  • 173
  • 272