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

Reply via email to