6

I've been using the next line in my constants to differentiate between devices and get back the number of the device. What's the appropriate way to identify iPhone 5 and still keep it in a one line format?

#define iPhoneType [[UIScreen mainScreen] scale]==2 || [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad ? @"4" : @"3"

Thanks

Edit: A lot of good answers but my goal is to keep it in a one line format for all devices.

Edit: Based on the comments, this question needs some clarification. Here are the requirements:

  1. A single-line macro that returns either @"3", @"4", or @"5" depending on the iOS device.
  2. The 4" devices (currently iPhone 5 and 5th gen iPod touch) should return @"5".
  3. All iPads and all remaining retina iPhones and iPod touches should return @"4".
  4. All remaining non-retina iPhones and iPod touches should return @"3".
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Segev
  • 19,035
  • 12
  • 80
  • 152
  • Why not write a method and use that, or call it in the #define? – meaning-matters May 06 '13 at 06:54
  • http://stackoverflow.com/questions/1108859/detect-the-specific-iphone-ipod-touch-model – Balu May 06 '13 at 06:55
  • What is your goal here? The line you posted means "If this is a retina device or an iPad, return 4 otherwise return 3". What does that mean? You need to clarify your question with more details about what value you want returned for what cases. – rmaddy May 06 '13 at 17:49
  • I want to keep it to one line. if iphone 3 return @"3", if iphone 4 or ipad return @"4" if iphone 5 return @"5" – Segev May 06 '13 at 17:59
  • This seems like the wrong thing to be testing for. What happens when the iPhone 6 is released? You should probably be testing for the specific feature you need, such as retina display or camera resolution. – Mike C. May 06 '13 at 18:07
  • @EXEC_BAD_ACCESS Now I'm more confused. Why would you treat all iPads and the iPhone 4 (what about the 4S?) the same? What about iPod touches? What is your real goal? What do you do with the 3, 4, and 5 you are trying to get? There is most likely a much better way to do what you need. – rmaddy May 06 '13 at 23:41
  • the numbers are attached to a url in order to get the right picture for the device. At this moment I'm treating Ipads the same as iPhone 4 res (I know it's not right but that's the resolutions the client provides) – Segev May 07 '13 at 00:21
  • @EXEC_BAD_ACCESS I edited your question to clarify the requirements. Are they correct? Is this what you really want? – rmaddy May 07 '13 at 15:56
  • Exactly what I want, thanks. Your answer looks good, I'll check it when I'm on my mac. – Segev May 07 '13 at 17:58

5 Answers5

3

According to your question I'm assuming you want to identify the hardware device, not the iOS version.

/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 6.x Edition
BSD License, Use at your own risk
*/

#include <sys/sysctl.h>

NSString* getSysInfoByName(char* typeSpecifier) {
    size_t size;
    sysctlbyname(typeSpecifier, NULL, &size, NULL, 0);
    char *answer = malloc(size);
    sysctlbyname(typeSpecifier, answer, &size, NULL, 0);
    NSString *results = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
    free(answer);
    return results;
}

NSString* platform() {
    return getSysInfoByName("hw.machine");
}

Import those functions in the .pch, then you are free to call this one liner:

BOOL isIphone5 = [platform() hasPrefix:@"iPhone5"];

It works for any device. See UIDevice-Hardware.m for a list of the strings returned.

Jano
  • 62,815
  • 21
  • 164
  • 192
2

Define Following Constants in .pch file of your project

#define IS_IPHONE5          ([[UIScreen mainScreen] bounds].size.width >= 568 || [[UIScreen mainScreen] bounds].size.height >= 568)?YES:NO
#define IS_IPHONE           (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)?YES:NO
#define IS_IPAD             (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)?YES:NO

#define DeviceType          ((IS_IPAD)?@"IPAD":(IS_IPHONE5)?@"IPHONE 5":@"IPHONE")

Now Check device type

NSLog(@"%@ %@",DeviceType,[DeviceType isEqualToString:@"IPAD"]?@"YES":@"NO");

Use following sequence to Identify Device Type

if(IS_IPAD)
    NSLog(@"IPAD");
else if(IS_IPHONE5)
    NSLog(@"IPHONE 5");
else
    NSLog(@"IPHONE");
Dipen Panchasara
  • 13,480
  • 5
  • 47
  • 57
  • 1
    The IS_IPHONE5 macro is incorrect. The screen size on the iPhone 5 is 320x568. Since you already check for the height being >= 568 there is no point in also checking if it is >= 1136. Also, that macro will return true on all iPads since their heights are 768. – rmaddy May 07 '13 at 16:06
  • @rmaddy its for retina display, and its by mistake i need to compare width for landscape screen. thanks for pin pointing me.! – Dipen Panchasara May 08 '13 at 04:07
  • 1
    Retina or not, the screen bounds is reported in points, not pixels. So you will never get 1136 as the height. You will get 480 for 3.5" devices and 568 for 4" devices. And a macro named `IS_IPHONE5` shouldn't require that you first call some other macro. – rmaddy May 08 '13 at 04:09
2

Assuming the updated requirements are correct, the following should work:

