Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
Hello,

I've hit a small snag... I'm using the method

[(NSDate*)date addTimeInterval];

However, the addTimeInterval method is deprecated in 10.6... My app will remain compatible with 10.5, so I would like to use the suggested method: dateByAddingTimeInterval:.

So, how can I detect the operating system version and call the appropriate method? Oh and i'd like the suppress the warning too if this is possible...

Closest thing I saw was in NSProcessInfo operatingSystemVersionString, but it says "This string is not appropriate for parsing.".... Err.
 
Whoa, I was in for more than I thought... I've got it though, I think... Who thinks this will suffice?

So, basically, if whatever operating system this is been run on, it will use the new method if it is found.

Now, this presents another issue... I wont get a warning in 10.7 when dateByAddingTimeInterval: is deprecated(not saying that it will be). So, is this the way I should do this?

Code:
NSMethodSignature *signature;
NSInvocation *invocation;
NSDate *date = nil;
SEL selector1, selector2;
	
selector1 = @selector(dateByAddingTimeInterval:);
selector2 = @selector(addTimeInterval:);
		
if ( [[event startDate] respondsToSelector:selector1] ) {
	signature = [NSDate instanceMethodSignatureForSelector:selector1];
	invocation = [NSInvocation invocationWithMethodSignature:signature];
	[invocation setSelector:selector1];
	[invocation setTarget:[event startDate]];
	[invocation setArgument:&lastUsedIntermediateTimeInterval atIndex:2];
	[invocation invoke];
	[invocation getReturnValue:&date];
	[event setEndDate:date];
}
else if ( [[event startDate] respondsToSelector:selector2] ) {
	signature = [NSDate instanceMethodSignatureForSelector:selector2];
	invocation = [NSInvocation invocationWithMethodSignature:signature];
	[invocation setSelector:selector2];
	[invocation setTarget:[event startDate]];
	[invocation setArgument:&lastUsedIntermediateTimeInterval atIndex:2];
	[invocation invoke];
	[invocation getReturnValue:&date];
	[event setEndDate:date];
}
 
I like your approach - that seems like the right way to do things. Even if the deprecated method gets removed in 10.7 your code should still work, since it has a fallback.
 
Here's how Adium does it (this is in a category on NSApplication, so you can do [NSApp isOnSnowLeopardOrBetter]):

Code:
//Make sure the version number defines exist; when compiling in 10.5, NSAppKitVersionNumber10_5 isn't defined 
#ifndef NSAppKitVersionNumber10_5
#define NSAppKitVersionNumber10_5 949
#endif 

- (BOOL)isOnSnowLeopardOrBetter
{
	return (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5);
}

I would avoid the NSInvocation if I were you; that's a lot of code and runtime overhead just to avoid a warning.
 
Here's how Adium does it (this is in a category on NSApplication, so you can do [NSApp isOnSnowLeopardOrBetter]):

Code:
//Make sure the version number defines exist; when compiling in 10.5, NSAppKitVersionNumber10_5 isn't defined 
#ifndef NSAppKitVersionNumber10_5
#define NSAppKitVersionNumber10_5 949
#endif 

- (BOOL)isOnSnowLeopardOrBetter
{
	return (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5);
}

I would avoid the NSInvocation if I were you; that's a lot of code and runtime overhead just to avoid a warning.

That #define will get you the version number of the machine you're compiling on, not the version number of the machine running the program.
 
That #define will get you the version number of the machine you're compiling on, not the version number of the machine running the program.

You misread the code. We're comparing *to* the #define. NSAppKitVersionNumber is an extern global defined by AppKit.framework.
 
Cool!

Alright, i used your advice Catfish_Man and i've done a mix between mine and yours...

Code:
if ( [NSApp isOnSnowLeopardOrBetter] ) {
	[event setEndDate:[[event startDate] dateByAddingTimeInterval:lastUsedIntermediateTimeInterval]];
}
else if ( [[event startDate] respondsToSelector:selector] ) {
	NSMethodSignature *signature;
	NSInvocation *invocation;
	NSDate *date = nil;
			
	signature = [NSDate instanceMethodSignatureForSelector:selector];
	invocation = [NSInvocation invocationWithMethodSignature:signature];
	[invocation setSelector:selector];
	[invocation setTarget:[event startDate]];
	[invocation setArgument:&lastUsedIntermediateTimeInterval atIndex:2];
	[invocation invoke];
	[invocation getReturnValue:&date];
	[event setEndDate:date];
}

So, basically
1) it won't use all the code overhead when running 10.6.
2) Compiles on 10.6 and 10.5, (i'll get a warning when compiling in 10.5 but who cares as i will be compiling releases on 10.6)
3) only one build!

Cool, thx guys!

EDIT

Oh, and now ill get warnings in the future if dateByAddingTimeInterval is deprecated. Beauty.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.