Unarchiving SKSpriteNode corrupts the SKTexture of a sprite in iOS 7.1, otherwise

I am using a NSKeyedArchiver

zip file NSMutableDictionary

that contains a NSMutableArray

subclass of SKSpriteNode

s. Its a card game in which I save the game stats and then an array of game related sprites.

The archive works very well. I also implement - (id)initWithCoder:(NSCoder *)aDecoder

and - (void)encodeWithCoder:(NSCoder *)aCoder

in my subclass SKSpriteNode

to make sure all properties, including the sprite texture, are archive-encoded.

The problem is when I unlock the game data. In my iOS 8 NSMutableArray

of SKSpriteNode

unpacked just fine and is added back into the game with their textures and qualities in tact.

However, in iOS 7.1 everything is unpacked except for the node texture. Instead, I get the error: SKTexture: Error loading image resource: "MissingResource.png"

and my sprites have a big red X instead of their textures.

Here's my code:

Archive:

- (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 encoding

- (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"];
}

      

NSLog()

in method - (id)initWithCoder:(NSCoder *)aDecoder

prints correct SKTexture in iOS 8 and prints SKTexture Missing Image in iOS 7.

Thoughts?

+3


source to share


1 answer


Following on from my own question, I decided instead to save the game state to [NSUserDefaults standardUserDefaults]

and [NSUbiquitousKeyValueStore defaultStore]

for iCloud. I now save an NSMutableArray

of NSMutableDictionary

representing my map's attributes in the user's defaults, and then I restore my sprites from those values ​​when it comes time to revive the saved game.



Everything works as it does now.

+1


source







All Articles