Thursday, May 31, 2012

Determine device (iPhone, iPod Touch) with iPhone SDK


Is there a way to determine the device running an application. I want to distinguish between iPhone and iPod Touch if possible.



Source: Tips4all

11 comments:

  1. You can use the UIDevice class as so:

    NSString *deviceType = [UIDevice currentDevice].model;

    if([deviceType isEqualToString:@"iPhone"])
    // it's an iPhone

    ReplyDelete
  2. Please feel free to use this class (gist @ github)


    CODE REMOVED AND RELOCATED TO

    https://gist.github.com/1323251


    UPDATE (01/14/11)

    Obviously, this code is a bit out of date by now, but it can certainly be updated using the code on this thread provided by Brian Robbins which includes similar code with updated models. Thanks for the support on this thread.

    ReplyDelete
  3. This is an updated for UIDeviceHardware.m from the answer above

    - (NSString *) platformString{
    NSString *platform = [self platform];
    if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G";
    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,3"]) return @"Verizon iPhone 4";
    if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
    if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
    if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
    if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
    if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G";
    if ([platform isEqualToString:@"iPad1,1"]) return @"iPad";
    if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)";
    if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2 (GSM)";
    if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)";
    if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2";
    if ([platform isEqualToString:@"iPad3,1"]) return @"iPad-3G (WiFi)";
    if ([platform isEqualToString:@"iPad3,2"]) return @"iPad-3G (4G)";
    if ([platform isEqualToString:@"iPad3,3"]) return @"iPad-3G (4G)";
    if ([platform isEqualToString:@"i386"]) return @"Simulator";
    if ([platform isEqualToString:@"x86_64"]) return @"Simulator";
    return platform;
    }

    ReplyDelete
  4. More usable

    #include <sys/types.h>
    #include <sys/sysctl.h>

    @interface UIDevice(Hardware)

    - (NSString *) platform;

    - (BOOL)hasRetinaDisplay;

    - (BOOL)hasMultitasking;

    - (BOOL)hasCamera;

    @end

    @implementation UIDevice(Hardware)

    - (NSString *) platform{
    int mib[2];
    size_t len;
    char *machine;

    mib[0] = CTL_HW;
    mib[1] = HW_MACHINE;
    sysctl(mib, 2, NULL, &len, NULL, 0);
    machine = malloc(len);
    sysctl(mib, 2, machine, &len, NULL, 0);

    NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
    free(machine);
    return platform;
    }

    - (BOOL)hasRetinaDisplay {
    NSString *platform = [self platform];
    BOOL ret = YES;
    if ([platform isEqualToString:@"iPhone1,1"]) {
    ret = NO;
    }
    else
    if ([platform isEqualToString:@"iPhone1,2"]) ret = NO;
    else
    if ([platform isEqualToString:@"iPhone2,1"]) ret = NO;
    else
    if ([platform isEqualToString:@"iPod1,1"]) ret = NO;
    else
    if ([platform isEqualToString:@"iPod2,1"]) ret = NO;
    else
    if ([platform isEqualToString:@"iPod3,1"]) ret = NO;
    return ret;
    }

    - (BOOL)hasMultitasking {
    if ([self respondsToSelector:@selector(isMultitaskingSupported)]) {
    return [self isMultitaskingSupported];
    }
    return NO;
    }

    - (BOOL)hasCamera {
    BOOL ret = NO;
    // check camera availability
    return ret;
    }

    @end


    you can reading properties with

    NSLog(@"platform %@, retita %@, multitasking %@", [[UIDevice currentDevice] platform], [[UIDevice currentDevice] hasRetinaDisplay] ? @"YES" : @"NO" , [[UIDevice currentDevice] hasMultitasking] ? @"YES" : @"NO");

    ReplyDelete
  5. Just adding the iPhone 4S device code to this thread...

    The iPhone 4S will return the string @"iPhone4,1".

    ReplyDelete
  6. Here's a minor update with new models:

    - (NSString *) platformString{
    NSString *platform = [self platform];
    if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G";
    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:@"iPod1,1"]) return @"iPod Touch 1G";
    if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
    if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
    if ([platform isEqualToString:@"i386"]) return @"iPhone Simulator";
    return platform;
    }

    ReplyDelete
  7. Dutchie432 and Brian Robbins have provided great solutions. But there's still one model missing, the Verizon iPhone 4. Here's the missing line.

    if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4"; //Verizon

    ReplyDelete
  8. What about iPad (1) - isn't there more than one model? I.e. iPad1,1 (Wifi), iPad1,2 (GSM)...

    ReplyDelete
  9. Check for GPS or the camera.

    ReplyDelete
  10. How about this code, if new version was released, you will identifier with the last know device

    - (NSString *)getModel {
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *model = malloc(size);
    sysctlbyname("hw.machine", model, &size, NULL, 0);
    NSString *sDeviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
    free(model);
    if ([sDeviceModel isEqual:@"i386"]) return @"Simulator"; //iPhone Simulator
    if ([sDeviceModel isEqual:@"iPhone1,1"]) return @"iPhone1G"; //iPhone 1G
    if ([sDeviceModel isEqual:@"iPhone1,2"]) return @"iPhone3G"; //iPhone 3G
    if ([sDeviceModel isEqual:@"iPhone2,1"]) return @"iPhone3GS"; //iPhone 3GS
    if ([sDeviceModel isEqual:@"iPhone3,1"]) return @"iPhone3GS"; //iPhone 4 - AT&T
    if ([sDeviceModel isEqual:@"iPhone3,2"]) return @"iPhone3GS"; //iPhone 4 - Other carrier
    if ([sDeviceModel isEqual:@"iPhone3,3"]) return @"iPhone4"; //iPhone 4 - Other carrier
    if ([sDeviceModel isEqual:@"iPhone4,1"]) return @"iPhone4S"; //iPhone 4S
    if ([sDeviceModel isEqual:@"iPod1,1"]) return @"iPod1stGen"; //iPod Touch 1G
    if ([sDeviceModel isEqual:@"iPod2,1"]) return @"iPod2ndGen"; //iPod Touch 2G
    if ([sDeviceModel isEqual:@"iPod3,1"]) return @"iPod3rdGen"; //iPod Touch 3G
    if ([sDeviceModel isEqual:@"iPod4,1"]) return @"iPod4thGen"; //iPod Touch 4G
    if ([sDeviceModel isEqual:@"iPad1,1"]) return @"iPadWiFi"; //iPad Wifi
    if ([sDeviceModel isEqual:@"iPad1,2"]) return @"iPad3G"; //iPad 3G
    if ([sDeviceModel isEqual:@"iPad2,1"]) return @"iPad2"; //iPad 2 (WiFi)
    if ([sDeviceModel isEqual:@"iPad2,2"]) return @"iPad2"; //iPad 2 (GSM)
    if ([sDeviceModel isEqual:@"iPad2,3"]) return @"iPad2"; //iPad 2 (CDMA)

    NSString *aux = [[sDeviceModel componentsSeparatedByString:@","] objectAtIndex:0];

    //If a newer version exist
    if ([aux rangeOfString:@"iPhone"].location!=NSNotFound) {
    int version = [[aux stringByReplacingOccurrencesOfString:@"iPhone" withString:@""] intValue];
    if (version == 3) return @"iPhone4"
    if (version >= 4) return @"iPhone4s";

    }
    if ([aux rangeOfString:@"iPod"].location!=NSNotFound) {
    int version = [[aux stringByReplacingOccurrencesOfString:@"iPod" withString:@""] intValue];
    if (version >=4) return @"iPod4thGen";
    }
    if ([aux rangeOfString:@"iPad"].location!=NSNotFound) {
    int version = [[aux stringByReplacingOccurrencesOfString:@"iPad" withString:@""] intValue];
    if (version ==1) return @"iPad3G";
    if (version >=2) return @"iPad2";
    }
    //If none was found, send the original string
    return sDeviceModel;
    }

    ReplyDelete
  11. Based on the very good answers above, here is what I came up with. This is very similar to @Rodrigo's answer, but addresses @Oliver's concern from the comment on that answer. This also provides the option of including the model string in the output string.

    + (NSString *) deviceModel {
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *model = malloc(size);
    sysctlbyname("hw.machine", model, &size, NULL, 0);
    NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
    free(model);

    return deviceModel;
    }

    + (NSString *) deviceName {
    NSString *deviceModel = [DeviceGateway deviceModel];

    if ([deviceModel isEqual:@"i386"]) return @"Simulator"; //iPhone Simulator
    if ([deviceModel isEqual:@"iPhone1,1"]) return @"iPhone1G"; //iPhone 1G
    if ([deviceModel isEqual:@"iPhone1,2"]) return @"iPhone3G"; //iPhone 3G
    if ([deviceModel isEqual:@"iPhone2,1"]) return @"iPhone3GS"; //iPhone 3GS
    if ([deviceModel isEqual:@"iPhone3,1"]) return @"iPhone4"; //iPhone 4 - AT&T
    if ([deviceModel isEqual:@"iPhone3,2"]) return @"iPhone4"; //iPhone 4 - Other carrier
    if ([deviceModel isEqual:@"iPhone3,3"]) return @"iPhone4"; //iPhone 4 - Other carrier
    if ([deviceModel isEqual:@"iPhone4,1"]) return @"iPhone4S"; //iPhone 4S
    if ([deviceModel isEqual:@"iPod1,1"]) return @"iPod1stGen"; //iPod Touch 1G
    if ([deviceModel isEqual:@"iPod2,1"]) return @"iPod2ndGen"; //iPod Touch 2G
    if ([deviceModel isEqual:@"iPod3,1"]) return @"iPod3rdGen"; //iPod Touch 3G
    if ([deviceModel isEqual:@"iPod4,1"]) return @"iPod4thGen"; //iPod Touch 4G
    if ([deviceModel isEqual:@"iPad1,1"]) return @"iPadWiFi"; //iPad Wifi
    if ([deviceModel isEqual:@"iPad1,2"]) return @"iPad3G"; //iPad 3G
    if ([deviceModel isEqual:@"iPad2,1"]) return @"iPad2"; //iPad 2 (WiFi)
    if ([deviceModel isEqual:@"iPad2,2"]) return @"iPad2"; //iPad 2 (GSM)
    if ([deviceModel isEqual:@"iPad2,3"]) return @"iPad2"; //iPad 2 (CDMA)

    NSString *aux = [[deviceModel componentsSeparatedByString:@","] objectAtIndex:0];

    //If a newer version exists
    if ([aux rangeOfString:@"iPhone"].location != NSNotFound) {
    int version = [[aux stringByReplacingOccurrencesOfString:@"iPhone" withString:@""] intValue];
    if (version == 3) return @"iPhone4";
    if (version == 4) return @"iPhone4s";
    return @"Newer iPhone";
    }
    if ([aux rangeOfString:@"iPod"].location != NSNotFound) {
    int version = [[aux stringByReplacingOccurrencesOfString:@"iPod" withString:@""] intValue];
    if (version == 4) return @"iPod4thGen";
    return @"Newer iPod";
    }
    if ([aux rangeOfString:@"iPad"].location != NSNotFound) {
    int version = [[aux stringByReplacingOccurrencesOfString:@"iPad" withString:@""] intValue];
    if (version == 1) return @"iPad3G";
    if (version == 2) return @"iPad2";
    return @"Newer iPad";
    }

    //If none was found, send the original string
    return deviceModel;
    }

    + (NSString *) deviceNameWithDeviceModel:(BOOL)shouldIncludeDeviceModel {
    if (shouldIncludeDeviceModel) {
    return [NSString stringWithFormat:@"%@ (%@)", [DeviceGateway deviceName], [DeviceGateway deviceModel]];
    }

    return [DeviceGateway deviceName];
    }

    ReplyDelete