Detecting the Operating System Version

Discussion in 'Mac Programming' started by Spike099, Sep 3, 2009.

  1. Spike099 macrumors regular

    Joined:
    Feb 18, 2007
    Location:
    Canada
    #1
    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.
     
  2. Spike099 thread starter macrumors regular

    Joined:
    Feb 18, 2007
    Location:
    Canada
    #2
    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];
    }
    
    
     
  3. wrldwzrd89 macrumors G5

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #3
    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.
     
  4. MacRumors Guy macrumors member

    Joined:
    Sep 17, 2008
    #4
    You could use diferente files + a make file rule to make builds for each OS.
     
  5. MrFusion macrumors 6502a

    Joined:
    Jun 8, 2005
    Location:
    West-Europe
    #5
    Code:
    ...
     else {
     NSLog(@"Time for another upgrade, this method too has been deprecated.");
    }
    
     
  6. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #6
    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.
     
  7. autorelease macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #7
    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.
     
  8. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #8
    You misread the code. We're comparing *to* the #define. NSAppKitVersionNumber is an extern global defined by AppKit.framework.
     
  9. Spike099 thread starter macrumors regular

    Joined:
    Feb 18, 2007
    Location:
    Canada
    #9
    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.
     

Share This Page