On Aug 28, 2013, at 4:53 PM, Marcel Weiher <marcel.wei...@gmail.com> wrote:
> does anyone have practical experience with the forward/backward compatibility 
> aspect of keyed archiving?  That is define a file format using keyed 
> archiving where backward and forward compatibility was both desirable and 
> achieved?


Hi,

 I've written code that was supposed to be future-safe with NSKeyedArchiver, 
and I've written raw binary file access code that was future-safe, but the 
archiver code I wrote hasn't actually been tested in practice AFAIK (i.e. I 
never got to see incompatible changes being made). So while I can give you the 
practice of writing the code, I can't actually confirm that it's bug-free.

 FWIW, it's usually fairly simple: You can add new fields with new keys without 
any extra effort, the old version will just ignore them. The new version's 
-initWithCoder: just has to be written to cope with these fields not being 
there, and in that case create a default object/assign a default value. 
encodeWithCoder: doesn't have to know about this, since you've initialized all 
the ivars with defaults, it can just write the newest version.

 If that for some reason isn't an option, you can simply write out a version 
number for each object in encodeWithCoder (just an int with 1 is fine for 
starters). In initWithCoder:, if the int isn't there or is 0, you assume it's 
the old format, if it is 1, you know it's the new format and read the new keys. 
If you want to be really future-safe, you also define that e.g. the bottom 16 
bits of the int are the minor revision, and the top 16 bits the newer one. If 
the minor version changes, that means you can read the file, you just won't get 
all the data (i.e. you increment the minor version when a change is a 
compatible change) while if the major version changes, you have a new file the 
old version of the app can't read.

 If you did your own binary writing code, you'd probably only need one version 
for the entire file. However, keyed archiving is encapsulated, per-object. You 
can have objects from various frameworks, each of which can change 
independently. This is a good, clean design, but means you need to save the 
version again for each class. There's no way around that either, as you don't 
really get a guarantee which object gets de-serialized first, so unless you 
write the version number to the file manually, then write the serialized object 
NSData after it, you have no way of reading the version number separately from 
the other objects to decide whether you can read the file.

 But you have a clean, compartmentalized OO design that automatically copes 
with individual objects being modified.

 Note that every class has a version (+setVersion: and +version) that you can 
use to store the current version number. You still have to write it out, but 
the neat thing is your comparison code can initially just compare and write out 
that current version for every class, and only when it actually changes, you 
hard-code a particular number different from 0.

 You can't really use keyed archivers if you want to be able to open and save 
the new file format with an old version. For one, you can't preserve the data 
that the old version doesn't know what to do with. You can't anticipate what to 
keep around (e.g. if you add an index, edit the file in the old version, but 
carry over the index unchanged, it'll be out of date, leading to wrong search 
results at best, crashes at worst). In this case I'd recommend you actually 
build a plist representation, and decide on some convention or separation that 
makes it easy to determine what can be kept around, and what needs to be 
deleted because the old version can't keep it in sync. Either a way of naming 
the keys, or a compatible/incompatible version number scheme like above, maybe 
again per object. Also, if you add a new class, the old application won't be 
able to de-serialize it from a keyed archiver. However, keyed archivers work if 
you only need to be able to open files created by the old version in a new 
version of the app.

Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to