I knew I would get into trouble doing this the "hard way"

And I did!
Anyways, for exercise 19.4 I want to archive an addressbook with some cards. So I added encoding and decoding methods to AddressCard.h/m and AddressBook.h/.m. For the AddressBook it is a piece of pie since its just as illustrated earlier in the chapter. But for AddressBook I wanted to use my version where I use a mutable dictionary of cardFields instead of variables like in the chapter. And here I knew I would run into problem

Anyways, I get my program to archive data fine. But decoding them I just get (null) back. And if I replace the return cardFields; with return self; in the initWithCoder: method my AddressBook list: method crashes.
I tried to change the encode and decode methods into a for-loop to archive/unarchive all the cardFields data. Both archive (I had a peek in the addrbook.arch file). But neither unarchive anything.
The decode method with a for-loop doesnt even run the for-loop...
Here is my AddressCard.m. Attached below is the complete project with all sources. I think I am missing something obvious, but cant quite see what it is....
//
// AddressCard.m
// Oppgave 19.4 side 452
//
// Created by Odd-Jarle Kristoffersen on 12.11.09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "AddressCard.h"
@implementation AddressCard
@synthesize cardFields;
// We need an initiator that takes all our arguments to set up an address card
-(void) initWithFirstName: (NSString *) theFirstName
andLastName: (NSString *) theLastName
andAddress: (NSString *) theAddress
andPostNummer: (NSString *) thePostNummer
andPostSted: (NSString *) thePostSted
andLand: (NSString *) theLand
andEmail: (NSString *) theEmail
andTelefon: (NSString *) theTelefon
andMobil: (NSString *) theMobil
{
self = [super init];
// If we could init ourself,
// define which fields each addresscard has
if (self) {
cardFields = [[NSMutableDictionary alloc] init];
[cardFields setObject: theFirstName forKey: @"firstName"];
[cardFields setObject: theLastName forKey: @"lastName"];
[cardFields setObject: theAddress forKey: @"address"];
[cardFields setObject: thePostNummer forKey: @"postNummer"];
[cardFields setObject: thePostSted forKey: @"postSted"];
[cardFields setObject: theLand forKey: @"land"];
[cardFields setObject: theEmail forKey: @"email"];
[cardFields setObject: theTelefon forKey: @"telefon"];
[cardFields setObject: theMobil forKey: @"mobil"];
}
}
// Synthesize getter/setters for all cardFields
-(NSMutableDictionary *) cardFields {
return cardFields;
}
// Method to print an addresscard
-(void) print
{
// We need a couple of length integers and a counter integer
int i, flengde, elengde = 0;
// theCard.firstname now has to be accessed [cardFields objectForKey: @"firstName"]
// Allow foreign chars by creating new NSStrings for output
NSString *fornavn = [NSMutableString stringWithString: [cardFields objectForKey: @"firstName"]];
// We want to add spaces to these string to pad up for nice display
// so we need a NSMutableString for them
NSMutableString *etternavn = [NSMutableString stringWithString: [cardFields objectForKey: @"lastName"]];
NSMutableString *adresse = [NSMutableString stringWithString: [cardFields objectForKey: @"address"]];
NSMutableString *poststed = [NSMutableString stringWithString: [cardFields objectForKey: @"postSted"]];
NSMutableString *landet = [NSMutableString stringWithString: [cardFields objectForKey: @"land"]];
// Email doesnt require "treatment" since it can only contain regular US chars
// Find length of the entire name
flengde = [fornavn length];
elengde = [etternavn length];
// Pad ending with spaces until we reach 30 chars to get nice output
for (i = flengde + elengde; i < 30; i++)
[etternavn appendString: @" "];
// Find length of address
flengde = [adresse length];
// Pad ending with spaces until we reach 30 chars to get nice output
for (i = flengde; i < 31; i++)
[adresse appendString: @" "];
// Find length of entire zip / city output
flengde = [[cardFields objectForKey: @"postNummer"] length];
elengde = [poststed length];
// Pad ending with spaces until we reach 30 chars to get nice output
for (i = flengde + elengde; i < 30; i++)
[poststed appendString: @" "];
// Find length of country
flengde = [landet length];
// Pad ending with spaces until we reach 30 chars to get nice output
for (i = flengde; i < 31; i++)
[landet appendString: @" "];
// Use %@ instead of %s to display our new local strings, except for email
NSLog(@"====================================");
NSLog(@"| %@ %@ |", fornavn, etternavn);
NSLog(@"| %@ |", adresse);
NSLog(@"| %@ %@ |", [cardFields objectForKey: @"postNummer"], poststed);
NSLog(@"| %@ |", landet);
NSLog(@"| %-31s |", [[cardFields objectForKey: @"email"] UTF8String]);
NSLog(@"| %-31s |", [[cardFields objectForKey: @"telefon"] UTF8String]);
NSLog(@"| %-31s |", [[cardFields objectForKey: @"mobil"] UTF8String]);
NSLog(@"====================================");
}
// We need to release our cardFields memory when we are done
-(void) dealloc
{
[cardFields release];
[super dealloc];
}
// Methods to encode/decode archive
-(void) encodeWithCoder: (NSCoder *) encoder
{
for ( NSString *key in cardFields ) {
// NSLog(@"%@ %@", key, [cardFields objectForKey: key]);
[encoder encodeObject: [cardFields objectForKey: key] forKey: key];
}
/*
[encoder encodeObject: [cardFields objectForKey: @"firstname"] forKey: @"firstname"];
[encoder encodeObject: [cardFields objectForKey: @"lastname"] forKey: @"lastname"];
[encoder encodeObject: [cardFields objectForKey: @"address"] forKey: @"address"];
[encoder encodeObject: [cardFields objectForKey: @"postNummer"] forKey: @"postNummer"];
[encoder encodeObject: [cardFields objectForKey: @"postSted"] forKey: @"postSted"];
[encoder encodeObject: [cardFields objectForKey: @"land"] forKey: @"land"];
[encoder encodeObject: [cardFields objectForKey: @"email"] forKey: @"email"];
[encoder encodeObject: [cardFields objectForKey: @"telefon"] forKey: @"telefon"];
[encoder encodeObject: [cardFields objectForKey: @"mobil"] forKey: @"mobil"];
*/
}
-(id) initWithCoder: (NSCoder *) decoder
{
NSLog(@"decoding...");
for ( NSString *key in cardFields ) {
NSLog(@"%@ %@", [decoder decodeObjectForKey: key], key);
[cardFields setObject: [decoder decodeObjectForKey: key] forKey: key];
}
NSLog(@"%@", [decoder decodeObjectForKey: @"firstname"]);
/*
[cardFields setObject: [decoder decodeObjectForKey: @"firstname"] forKey: @"firstname"];
[cardFields setObject: [decoder decodeObjectForKey: @"lastname"] forKey: @"lastName"];
[cardFields setObject: [decoder decodeObjectForKey: @"address"] forKey: @"address"];
[cardFields setObject: [decoder decodeObjectForKey: @"postNummer"] forKey: @"postNummer"];
[cardFields setObject: [decoder decodeObjectForKey: @"postSted"] forKey: @"postSted"];
[cardFields setObject: [decoder decodeObjectForKey: @"land"] forKey: @"land"];
[cardFields setObject: [decoder decodeObjectForKey: @"email"] forKey: @"email"];
[cardFields setObject: [decoder decodeObjectForKey: @"telefon"] forKey: @"telefon"];
[cardFields setObject: [decoder decodeObjectForKey: @"mobil"] forKey: @"mobil"];
*/
return cardFields;
}
@end