2

I have a problem with detecting retina displays on iOS devices. I'm using the following code which was recommended by various people:

BOOL isRetina()
{
    UIScreen* s = [UIScreen mainScreen];
    if ([s respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
        [s respondsToSelector:@selector(scale)])
    {
        CGFloat scale = [s scale];
        return scale == 2.0;
    }

    return NO;
}

The problem is that it compiles fine for deployment target iOS 4 and higher, but when I compile for iOS3.2 I get an "Incompatible types in initialization" error at the "scale = [s scale]" line because I'm trying to assign an id to a float. I couldn't find anything about that. Since everyone else seems to be using this approach I must be missing something really obvious here? Base SDK version is 4.3 with XCode 4 by the way.

Here are my BaseSDK/Deployment Target settings: SDK settings

Update: I've solved it. Basically the problem was some XCode issue. To fix some other problem I had to uninstall and reinstall XCode. After that the behavior was gone.

Gottfried
  • 155
  • 2
  • 11
  • And just casting the result to float doesn't work? (ie `CGFloat scale = (CGFloat)[s scale];`) – jv42 Apr 14 '11 at 14:09
  • No, you can't cast a pointer type to a float. I already tried that. Even tried to go via a void*. – Gottfried Apr 14 '11 at 14:34
  • Ah of course, as I was a little time away for ObjC, I forgot some of its inner details. Good luck! – jv42 Apr 14 '11 at 15:03

2 Answers2

1

In iOS 3.2, the symbol -[UIScreen scale] is not defined and thus the compiler assumes it returns id by default when you compile with iOS SDK 3.2. Hence the warning.

It's very important to understand the difference of SDK against which you compile and the deployment target. You generally want to compile against the latest SDK, but you set a deployment target of the minimum iOS version you want to support.

Community
  • 1
  • 1
DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • That's the funny thing, I already know that: My base SDK is set to 4.3. My deployment target is 3.2. But still when I select to build for e.g. iPad 3.2 simulator in XCode then I get this error. – Gottfried Apr 14 '11 at 14:26
  • 1
    @Gottfried: That's because in this case the Base SDK is set 3.2. – DarkDust Apr 14 '11 at 14:37
  • I've attached a screenshot of my Base SDK settings. They seem to be OK. – Gottfried Apr 14 '11 at 14:49
1

Here is the code I use that works as far back as 3.1 (I haven't tested earlier than that):

BOOL isRetina;
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2){
    isRetina = YES;
} else {
    isRetina = NO;
}

As pointed out by @DarkDust the problem isn't really your code (although the above should be simpler for you), it's that you are trying to compile for 3.2 and really you should just be setting your deployment target to 3.2 and still compiling using the latest SDK.

The difference is that when you compile for the older SDK it will fail to build because it knows it can't call that method (scale) - even though it won't actually get to that line of code. But if you have set your deployment target correctly, you can use your code on 3.2 and not worry because you know the scale method will never get called where it doesn't exist because you verified that it doesn't exist.

Community
  • 1
  • 1
theChrisKent
  • 15,029
  • 3
  • 61
  • 62
  • Please read my comment @DarkDust. Basically I realize that somehow Xcode is building using 3.2 as base sdk, but in my Xcode settings it says base sdk 4.3, deployment target 3.2. But I am sure that I'm missing something since after I switched to XCode 4 I'm a bit confused :) – Gottfried Apr 14 '11 at 14:33