108

Possible Duplicate:
Determine device (iPhone, iPod Touch) with iOS

I am making a game that utilizes the peer-to-peer bluetooth capabilities of the iPhone (and probably the iPod touch 2nd generation). However, to stop the users from trying to play a multiplayer on an iPod 1st gen and iPhone 2G I need to check for the specific device model.

[[UIDevice currentDevice] model] will only tell me if the device is an "iPhone" or an "iPod touch". Is there a way to check for the specific device model, like: "iPhone 3GS", "iPod touch 1st generation" or something.

EDIT:

There is a category to UIDevice (I think it's created by Erica Sadun, I don't take credit for it) that uses the following code to get the specific device model. You can find the whole category here along with other useful stuff: https://github.com/erica/uidevice-extension

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

@implementation UIDevice (Hardware)

/*
 Platforms
 iPhone1,1 -> iPhone 1G
 iPhone1,2 -> iPhone 3G 
 iPod1,1   -> iPod touch 1G 
 iPod2,1   -> iPod touch 2G 
*/

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

This works and apps using this have been lately approved in the AppStore.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Dimitris
  • 13,480
  • 17
  • 74
  • 94
  • 7
    VERY IMPORTANT: Apple recommends NOT to use this code. This is because in some scenarios this can be detected incorrectly. Check WWDC 2011 Session 123 at 3'30 and you'll see them showing this exact code and telling not to use. – Thiago Peres Nov 25 '11 at 01:41
  • @Lookez and what code we have to use? – Rodrigo Dec 12 '11 at 14:47
  • 4
    I saw that video. Using that kind of code is not recommended for checking for iPad (as we have UI_USER_INTERFACE_IDIOM for it now), but nothing was said about using it to determine the concrete hardware model. – zubko Jan 20 '12 at 14:58
  • In this SO question, a link was posted to this website. HTH – drvdijk Jul 10 '09 at 10:58
  • Yea its not that in "some scenarios this can be detected incorrectly", it is always detected correctly. You just have to future proof your code and not have some dangling "else" condition that defaults to a specific version. – Cbas Aug 17 '16 at 03:53

6 Answers6

154

You can get the device model number using uname from sys/utsname.h. For example:

#import <sys/utsname.h>

NSString*
machineName()
{
    struct utsname systemInfo;
    uname(&systemInfo);

    return [NSString stringWithCString:systemInfo.machine
                              encoding:NSUTF8StringEncoding];
}

The result should be:

@"i386"      on the simulator
@"iPod1,1"   on iPod Touch
@"iPod2,1"   on iPod Touch Second Generation
@"iPod3,1"   on iPod Touch Third Generation
@"iPod4,1"   on iPod Touch Fourth Generation
@"iPhone1,1" on iPhone
@"iPhone1,2" on iPhone 3G
@"iPhone2,1" on iPhone 3GS
@"iPad1,1"   on iPad
@"iPad2,1"   on iPad 2
@"iPad3,1"   on iPad 3 (aka new iPad)
@"iPhone3,1" on iPhone 4
@"iPhone4,1" on iPhone 4S
@"iPhone5,1" on iPhone 5
@"iPhone5,2" on iPhone 5
JAL
  • 41,701
  • 23
  • 172
  • 300
Will Harris
  • 21,597
  • 12
  • 64
  • 64
66

Most complete UIDevice (Hardware) category probably is http://github.com/erica/uidevice-extension/ (by Erica Sadun):

[[UIDevice currentDevice] platformType]   // ex: UIDevice4GiPhone
[[UIDevice currentDevice] platformString] // ex: @"iPhone 4G"
djromero
  • 19,551
  • 4
  • 71
  • 68
23

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

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

- (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 @"iPhone4 AT&T";  //iPhone 4 - AT&T
    if ([sDeviceModel isEqual:@"iPhone3,2"]) return @"iPhone4 Other";  //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:@"iPhone5,1"]) return @"iPhone5";    //iPhone 5 (GSM)
    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;
}
Rodrigo
  • 11,909
  • 23
  • 68
  • 101
4
BOOL hasHighResScreen = NO;
if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
    CGFloat scale = [[UIScreen mainScreen] scale];
    if (scale > 1.0) {
        hasHighResScreen = YES;
    }
}
gotnull
  • 26,454
  • 22
  • 137
  • 203
4

iPhone 4 is iPhone3,1 and iPhone3,2
iPhone 4S is iPhone4,1
iPad 2 is iPad2,1 iPad2,2 and iPad2,3 depending on version (GSM etc)
iPad 3 is iPad3,1 iPad3,2 and iPad3,3 depending on version (GSM etc)

See Iphone secrets (scroll down to "internal product codes")

Another good source is: everyiphone.com

Sten
  • 3,624
  • 1
  • 27
  • 26
-11
NSString* valueDevice = [[UIDevice currentDevice] model];

and then check if the string is equal to whatever device you are looking for like :

if(value==@"iPod1,1" ) 
{}

and you should be good to go

Matt
  • 45,022
  • 8
  • 78
  • 119
Ajith
  • 11
  • 1