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]

Reply via email to