使用iOS SDK和完整的Cocoa Touch / Objective-C代码确定用户的设备

我已经写了下面的UIDevice类别根据不同的来源。 我已经升级了platformCode方法,所以它比可以看到的更低级别。

这工作完美,但platformCode方法是低水平的。 你知道这种电话是否可以用Cocoa Touch代码替代吗? 以下是相关的代码:

UIDevice_enhanced.h

 @interface UIDevice (Enhanced) typedef enum { kUnknownPlatform = 0, kiPhone1G, kiPhone3G, kiPhone3GS, kiPhone4, kiPhone4Verizon, kiPhone4S, kiPodTouch1G, kiPodTouch2G, kiPodTouch3G, kiPodTouch4G, kiPad, kiPad2Wifi, kiPad2GSM, kiPad2CMDA, kSimulator } PlatformType; - (NSString *) platformName; - (PlatformType) platform; @end 

UIDevice_enhanced.m

 #import "UIDevice_enhanced.h" #include <sys/utsname.h> @interface UIDevice (Enhanced) - (NSString *) platformCode; @end @implementation UIDevice (Enhanced) // Utility method (private) - (NSString*) platformCode { struct utsname systemInfo; uname(&systemInfo); NSString* platform = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; return platform; } // Public method to use - (NSString*) platformName { NSString* platform = [self platformCode]; 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,2"]) 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:@"i386"]) return @"Simulator"; return platform; } // Public method to use - (PlatformType) platform { NSString *platform = [self platformCode]; if ([platform isEqualToString:@"iPhone1,1"]) return kiPhone1G; if ([platform isEqualToString:@"iPhone1,2"]) return kiPhone3G; if ([platform isEqualToString:@"iPhone2,1"]) return kiPhone3GS; if ([platform isEqualToString:@"iPhone3,1"]) return kiPhone4; if ([platform isEqualToString:@"iPhone3,2"]) return kiPhone4Verizon; if ([platform isEqualToString:@"iPhone4,1"]) return kiPhone4S; if ([platform isEqualToString:@"iPod1,1"]) return kiPodTouch1G; if ([platform isEqualToString:@"iPod2,1"]) return kiPodTouch2G; if ([platform isEqualToString:@"iPod3,1"]) return kiPodTouch3G; if ([platform isEqualToString:@"iPod4,1"]) return kiPodTouch4G; if ([platform isEqualToString:@"iPad1,1"]) return kiPad; if ([platform isEqualToString:@"iPad2,1"]) return kiPad2Wifi; if ([platform isEqualToString:@"iPad2,2"]) return kiPad2GSM; if ([platform isEqualToString:@"iPad2,3"]) return kiPad2CMDA; if ([platform isEqualToString:@"i386"]) return kSimulator; return kUnknownPlatform; } @end 

这可能被认为是一个“客观的”的方式:

 // Utility method (private) - (NSString *)platformCode { // This may or not be necessary // Im not sure if you can have a device thats not currentDevice can you? // if ([self isEqual:[UIDevice currentDevice]]) {  NSString* platform =  [[self.systemName copy] autorelease];  return platform; // Could probably shorten to just // return [[self.systemName copy] autorelease]; // or - return [NSString stringWithString:self.systemName]; } 

这将是obj-c版本的utsname machine (从这一行: NSString* platform = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; )。

utsname

<sys/utsname.h>头文件定义了结构utsname,其中至less包括以下成员:

char sysname[]这个操作系统的实现名称
char nodename[]在实现相关通信networking中的此节点的名称
char release[]当前版本级别的这个实现
char version[]此版本的当前版本级别
char machine[]系统正在运行的硬件types的名称

UIDevice类参考 :

systemName接收器所代表的设备上运行的操作系统的名称。 (只读)
@property (nonatomic, readonly, retain) NSString *system


但是,由于systemName只返回@“iPhone OS”,所以要获取实际的设备型号,必须使用c代码。 这是另一种方法:

 #include <sys/types.h> #include <sys/sysctl.h> - (NSString *)machine { size_t size; // Set 'oldp' parameter to NULL to get the size of the data // returned so we can allocate appropriate amount of space sysctlbyname("hw.machine", NULL, &size, NULL, 0); // Allocate the space to store name char *name = malloc(size); // Get the platform name sysctlbyname("hw.machine", name, &size, NULL, 0); // Place name into a string NSString *machine = [NSString stringWithCString:name]; // Done with this free(name); return machine; } 

你将不得不使用低级C调用来获取infoString。 为了我的目的,我写了一个小型的Objective-C库,将这个库抽象出来,并提供一个Objective-C接口。

 NSLog(@"Big model number: %d", deviceDetails.bigModel); //Big model number: 4 NSLog(@"Small model number: %d", deviceDetails.smallModel); //Small model number: 1 if (deviceDetails.model == GBDeviceModeliPhone4S) { NSLog(@"It's a 4S"); } //It's a 4S if (deviceDetails.family != GBDeviceFamilyiPad) { NSLog(@"It's not an iPad"); } //It's not an iPad NSLog(@"systemInfo string: %@", [GBDeviceInfo rawSystemInfoString]); //systemInfo string: iPhone4,1 

你可以得到它在github上,如果你喜欢: GBDeviceInfo