#define iPhoneType (fabs((double)[UIScreen mainScreen].bounds.size.height - (double)568) < DBL_EPSILON) ? @"5" : ([UIScreen mainScreen].scale==2 || UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? @"4" : @"3")

This will return @"5" for the 4" screened iPhones and iPod touches. This will return @"4" for all iPads and retina iPhones and iPod touches. And it will return @"3" for non-retina iPhones and iPod touches.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
0

The best way to identify the different iOS devices programatically is their screen resolution. I done same in my application it is working great. Please refer my code.

- (NSString *) getDeviceScreenWidth
{
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    CGFloat width = CGRectGetWidth(screenBounds);
    NSNumber* number = [NSNumber numberWithFloat:width];
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
    NSString* commaString = [numberFormatter stringForObjectValue:number];
    NSString *screenWidth = [NSString stringWithFormat:@"%@",commaString];
    NSLog(@"screen Width is: %@",screenWidth);
    return screenWidth;
}

- (NSString *) getDeviceScreenHeight
{
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    CGFloat height = CGRectGetHeight(screenBounds);
    NSNumber* number = [NSNumber numberWithFloat:height];
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
    NSString* commaString = [numberFormatter stringForObjectValue:number];
    NSString *screenHeight = [NSString stringWithFormat:@"%@",commaString];
    NSLog(@"screen height is: %@",screenHeight);
    return screenHeight;
}
Undo
  • 25,519
  • 37
  • 106
  • 129
  • 2
    This is far from the "Best Way" to identify different iOS devices. The iPhone 5 and 5th gen iPod touch have the same resolution. Every iPhone before the iPhone 5 and every iPod touch before the 5th gen all have the same resolution. Every iPad will give the same width and height (since they are measured in points). – rmaddy May 06 '13 at 17:53
  • 1
    According to question i am right because here the question is to identify iphone 3,4,5 not ipod and ipad. But for more info the above code is working for iphone and ipad in every case from old one to latest new one. –  May 07 '13 at 10:42
  • 1
    @Pranav there are much simpler ways to do it such as the way `Dipen Panchasara` has done it, and `rmaddy` first comment is also correct. This is possibly both why you have received the 2 downvotes. Also it is no where near 1 line like the user has asked so it doesn't answer the question. – Popeye May 07 '13 at 13:38
  • 1
    @Popeye Thanks..No one like you here who clarify.. again thanks..some of here are shows their anger by downvotes and some of here are by technically downvotes.. –  May 07 '13 at 13:52
  • but if you like my answer and if it is possible way than make me happy by upvote this answer. –  May 07 '13 at 13:53
  • @Pranav It's always good to leave a reason for the downvote so you can improve/correct or just work on it in the future, sometimes though it can be hard to give a reason when answers or questions are not very good and some will just flag as not an answer or something. To be honest, your answer kinda confused me a little bit, and I don't understand why you would do it that way when you could do it `Dipen Panchasara` way and it is so much simpler. I don't know whether it deserves a downvote but I do know I can't bring myself to give an upvote sorry. – Popeye May 07 '13 at 13:59
  • @Popeye..Thanks..and just kidding for upvote..today i learned new thing for identify different ios devices.. But for clarification in my answer i get screen height and width in string format... –  May 07 '13 at 14:09
  • @Pranav The original question makes no sense so it really can't be answered very well, not matter what. At a minimum, the question seems to be for determining which device the user has. Your answer doesn't do that. All your answer does is provide two vastly over-complicated methods that return the current screen width or height as strings. The iPhone 3, 3G, 4, 4S, and 5 all have the same screen width. All iPhones except the iPhone 5 will have the same height. So how does your answer help solve the original question? And your answer gives different results in different countries. – rmaddy May 07 '13 at 15:33
  • @rmaddy Yes..thanks rmaddy..nice to chat with you..and also thanks Popeye..please be in touch with me on stackoverflow....thanks a lot –  May 08 '13 at 05:21
0

As sample you may found this code in cocos2d framework:

-(NSInteger) runningDevice
{
    NSInteger ret=-1;

#ifdef __CC_PLATFORM_IOS

    if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        ret = (CC_CONTENT_SCALE_FACTOR() == 2) ? kCCDeviceiPadRetinaDisplay : kCCDeviceiPad;
    }
    else if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone )
    {
        // From http://stackoverflow.com/a/12535566
        BOOL isiPhone5 = CGSizeEqualToSize([[UIScreen mainScreen] preferredMode].size,CGSizeMake(640, 1136));

        if( CC_CONTENT_SCALE_FACTOR() == 2 ) {
            ret = isiPhone5 ? kCCDeviceiPhone5RetinaDisplay : kCCDeviceiPhoneRetinaDisplay;
        } else
            ret = isiPhone5 ? kCCDeviceiPhone5 : kCCDeviceiPhone;
    }

#elif defined(__CC_PLATFORM_MAC)

    // XXX: Add here support for Mac Retina Display
    ret = kCCDeviceMac;

#endif // __CC_PLATFORM_MAC

    return ret;
}

I hope this code helps change your macro.

stosha
  • 2,108
  • 2
  • 27
  • 29