Re: More Problems with archiving.
Re: More Problems with archiving.
- Subject: Re: More Problems with archiving.
- From: David Spooner <email@hidden>
- Date: Wed, 05 Dec 2007 07:29:09 -0700
You haven't shown the code which invokes the archiver, but I'm
guessing you are archiving the document; that would be inconsistent
with your method of unarchiving. I would expect to see something
like the following...
- (NSData *) dataOfType:(NSString *)typeName error:(NSError **)outError
{
NSDictionary *saveDict
= [NSDictionary dictionaryWithObjectsAndKeys:
projectDict, @"ProjectDict",
...
nil];
return [NSKeyedArchiver archivedDataWithRootObject:saveDict];
}
- (BOOL) readFromData:(NSData *)data ofType:(NSString *)typeName
error:(NSError **)outError
{
NSDictionary *saveDict = [NSKeyedUnarchiver
unarchiveObjectWithData:data];
projectDict = [[NSMutableDictionary alloc] initWithDictionary:
[saveDict objectForKey:@"ProjectDict"]];
...
}
As Ricky said, you should be able to use a single archiver/unarchiver
to encode/decode all relevant objects.
Note also that mutability of dictionaries and arrays is preserved
through archiving, so you needn't create mutable copies on unarchiving.
dave
On 4-Dec-07, at 5:03 PM, Development wrote:
On Dec 4, 2007, at 4:47 PM, Ricky Sharp wrote:
On Dec 4, 2007, at 5:10 PM, Development wrote:
I cannot seem to make keyed archiving work and I dont know why.
For the outline view I use a simple leaf node structure. I am
trying to archive and then retrieve that structure so in the
nodeitem object I've implemented NSCoding and am encoding it as
follows:
-(void)encodeWithCoder:(NSCoder*)coder
{
NSLog(@"Encoding root item: %@",self);
[coder encodeObject:itemParent forKey:@"ItemParent"];
[coder encodeObject:itemName forKey:@"ItemName"];
[coder encodeObject:itemType forKey:@"ItemType"];
[coder encodeObject:children forKey:@"ItemChildren"];
[coder encodeObject:itemProperties forKey:@"ItemProperties"];
[coder encodeObject:itemPath forKey:@"ItemPath"];
[coder encodeObject:itemNote forKey:@"ItemNote"];
[coder encodeBool:isGroup forKey:@"Expandable"];
}
I'm going to assume that all your attributes (objects) conform to
NSCoding. Having said that, I'm also going to assume that
children is an ivar of type NSArray that will contain other
nodeitem objects?
Are you only calling this method directly for the top root node?
Yes only on the top node. it automatically calls it for the
children, I see this via the NSLogs I have.
And yes all the things I want to archive have <NSCoding> in the
header and implement initWithCoder/encodeWithCoder, neither of
which is called automatically it would appear.
I can see when the file is created that this encoding method is
in fact being called. And when I look in the data file I can see
all the keys there.
However when I attempt to retrieve the data, no matter how I do
it, it's null. In the NSDocument subclass that I use to hold the
information about this structure is have implemented:
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName
error:(NSError **)outError
{
if([typeName isEqualTo:@"My Project"]){
NSLog(@"Opening a project File");
NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
projectDict = [[NSMutableDictionary alloc]initWithDictionary:
[[unarchiver decodeObjectForKey:@"ProjectDict"]retain]];
projectStruct = [[NSMutableArray alloc]initWithArray:
[[unarchiver decodeObjectForKey:@"ProjectStruct"]retain]];
NSData * nodeData = [[unarchiver decodeObjectForKey:@"RootNode"]
retain];
NSKeyedUnarchiver * newArch = [[NSKeyedUnarchiver alloc]
initForReadingWithData:nodeData];
//I get an error here that the data object is empty.
_root = [[NodeItem alloc]initWithCoder:newArch];
NSLog(@"unarchived: %@, %@, %@",_root,projectDict,projectStruct);
//Here an empty array and empty dictionary print and where it
should print the root's name it prints null.
//I have also tried a straight _root = [[unarchiver
decodeObjectForKey:@"RootNode"]retain]
return YES;
}
return NO;
}
The dictionary and array that I encode when creating the project
file appear to decode correctly however the NSObject subclass
that is the NodeItem just come out null and I cannot seem to find
any possible way to get it to actually read the information.
Finally when the actual document is encoded for writing this is
what is called":
-(void)encodeWithCoder:(NSCoder*)coder
{
NSLog(@"CAlling encode with coder %@",coder);
[coder encodeObject:projectDict forKey:@"ProjectDict"];
[coder encodeObject:projectStruct forKey:@"ProjectStruct"];
NSData * nodes = [NSKeyedArchiver
archivedDataWithRootObject:_root];
// I've also tried this with a flat [coder encodeObject:_root
forKey:@"RootNode"];
NSLog(@"Encoding Data: %@",nodes);
[coder encodeObject:nodes forKey:@"RootNode"];
NSLog(@"Reached end of encode");
}
I think it would be best to use just a single call to encode/
decode your entire object structure. In one of my products, I
have a classroom object (singleton) that serves as the root
object. I then just archive/unarchive that. In turn, it contains
dictionaries of arrays/dictionaries/objects that goes pretty
deep. But at the end of the day, I end up with a fully rebuilt
object structure.
See the APIs: NSKeyedUnarchiver's unarchiveObjectWithFile: and
archiveRootObject:toFile: Also look at their NSData equivalents.
I'm only writing because it's obvious to me that I did not
understand a single word of what I read in these references, in my
books or in the header files.
As an Update to this information. I have added data to the array
and the dictionary and they are not working either. I encode the
information as all the examples say I am suppose to, or at least my
understanding of it, and nothing is retrievable. Like I said I can
see all the information in the file, all the keys etc but for
whatever reason when I attempt to recall it nothing comes back.
___________________________________________________________
Ricky A. Sharp mailto:email@hidden
Instant Interactive(tm) http://www.instantinteractive.com
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
40conversionworks.com
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden