2
votes

Im having issues with NSKeyedArchiver. I'm trying to archive a dictionary, which in turn contains arrays of custom objects, Album and Song.

Album and Song both inherent from NSObject and and conform to the NSCoding protocol. Here is how ive implemented the protocol:

Album implementation file:

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];

    self.title = [aDecoder decodeObjectForKey:@"title"];
    self.artistName = [aDecoder decodeObjectForKey:@"artistName"];
    self.songs = [aDecoder decodeObjectForKey:@"songs"];

    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.title forKey:@"title"];
    [aCoder encodeObject:self.artistName forKey:@"artistName"];
    [aCoder encodeObject:self.songs forKey:@"songs"];
}

Song Implementation file:

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    self.title = [aDecoder decodeObjectForKey:@"title"];
    self.artistName = [aDecoder decodeObjectForKey:@"artistName"];

    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.title forKey:@"title"];
    [aCoder encodeObject:self.artistName forKey:@"artistName"];
}

title and artistName properties are both NSStrings, white the songs property is an array of Song objects.

I place arrays of these objects into a dictionary called ipodDictForArchiving, then archive the dictionary like so:

-(NSData *)dataForClient {
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:[self ipodDictForArchiving] forKey:kDataArchive];
    [archiver finishEncoding];
    NSLog(@"encoded dictionary");
    return data;
}

I then unarchive the dictionary like this:

-(NSDictionary *)unarchiveData:(NSData *)data {
    NSData *clientData = data;
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:clientData];
    NSDictionary *myDictionary = [unarchiver decodeObjectForKey:kDataArchive];
    [unarchiver finishDecoding];

    return myDictionary;
}

For some reason, dictionary contains the Song and Album objects, but those objects return null for their properties. I can't figure this out any help greatly appreciated!!

Thanks

1
Did you ever find a solution for this problem? - Supertecnoboff

1 Answers

-1
votes

The way you implement initWithCoder is incorrect, should as below:

- (id)initWithCoder:(NSCoder *)aDecoder {

    Album *al = [[Album alloc] init];

    al.title = [[[NSString alloc] initWithString:[aDecoder decodeObjectForKey:@"title"]] autorelease];
    al.artistName = [[[NSString alloc] init] initWithString:[aDecoder decodeObjectForKey:@"artistName"]] autorelease];
    al.songs = [[[NSArray alloc] initWithArray:[aDecoder decodeObjectForKey:@"songs"]] autorelease];

    return al;
}

The same for Song.

[Edit] And the way you archive the album seems incorrect, let try a simpler way:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:album];

Then you can save this data to unarchive it later.