4

How can I perform a run-time check to see if I can use UIGraphicsBeginImageContextWithOptions, which is only available starting with iOS 4.

I know I could check [[UIDevice currentDevice] systemVersion], but Apple recommends using things like NSClassFromString() or respondsToSelector:. Is there a respondsToSelector: for C functions?

ma11hew28
  • 121,420
  • 116
  • 450
  • 651

3 Answers3

10

Here's another option, which I've been using.

C functions are pointers. If you "weak" link to UIKit framework, on iOS 3 the function pointer will simply be NULL, so you can test for the existence of the function by doing:

if (UIGraphicsBeginImageContextWithOptions)
{
    // On iOS 4+, use the main screen's native scale factor (for iPhone 4).
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
}
else
{
    UIGraphicsBeginImageContext(size);
}

See also: How do I weak link frameworks on Xcode 4?

Community
  • 1
  • 1
Daniel Dickison
  • 21,832
  • 13
  • 69
  • 89
1

What you're probably interested in here is weak linking. (See "Listing 3-2: Checking the availability of a C function".)

-2

This is what I'm going with:

if ([mainScreen respondsToSelector:@selector(scale)]) {
    UIGraphicsBeginImageContextWithOptions(newSize, NO, [[UIScreen mainScreen] scale]);
} else {
    UIGraphicsBeginImageContext(newSize);
}

I think this is good enough, but if you have any better suggestions, please answer.

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 2
    That scale call exists on iOS 3.2, which had a "scale" method that was not documented... so "respondsToSelector" will work, but the UIGraphicsBeginImageContextWithOptions call is only available from iOS 4.0 onward. Thus it would crash on the original non-upgraded iPad. I would use Daniels check, you should always check for the exact call you are about to make and not rely on "pairings" of call checking like this. – Kendall Helmstetter Gelner Jul 08 '11 at 17:54