Hi Graham, thanks for sharing your experience, that’s really helpful!
On Sep 1, 2013, at 11:54 , Graham Cox <[email protected]> wrote: > On 31/08/2013, at 6:48 PM, Marcel Weiher <[email protected]> wrote: >> So you’ve had good practical experience with forward/backward compatible >> designs? > > Yes. > > But let me qualify it :) By 'backward compatible' I mean files created by an > earlier version of the app can be opened in a newer version, 'forward > compatible' means the inverse: newer files can be opened by an older version > of the app. :-) > Backward compatibility is much easier than forward compatibility, and > typically as the app evolves, that is what the primary focus is on, because > on the whole you expect people to upgrade your app to a newer version, but > they may have files created by the earlier version. Going in the other > direction is only important if users with a variety of versions of your app > share the files amongst each other - it's very rare for a single user to > downgrade to an earlier version of your app. Exactly my thoughts. When I was using old-style archiving, I only provided for backwards compatibility, and it was easy enough: read base version info if ( version >= x ) { read version x info if ( version >= y ) { read version y info ... } } Alternatively, if the changes are more incompatible: if ( version == x ) { read version x info; } else if ( version == y ) { read version y info; } ... The code is pretty straightforward in both cases, as you already have the old code and just add the new code. > So ensuring backward compatibility is something that is typically handled on > a class-by-class basis, where the -encodeWithCoder simply writes what data it > currently needs to, possibly with flags or versioning info so that the > corresponding -initWithCoder is able to know which particular items are of > interest. -initWithCoder: should also, as necessary, deal with older-format > items it encounters when handed an old file. Right. And if you want to preserve the ability to write older versions, just pass that info in and handle in a way that’s similar to the reading case. > Going the other way requires more cunning, and usually needs some support > from version 1.0 of your app. I mentioned using a keyed unarchiver delegate - > one way that can be used is to handle entire classes that the older app > doesn't know about. It can substitute something else, perhaps the nearest > superclass, or a placeholder so that newer files can be opened with reduced > functionality. This can also help with backward compatibility, for example by > translating older classnames to newer ones if you ever change them (that > sounds unlikely, but it did happen in one product I developed due to a client > insisting on changing a whole bunch of classnames after version 1.0). OK. Substituting classes does work in NSUnarchiver, but you can’t then easily ignore > Newer versions can also provide alternate objects which cover the > functionality present in the older apps, even if it's just a way to > communicate to the user that they ought to upgrade. Example: a newer version > of an app wrote out image data differently from an earlier version (which > fell into the classic trap of archiving an NSImage object), but the newer app > also archived a placeholder NSImage which included the text "version xxx is > required to view this image", so that opening the newer file in an old app at > least gave the user the hint. In that case it would have been possible to > include image data in both formats, but we preferred to encourage the user to > upgrade. The newer app could dearchive an old file's NSImage and convert it > without a problem so a subsequent save would promote the file to the newer > format. To achieve something like this with NSArchiver would definitely require more work and forethought, such as an extension “blob” that can optionally be unarchived separately. > > That's as far as I've ever gone on forward compatibility. If you need > something more robust than that I'm sure it can be done. As you said, some > externally defined format helps a lot but the convenience and flexibility of > keyed archiving is very attractive. Well, archiving in general is pretty convenient, I am just trying to figure out how significant the benefits of keyed archiving are in particular (as compared to, for example, old style archiving). If you’re on iOS you don’t have a choice, but otherwise it seems the benefits are fairly slim, considering the 2-4x performance penalty. Thanks again! Marcel _______________________________________________ Cocoa-dev mailing list ([email protected]) 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 [email protected]
