I am using NSKeyedArchiver
to archive an NSMutableDictionary
that contains an NSMutableArray
of subclassed SKSpriteNode
s. Its a card game where i'm saving some game stats and then an array of sprites associated with the game.
Archival is working pretty well. I'm also implementing - (id)initWithCoder:(NSCoder *)aDecoder
and - (void)encodeWithCoder:(NSCoder *)aCoder
in my SKSpriteNode
subclass to make sure that all of the properties, including the sprite's texture, are coded through to the archive.
The problem is that when I unarchive this game data. In iOS 8, my NSMutableArray
of SKSpriteNode
s unpack just fine, and are added back to the game with their textures and properties in tact.
In iOS 7.1 however, everything unpacks except for the node's texture. Instead, I get the error: SKTexture: Error loading image resource: "MissingResource.png"
and my sprites have big red X's in place of their textures.
Here's my code:
Archival:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
SKView *view = (SKView *)self.window.rootViewController.view;
if( view.scene ) {
GameScene* game = (GameScene*)view.scene;
NSMutableDictionary* currentGame = [[NSMutableDictionary alloc] init];
// game stats
[currentGame setObject:[[Global getSharedInstance] undoStack] forKey:@"undoStack"];
[currentGame setObject:[NSNumber numberWithInt:game.hints] forKey:@"remainingHints"];
[currentGame setObject:[NSNumber numberWithInt:game.undos] forKey:@"remainingUndos"];
[currentGame setObject:[NSNumber numberWithInt:[[Global getSharedInstance] moves]] forKey:@"gameMoves"];
[currentGame setObject:[NSNumber numberWithInt:[[Global getSharedInstance] score]] forKey:@"gameScore"];
[currentGame setObject:[NSNumber numberWithInteger:[[Global getSharedInstance] elapsedTime]] forKey:@"elapsedTime"];
[currentGame setObject:[NSNumber numberWithInteger:[[Global getSharedInstance] minutes]] forKey:@"minutes"];
[currentGame setObject:[NSNumber numberWithInteger:[[Global getSharedInstance] startedTimeInterval]] forKey:@"startedTimeInterval"];
[currentGame setObject:[NSNumber numberWithInteger:[[Global getSharedInstance] elapsedPauseTime]] forKey:@"elapsedPauseTime"];
[currentGame setObject:[NSNumber numberWithInteger:[[Global getSharedInstance] lastPauseTime]] forKey:@"lastPauseTime"];
// here - game cards SKSpriteNodes
[currentGame setObject:game.cards forKey:@"cards"];
// encode to disk
NSData* encodedData = [NSKeyedArchiver archivedDataWithRootObject:currentGame];
[encodedData writeToFile:[Global gameDataFilePath] atomically:YES];
}
}
Sprite Coding
- (id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(@"%@",[aDecoder decodeObjectForKey:@"texture"]);
self = [super initWithTexture:[aDecoder decodeObjectForKey:@"texture"] color:[UIColor clearColor] size:CGSizeMake(106,156)];
if(self) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.theme = [aDecoder decodeObjectForKey:@"theme"];
self.suit = [aDecoder decodeObjectForKey:@"suit"];
self.value = [aDecoder decodeIntForKey:@"value"];
self.ID = [aDecoder decodeIntForKey:@"ID"];
self.locked = [aDecoder decodeBoolForKey:@"locked"];
self.faceUp = [aDecoder decodeBoolForKey:@"faceUp"];
self.black = [aDecoder decodeBoolForKey:@"black"];
self.dealCard = [aDecoder decodeBoolForKey:@"dealCard"];
self.highlighted = [aDecoder decodeBoolForKey:@"highlighted"];
self.highlightAction = [aDecoder decodeObjectForKey:@"highlightAction"];
self.inStackNode = [aDecoder decodeObjectForKey:@"inStackNode"];
self.shadowNode = [aDecoder decodeObjectForKey:@"shadowNode"];
self.highlightNode = [aDecoder decodeObjectForKey:@"highlightNode"];
self.zPosition = [aDecoder decodeFloatForKey:@"zPosition"];
[self addChild:self.shadowNode];
[self addChild:self.inStackNode];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.theme forKey:@"theme"];
[aCoder encodeObject:self.suit forKey:@"suit"];
[aCoder encodeInt:self.value forKey:@"value"];
[aCoder encodeInt:self.ID forKey:@"ID"];
[aCoder encodeBool:self.black forKey:@"black"];
[aCoder encodeBool:self.locked forKey:@"locked"];
[aCoder encodeBool:self.faceUp forKey:@"faceUp"];
[aCoder encodeBool:self.dealCard forKey:@"dealCard"];
[aCoder encodeBool:self.highlighted forKey:@"highlighted"];
[aCoder encodeObject:self.highlightAction forKey:@"highlightAction"];
[aCoder encodeObject:self.inStackNode forKey:@"inStackNode"];
[aCoder encodeObject:self.shadowNode forKey:@"shadowNode"];
[aCoder encodeObject:self.highlightNode forKey:@"highlightNode"];
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeFloat:self.xScale forKey:@"scale"];
[aCoder encodeFloat:self.zPosition forKey:@"zPosition"];
[aCoder encodeObject:self.texture forKey:@"texture"];
}
The NSLog()
in the - (id)initWithCoder:(NSCoder *)aDecoder
method prints the correct SKTexture in iOS 8, and prints the Missing Image SKTexture in iOS 7.
Thoughts?