Re: NSUnarchiver / Data.archive Extract all Keys
Re: NSUnarchiver / Data.archive Extract all Keys
- Subject: Re: NSUnarchiver / Data.archive Extract all Keys
- From: Roland King <email@hidden>
- Date: Sat, 11 Dec 2010 19:00:27 +0800
that's a binary plist file representing a keyed archive, you should be able to open it with plist but for some reason when I do that I don't get one of the entries I expected (the $top dictionary is empty instead of having a 'root' key in it), and I like looking at files in vi anyway so .. I converted the one you mailed me to xml
plutil -convert xml1 -e xml Data.archive
gives you Data.xml which you can look at or again open in plist
I took a a look at that and found only a couple of custom classes so I figured with a bit of messing about we should be able to unarchive it. So I started a new command line project and put this simple bit of code in it
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ];
id MyObject = [ NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/rols/Downloads/Data.archive" ];
NSLog( @"MyObject: %@", MyObject );
[pool drain];
return 0;
}
Run that (change the path to your file) and it will instantly fail because it wants to decode a YHACPlugin .. which doesn't exist.
if you look at that xml plist file you'll see an entry for $top.root.CF$UID which is '1'. That means that the top level object it wants to archive is 'Item 1' in the list. You can see it's of class type 'Item 123' and has 4 more keys, cells, footer, header and settings. Looking at Item 123 that's the name of the class YHACPlugin. So it looks to me there that YHACPlugin is an object which uses keyed archiving and has 4 keys, so we'll create a little stub file which just unarchives it. You can be diligent and look through the XML to see what classes each of those keys are but I'm going to be lazy and use id and the modern runtime can synth the properties for me
@interface YHACPlugin : NSObject <NSCoding>
{
}
@property( readwrite, retain ) id cells;
@property( readwrite, retain ) id header;
@property( readwrite, retain ) id footer;
@property( readwrite, retain ) id settings;
@end
and the .m file (leaving out the dealloc method which is obvious),
@synthesize header, footer, cells, settings;
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [ super init ];
cells = [ [ aDecoder decodeObjectForKey:@"cells" ] retain ];
footer = [ [ aDecoder decodeObjectForKey:@"footer" ] retain ];
header = [ [ aDecoder decodeObjectForKey:@"header" ] retain ];
settings = [ [ aDecoder decodeObjectForKey:@"settings" ] retain ];
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
// unimplemented
}
Now run that again and it will fail trying to decode an object of type YHACCell, good, we're getting somewhere. I looked in the XML again to see what that object looked like. The class definition appears to be Item 21 and the data it's decoding is Item 3. That only has one key and the key is $0 . I thought about that a bit and decided that probably meant someone had used non-keyed archiving on it, so use non-keyed unarchiving to try and restore that one, here's the code trimmed
@interface YHACCell : NSObject <NSCoding>
{
}
@property( readwrite, retain ) id mysteryValue;
@end
@implementation YHACCell
@synthesize mysteryValue;
-(id)initWithCoder:(NSCoder *)aDecoder
{
mysteryValue = [ [ aDecoder decodeObject ] retain ]; // <- non=keyed decoding
return self;
}
Now run that and you get all the way to an error message that NSParagraphStyle can't be unarchived. That confused me for a while until I realized NSParagraphStyle is in AppKit and that framework isn't linked into a console app, so I added the framework to the link stage and the code ran to the end. Sticking a debug on [ pool drain ] you can go inspect the object you just made.
po [ MyObject settings ]
gave a nice load of data, as does
po [ [ [ MyObject cells ] objectAtIndex:0 ] mysteryValue ]
The one you gave me was pretty simple and didn't have any values for header or footer so there may be more objects you may have to stub out.
So at the end you have a YHACPlugin object which is just a shell with data in it, that you need to then convert to whatever new object you really want and rearchive it.
_______________________________________________
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