Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to conditionally use a new Cocoa API

In 10.6 Apple added +[NSPropertyListSerialization dataWithPropertyList:format:options:error:] and labeled the older +[NSPropertyListSerialization dataFromPropertyList:format:errorDescription:] as obsolete and soon to be deprecated. One way to use the newer call on 10.6 and above, and still run on earlier OS releases, would be something like this:

if ([NSPropertyListSerialization respondsToSelector:@selector(dataWithPropertyList:format:options:error:)]) {
    data = [NSPropertyListSerialization dataWithPropertyList:dict
                                                      format:NSPropertyListXMLFormat_v1_0
                                                     options:0
                                                       error:&err];
} else {
    data = [NSPropertyListSerialization dataFromPropertyList:dict
                                                      format:NSPropertyListXMLFormat_v1_0
                                            errorDescription:&errorDescription];        
}

Built against the 10.4 SDK (for compatibility with that release), this results in: warning: 'NSPropertyListSerialization' may not respond to '+dataWithPropertyList:format:options:error:' And, worse, since the compiler does not know about this selector, it may pass the arguments incorrectly.

Is NSInvocation the approved/best way to call new APIs that, as far as the SDK is concerned, don't yet exist?

like image 443
Jim Matthews Avatar asked Feb 28 '23 01:02

Jim Matthews


2 Answers

IIRC, you want to use the 10.6 SDK and set your deployment target (MACOSX_DEPLOYMENT_TARGET) to 10.4 so the 10.5/10.6 symbols are weak-linked. Then you can use the respondsToSelector: stuff and not get warnings.

Make sure you're checking that the object can respond to the selector, of course, or you will crash on 10.4/10.5.

like image 123
Wevah Avatar answered Mar 08 '23 15:03

Wevah


One other way of doing things is to declare the missing method yourself as a category of the class in question. This will get the compiler to stop complaining about not finding the method, though of course you'll still need the runtime check you're already doing to avoid actually calling the method. You might also want to wrap such a declaration using availability macros, so that it will be ignored once you do move up to using the 10.5/10.6 SDK and you won't get a different compiler complaint down the line. That would look something like this:

#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 //ignore when compiling with the 10.5 SDK or higher
@interface NSPropertyListSerialization(MissingMethods)

+ (NSData *)dataWithPropertyList:(id)plist format:(NSPropertyListFormat)format options:(NSPropertyListWriteOptions)opt error:(NSError **)error;

@end
#endif
like image 36
Brian Webster Avatar answered Mar 08 '23 16:03

Brian Webster