views:

319

answers:

2

I'm working on an iOS app. It currently only works on iOS 4 since I use the following method on several occasions: "UIGraphicsBeginImageContextWithOptions". This method is only available in iOS 4 and therefor my app currently crashes/doesn't work on iPhone OS 3. Aside from this method there is no reason why the app should not work on iPhone OS 3. How do I make a check to see wether or not this method is available ? I've tried the following without succes:

if([self respondsToSelector:@selector(UIGraphicsBeginImageContextWithOptions)]) {
    UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0); // this will crop
}
else 
{
    UIGraphicsBeginImageContext(targetSize);

}

I'f only tried variations like this:

if([self respondsToSelector:@selector(UIGraphicsBeginImageContextWithOptions:size:opaque:scale:)])

and

if([self respondsToSelector:@selector(UIGraphicsBeginImageContextWithOptions:)])

Without succes. Any help would be appreciated.

+4  A: 

UIGraphicsBeginImageContextWithOptions is a C function, so you can't use Objective-C methods like -respondsToSelector: to test its existence.

You could, however, weak link the UIKit framework, and then check if UIGraphicsBeginImageContextWithOptions is NULL:

if (UIGraphicsBeginImageContextWithOptions != NULL) {
   UIGraphicsBeginImageContextWithOptions(...);
} else {
   UIGraphicsBeginImageContext(...);
}
KennyTM
Thanks, are you sure I need to weaklink UIKit though ?
Gidogeek
@Gido: No. You could use `dlsym`. But weak link is easiest.
KennyTM
I weaklinked the UIKit framework and entered the code as you show it here. However on an iPhone running OS 3.0 it still manages to go through the IF statement instead of ending up in the else..
Gidogeek
No other suggestions ?
Gidogeek
The code currently looks like this: http://dl.dropbox.com/u/610806/backwardscompatability.pngThe code however ends up in the NSLog line on a iPhone 3G running 3.1.3 which does not have this method. What could I be doing wrong ?
Gidogeek
@Gigo: Try `NSLog(@"%p", UIGraphicsBeginImageContextWithOptions)`?
KennyTM
@KennyTM this prints out "0x0"
Gidogeek
@Gidogeek: Odd, then the `if` line shouldn't pass, since `0 != NULL` is false obviously.
KennyTM
@KennyTM that's what I figured.. but somehow it passes.. pulling out my hair over this.. what else could I try ?
Gidogeek
@Gido: Try casting UIGraphicsBeginImageContextWithOptions to `void*`?
KennyTM
@KennyTM sadly that didn't help either. Probably I should look for the problem elsewhere.. if all these people use it without trouble I should be doing something wrong in my setup. Probably something basic so I'll list some of the properties in my plist for my build target:* Base SDK: iPhone Device 4.0* C/C++ Compiler: LLVM compiler 1.5* iPhone OS Deployment Target: iPhone OS 3.1.3I have the before mentioned code in a category like so:@interface UIImage (Resizing)//the methods containing the version specific code@endCould this be cause of the problem ?
Gidogeek
@Gido: Have you tried using GCC instead of LLVM?
KennyTM
@KennyTM switching the compiler to GCC 4.2 actually worked.. how silly is that ? is this a bug ? Thanks anyway !
Gidogeek
@Gido: Likely an optimizing-too-aggressively bug of LLVM. [Please file a bug report](http://llvm.org/docs/HowToSubmitABug.html).
KennyTM
This worked perfectly for me. Thanks
Daniel Wood
A: 

I have the same problem. You could try testing the system version. This seems to work for me on the devices I tested.

char majorVersion = [[[UIDevice currentDevice] systemVersion] characterAtIndex: 0];
if (majorVersion == '2' || majorVersion == '3')
     UIGraphicsBeginImageContext(...);
else
     UIGraphicsBeginImageContextWithOptions(...);
Eric