0

In my application, I have a dictionary called matchDataDictionary and I set the following:

[[GCTurnBasedMatchHelper sharedInstance].matchDataDictionary setObject:deck forKey:@"deck"];

where deck is an instance of Deck: https://gist.github.com/naderhen/4711899

I then am trying to just test the archiving/unarchiving with the following:

Archiving (this seems to work):

NSMutableData *newData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:newData];
[archiver encodeObject:[GCTurnBasedMatchHelper sharedInstance].matchDataDictionary forKey:@"root"];
[archiver finishEncoding];

NSLog(@"Archived Data: %@", newData);

Unarchiving (Doesn't Work):

NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:newData];
NSMutableDictionary *matchDataDictionary = [unarchiver decodeObjectForKey:@"root"];
[unarchiver finishDecoding];

NSLog(@"Unarchived Data: %@", matchDataDictionary);

Any guidance as to how I can go about effectively archiving and subsequently unarchiving this data would be greatly appreciated. If it helps, this is for a turn-based game using the GameKit framework, so I'm trying to prepare user actions to send via the current match's matchData.

Also! Any advice on how I might fix up the Deck encoding to include its "Tiles" array would be greatly appreciated.

Thanks so much!

Nader

Nader Hendawi
  • 375
  • 1
  • 7
  • 17

1 Answers1

0

Use the NSCoding protocol. Each entity encodes itself, and then decodes itself. Kind of magical how easy it is, and as the app grows, people can add the functionality to the new parts of the object graph without knowing anything about the archivers/unarchivers, or their formats.

NSCoding Protocol

I have an open source project on GitHub that makes it easy to do NSCoding to/from JSON: JSONCoding.

Here is some code from before I developed that (out of a unit test):

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:firstDish];
RestaurantDish *retrievedDish = [NSKeyedUnarchiver unarchiveObjectWithData:data];
assertThat(retrievedDish.name, is(dishName));   

The instance firstDish is just an entity Dish that represents a plate of food.

Rob
  • 11,446
  • 7
  • 39
  • 57
  • Am I implementing the NSCoding protocol incorrectly (In the above gist)? I have both the initWithCoder and encodeWithCoder but perhaps they are wrong – Nader Hendawi Feb 05 '13 at 03:33
  • Your custom object in the dictionary should be conforms to `NSCoding Protocol` – Anil Varghese Feb 05 '13 at 03:37
  • I think it is? Implemented its two functions and added the in the header file. The Gist: https://gist.github.com/naderhen/4711899 – Nader Hendawi Feb 05 '13 at 03:40
  • Your implementation looks ok, but I don't think you should have to be diddling the tree nodes in the archiver, looking at some of my own code…. – Rob Feb 05 '13 at 03:46
  • Do you mean use just "encodeObject" and "decodeObject" respectively. without the forKey: param? Also do you have a link to some relevant code? – Nader Hendawi Feb 05 '13 at 03:50
  • Edited my answer. Maybe this helps? – Rob Feb 05 '13 at 03:50
  • I've tried the following and it still seems to break on the "unarchiveObjectWithData" method. The archiving appears to work fine: https://gist.github.com/naderhen/4712026 – Nader Hendawi Feb 05 '13 at 03:55
  • 1
    You are not encoding the objects. You should put log statements in your encode/initWithCoder. For sure they are not getting called. – Rob Feb 05 '13 at 04:11