I use keyed coding with defaults to solve this issue, keys never change meaning after definition, app should ignore non-recognised keys and missing keys are defaulted or inferred from existing ones.
On Sep 1, 2013, at 23:07, Marcel Weiher <marcel.wei...@gmail.com> wrote: > Hi Graham, > > thanks for sharing your experience, that’s really helpful! > > On Sep 1, 2013, at 11:54 , Graham Cox <graham....@bigpond.com> wrote: >> On 31/08/2013, at 6:48 PM, Marcel Weiher <marcel.wei...@gmail.com> 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 (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/xcvista%40me.com > > This email sent to xcvi...@me.com _______________________________________________ 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