5

I have following code snip to detect the iOS Device.

NSString * platformNSString () {
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *machine = malloc(size);
    sysctlbyname("hw.machine", machine, &size, NULL, 0);
    NSString *platform = [NSString stringWithUTF8String:machine];
    free(machine);
    return platform;
}

NSString * platformString () {
    NSString *platform = platformNSString();

    // iphones
    if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
    if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
    if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
    if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
    if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
    if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4 (CDMA)";
    if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
    if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
    if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (GSM+CDMA)";
    if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (UK+Europe+Asis+China)";
    if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (GSM+CDMA)";
    if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (UK+Europe+Asis+China)";
    if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6";
    if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6 Plus";

    // ipods
    if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch (1 Gen)";
    if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch (2 Gen)";
    if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch (3 Gen)";
    if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch (4 Gen)";
    if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch (5 Gen)";

    // ipads
    if ([platform isEqualToString:@"iPad1,1"]) return @"iPad";
    if ([platform isEqualToString:@"iPad1,2"]) return @"iPad 3G";
    if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)";
    if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2";
    if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)";
    if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2";
    if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini (WiFi)";
    if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini";
    if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3 (WiFi)";
    if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3";
    if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)";
    if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4";
    if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4 (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air (WiFi)";
    if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini Retina (WiFi)";
    if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini Retina (GSM+CDMA)";
    if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini Retina (GSM+CDMA)";
    // iPad5,3

    // simulators
    if ([platform isEqualToString:@"i386"] || [platform isEqualToString:@"x86_64"] || [platform isEqualToString:@"ppc"] || [platform isEqualToString:@"ppc64"]) {

    }

    else return @"Unknown";
    return platform;
}

What I am also expecting is to have list of iOS Simulators as well?

See following image.

LIST OF IOS SIMULATORS

In short, I also want to detect what type of simulator with what iOS version is being used run-time as we detect the device.

Here is the code block of which indicates my efforts on same.

// simulators
if ([platform isEqualToString:@"i386"] || [platform isEqualToString:@"x86_64"] || [platform isEqualToString:@"ppc"] || [platform isEqualToString:@"ppc64"]) {
    CGSize size = [[UIScreen mainScreen] bounds].size;
    CGFloat simulatorHeight = (size.height>size.width)?size.height:size.width;
    if(simulatorHeight>=2048) {
        return @"Retina iPad Simulator";
    } else if(simulatorHeight>=1920) {
        return @"Retina iPhone 6+ Simulator";
    } else if(simulatorHeight>=1334) {
        return @"Retina iPhone 6 Simulator";
    } else if(simulatorHeight>=1136) {
        return @"Retina iPhone 5/5S/5C Simulator";
    } else if(simulatorHeight>=960) {
        return @"Retina iPhone 4/4S Simulator";
    } else if(simulatorHeight>=480) {
        return @"Retina iPhone 4/4S Simulator";
    }
}
sagarkothari
  • 24,520
  • 50
  • 165
  • 235
  • As a developer, you should not need to make any determination based on that information. Please elaborate on why you need this information, and I'll help you figure out a better alternative. – Jeremy Huddleston Sequoia Oct 31 '14 at 17:09
  • 1
    Well. I can not have all the devices at once like iPhone6, iPhone6+, iPad Air2, iPadAir, iPadMini3 etc. Sometimes, we've integrated device specific code. But it turns out difficult to check those specific code on simulators. – sagarkothari Oct 31 '14 at 19:08
  • My point is that you should not need to know these identifiers. You should not be making any decisions in your application based on these identifiers. You should be making decisions based on OTHER criteria, not the hardware identifier. – Jeremy Huddleston Sequoia Oct 31 '14 at 21:32

1 Answers1

6

As indicated in my comment above, you really shouldn't need this information.

But in the interest of at least providing an answer, with Xcode 6, you can use getenv("SIMULATOR_MODEL_IDENTIFIER") instead of sysctlbyname("hw.machine", ...). There's no guarantee that this will work in future releases.

Jeremy Huddleston Sequoia
  • 22,938
  • 5
  • 78
  • 86
  • This information is helpful when setting custom NSLayoutConstraints based on the device. Could you include a code snippet to get the full NSString of the type of Simulator being run? – TheJeff Jan 10 '17 at 17:43
  • Xcode 8 Analysis will report a memory leak on "machine" if you substitute the "getenv" line for the second "sysctlbyname" line, even with the "free(machine)" line. That can be resolved by keeping that second "sysctlbyname" line and putting the "getenv" line immediately after it. But, oddly enough, you do have to get rid of the "free(machine)" line. No memory leak reported, no problem deallocating the variables. – GlennRay May 04 '17 at 03:45
  • Just to be clear, I get a compile error if I leave in the "free(machine)" line saying that the variable cannot be freed because it has never been allocated. I do, however, set the values of the variables I use (including "machine") to nil at the end of the module. – GlennRay May 05 '17 at 01:09