Reputation: 5713
I use this method to fetch device model name:
+ (NSString *) machineModel
{
const char *name = "hw.model";
#if TARGET_OS_IPHONE
// .model on iOS returns internal model name (e.g. "N51AP") when we'd prefer to see the model identifier here ("iPhone6,1")
name = "hw.machine";
#endif
int error = 0;
size_t length = 0;
error = sysctlbyname(name, NULL, &length, NULL, 0);
if (error != 0) {
return nil;
}
char *p = malloc(sizeof(char) * length);
if (p) {
error = sysctlbyname(name, p, &length, NULL, 0);
}
if (error != 0) {
free(p);
return nil;
}
NSString *machinemodel = [NSString stringWithFormat:@"%s", p];
free(p);
return machinemodel;
}
However, when I run this code on thousands of devices I get following options in my database:
"iPhone7;1"
"iPhone8,1"
"iPhone7;2"
"iPhone"
"iPhone9;3"
"iPhone7;1"
"iPhone8,1"
"iPhone8,1"
"iPhone7,2"
"iPhone7;2"
"iPhone9;1"
"iPhone7;2"
...
Sometimes I have ,
separator, sometimes ;
and sometimes I see no number: "iPhone"
Why does it happen?
I would expect this from Android devices (5K different manufactories) but why iOS where only Apple is owner
Upvotes: 6
Views: 1049
Reputation: 478
With this knowledge, we can finally get a “Hardware model” value by using sysctl to get the HW_MODEL for OS X and HW_MACHINE for iOS systems.
In iOS, you should use hw.machine
rather than hw.model
size_t size;
int nR = sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = (char *)malloc(size);
nR = sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *deviceString = [NSString stringWithCString:machine encoding:NSUTF8StringEncoding];
free(machine);
Upvotes: 0
Reputation: 2581
@snaggs you can add this method it will give you proper output. i have call your method in first line of method.
- (NSString *)platformString
{
NSString *platform = [self machineModel];
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 (GSM)";
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 (GSM)";
if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (GSM+CDMA)";
if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (GSM)";
if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (GSM+CDMA)";
if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (GSM)";
if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (GSM+CDMA)";
if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 GSM";
if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6 GSM+CDMA";
if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6+ GSM";
if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6+ Global";
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:@"iPod5,1"]) return @"iPod Touch 5G";
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 (WiFi)";
if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini (WiFi)";
if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini (GSM)";
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 (GSM)";
if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)";
if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4 (GSM)";
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)";
if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini Retina (WiFi)";
if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini Retina (GSM)";
if ([platform isEqualToString:@"i386"]) return @"Simulator";
if ([platform isEqualToString:@"x86_64"]) return @"Simulator";
return platform;
}
Upvotes: 2
Reputation: 12051
I believe you have an issue with the code, by accessing the model name directly. Probably on some iOS versions or iOS architectures it works differently.
I suggest you use some higher level library like DeviceKit or Device - it works super well for me and always gives correct results.
If you don't want to use them directly, at least you can see how they work under the hood and implement the same logic yourself.
Upvotes: 2