如何在iOS上获得设备制作和模型?

我想知道是否有可能确定当前设备是哪种iPhone(例如)?我知道可以通过
得到模型 NSString *deviceType = [[UIDevice currentDevice] model]; < br > 它只会返回我是否有“iPhone”或“iPod”,但我想知道是否有可能检测/知道我是否有iPhone 3GS vs.和iPhone 4 vs. iPhone 4S (实际上,我真正想做的是确定我是否有3G,因为我正在做相当图形密集型的东西)。< / p >

所以,请告诉我,谢谢!

274098 次浏览

你可以试试这个库:http://github.com/erica/uidevice-extension/ (by Erica Sadun)。(图书馆有7-8年的历史,已经过时了)

(示例代码):

    [[UIDevice currentDevice] platformType]   // ex: UIDevice4GiPhone
[[UIDevice currentDevice] platformString] // ex: @"iPhone 4G"

或者你可以用这个方法:

您可以使用sys/utsname.h中的uname获取设备型号。例如:

objective - c

    #import <sys/utsname.h> // import it in your header or implementation file.


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

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

斯威夫特3

    extension UIDevice {
var modelName: String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
return identifier
}
}


print(UIDevice.current.modelName)

结果应该是:

// Output on a simulator
@"i386"      on 32-bit Simulator
@"x86_64"    on 64-bit Simulator


// Output on an iPhone
@"iPhone1,1" on iPhone
@"iPhone1,2" on iPhone 3G
@"iPhone2,1" on iPhone 3GS
@"iPhone3,1" on iPhone 4 (GSM)
@"iPhone3,2" on iPhone 4 (GSM Rev A)
@"iPhone3,3" on iPhone 4 (CDMA/Verizon/Sprint)
@"iPhone4,1" on iPhone 4S
@"iPhone5,1" on iPhone 5 (model A1428, AT&T/Canada)
@"iPhone5,2" on iPhone 5 (model A1429, everything else)
@"iPhone5,3" on iPhone 5c (model A1456, A1532 | GSM)
@"iPhone5,4" on iPhone 5c (model A1507, A1516, A1526 (China), A1529 | Global)
@"iPhone6,1" on iPhone 5s (model A1433, A1533 | GSM)
@"iPhone6,2" on iPhone 5s (model A1457, A1518, A1528 (China), A1530 | Global)
@"iPhone7,1" on iPhone 6 Plus
@"iPhone7,2" on iPhone 6
@"iPhone8,1" on iPhone 6S
@"iPhone8,2" on iPhone 6S Plus
@"iPhone8,4" on iPhone SE
@"iPhone9,1" on iPhone 7 (CDMA)
@"iPhone9,3" on iPhone 7 (GSM)
@"iPhone9,2" on iPhone 7 Plus (CDMA)
@"iPhone9,4" on iPhone 7 Plus (GSM)
@"iPhone10,1" on iPhone 8 (CDMA)
@"iPhone10,4" on iPhone 8 (GSM)
@"iPhone10,2" on iPhone 8 Plus (CDMA)
@"iPhone10,5" on iPhone 8 Plus (GSM)
@"iPhone10,3" on iPhone X (CDMA)
@"iPhone10,6" on iPhone X (GSM)
@"iPhone11,2" on iPhone XS
@"iPhone11,4" on iPhone XS Max
@"iPhone11,6" on iPhone XS Max China
@"iPhone11,8" on iPhone XR
@"iPhone12,1" on iPhone 11
@"iPhone12,3" on iPhone 11 Pro
@"iPhone12,5" on iPhone 11 Pro Max
@"iPhone12,8" on iPhone SE (2nd Gen)
@"iPhone13,1" on iPhone 12 Mini
@"iPhone13,2" on iPhone 12
@"iPhone13,3" on iPhone 12 Pro
@"iPhone13,4" on iPhone 12 Pro Max


//iPad 1
@"iPad1,1" on iPad - Wifi (model A1219)
@"iPad1,2" on iPad - Wifi + Cellular (model A1337)


//iPad 2
@"iPad2,1" - Wifi (model A1395)
@"iPad2,2" - GSM (model A1396)
@"iPad2,3" - 3G (model A1397)
@"iPad2,4" - Wifi (model A1395)


// iPad Mini
@"iPad2,5" - Wifi (model A1432)
@"iPad2,6" - Wifi + Cellular (model  A1454)
@"iPad2,7" - Wifi + Cellular (model  A1455)


//iPad 3
@"iPad3,1" - Wifi (model A1416)
@"iPad3,2" - Wifi + Cellular (model  A1403)
@"iPad3,3" - Wifi + Cellular (model  A1430)


//iPad 4
@"iPad3,4" - Wifi (model A1458)
@"iPad3,5" - Wifi + Cellular (model  A1459)
@"iPad3,6" - Wifi + Cellular (model  A1460)


//iPad AIR
@"iPad4,1" - Wifi (model A1474)
@"iPad4,2" - Wifi + Cellular (model A1475)
@"iPad4,3" - Wifi + Cellular (model A1476)


// iPad Mini 2
@"iPad4,4" - Wifi (model A1489)
@"iPad4,5" - Wifi + Cellular (model A1490)
@"iPad4,6" - Wifi + Cellular (model A1491)


// iPad Mini 3
@"iPad4,7" - Wifi (model A1599)
@"iPad4,8" - Wifi + Cellular (model A1600)
@"iPad4,9" - Wifi + Cellular (model A1601)


// iPad Mini 4
@"iPad5,1" - Wifi (model A1538)
@"iPad5,2" - Wifi + Cellular (model A1550)


//iPad AIR 2
@"iPad5,3" - Wifi (model A1566)
@"iPad5,4" - Wifi + Cellular (model A1567)


// iPad PRO 9.7"
@"iPad6,3" - Wifi (model A1673)
@"iPad6,4" - Wifi + Cellular (model A1674)
@"iPad6,4" - Wifi + Cellular (model A1675)


//iPad PRO 12.9"
@"iPad6,7" - Wifi (model A1584)
@"iPad6,8" - Wifi + Cellular (model A1652)


//iPad (5th generation)
@"iPad6,11" - Wifi (model A1822)
@"iPad6,12" - Wifi + Cellular (model A1823)
         

//iPad PRO 12.9" (2nd Gen)
@"iPad7,1" - Wifi (model A1670)
@"iPad7,2" - Wifi + Cellular (model A1671)
@"iPad7,2" - Wifi + Cellular (model A1821)
         

//iPad PRO 10.5"
@"iPad7,3" - Wifi (model A1701)
@"iPad7,4" - Wifi + Cellular (model A1709)


// iPad (6th Gen)
@"iPad7,5" - WiFi
@"iPad7,6" - WiFi + Cellular


// iPad (7th Gen)
@"iPad7,11" - WiFi
@"iPad7,12" - WiFi + Cellular


//iPad PRO 11"
@"iPad8,1" - WiFi
@"iPad8,2" - 1TB, WiFi
@"iPad8,3" - WiFi + Cellular
@"iPad8,4" - 1TB, WiFi + Cellular


//iPad PRO 12.9" (3rd Gen)
@"iPad8,5" - WiFi
@"iPad8,6" - 1TB, WiFi
@"iPad8,7" - WiFi + Cellular
@"iPad8,8" - 1TB, WiFi + Cellular


//iPad PRO 11" (2nd Gen)
@"iPad8,9" - WiFi
@"iPad8,10" - 1TB, WiFi


//iPad PRO 12.9" (4th Gen)
@"iPad8,11" - (WiFi)
@"iPad8,12" - (WiFi+Cellular)


// iPad mini 5th Gen
@"iPad11,1" - WiFi
@"iPad11,2" - Wifi  + Cellular


// iPad Air 3rd Gen
@"iPad11,3" - Wifi
@"iPad11,4" - Wifi  + Cellular


// iPad (8th Gen)
@"iPad11,6" - iPad 8th Gen (WiFi)
@"iPad11,7" - iPad 8th Gen (WiFi+Cellular)


// iPad Air 4th Gen
@"iPad13,1" - iPad air 4th Gen (WiFi)
@"iPad13,2" - iPad air 4th Gen (WiFi+Cellular)


//iPod Touch
@"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
@"iPod5,1"   on iPod Touch 5th Generation
@"iPod7,1"   on iPod Touch 6th Generation
@"iPod9,1"   on iPod Touch 7th Generation


// Apple Watch
@"Watch1,1" on Apple Watch 38mm case
@"Watch1,2" on Apple Watch 38mm case
@"Watch2,6" on Apple Watch Series 1 38mm case
@"Watch2,7" on Apple Watch Series 1 42mm case
@"Watch2,3" on Apple Watch Series 2 38mm case
@"Watch2,4" on Apple Watch Series 2 42mm case
@"Watch3,1" on Apple Watch Series 3 38mm case (GPS+Cellular)
@"Watch3,2" on Apple Watch Series 3 42mm case (GPS+Cellular)
@"Watch3,3" on Apple Watch Series 3 38mm case (GPS)
@"Watch3,4" on Apple Watch Series 3 42mm case (GPS)
@"Watch4,1" on Apple Watch Series 4 40mm case (GPS)
@"Watch4,2" on Apple Watch Series 4 44mm case (GPS)
@"Watch4,3" on Apple Watch Series 4 40mm case (GPS+Cellular)
@"Watch4,4" on Apple Watch Series 4 44mm case (GPS+Cellular)
@"Watch5,1" on Apple Watch Series 5 40mm case (GPS)
@"Watch5,2" on Apple Watch Series 5 44mm case (GPS)
@"Watch5,3" on Apple Watch Series 5 40mm case (GPS+Cellular)
@"Watch5,4" on Apple Watch Series 5 44mm case (GPS+Cellular)
@"Watch5,9" on Apple Watch SE 40mm case (GPS)
@"Watch5,10" on Apple Watch SE 44mm case (GPS)
@"Watch5,11" on Apple Watch SE 40mm case (GPS+Cellular)
@"Watch5,12" on Apple Watch SE 44mm case (GPS+Cellular)
@"Watch6,1" on Apple Watch Series 6 40mm case (GPS)
@"Watch6,2" on Apple Watch Series 6 44mm case (GPS)
@"Watch6,3" on Apple Watch Series 6 40mm case (GPS+Cellular)
@"Watch6,4" on Apple Watch Series 6 44mm case (GPS+Cellular)

[[UIDevice currentDevice] model]只返回iPhoneiPod,你不会得到能让你区分不同代设备的型号的数字。

编写这个方法:

#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 *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
free(model);
return deviceModel;
}

当你需要模型的时候调用方法[self getModel],你会得到例如:"iPhone5,1"用于超薄而快速的iPhone5。

一个好的做法是创建一个名为Utils.h/Utils.m的类,并在其中放置getModel这样的方法,这样你就可以通过导入类并调用[Utils getModel];从应用程序的任何地方获得这些信息

我已经创建了plist文件,以帮助您获得每个设备的完整名称(源代码就在我的答案的末尾)

基于OhhMee的回答,你可以这样使用它:

斯威夫特4.0

static func deviceName() -> String {


var systemInfo = utsname()
uname(&systemInfo)


guard let iOSDeviceModelsPath = Bundle.main.path(forResource: "iOSDeviceModelMapping", ofType: "plist") else { return "" }
guard let iOSDevices = NSDictionary(contentsOfFile: iOSDeviceModelsPath) else { return "" }


let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}


return iOSDevices.value(forKey: identifier) as! String
}

不要忘记在桥接头中添加#import <sys/utsname.h>

Objective - C

#import <sys/utsname.h>


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


NSString *iOSDeviceModelsPath = [[NSBundle mainBundle] pathForResource:@"iOSDeviceModelMapping" ofType:@"plist"];
NSDictionary *iOSDevices = [NSDictionary dictionaryWithContentsOfFile:iOSDeviceModelsPath];


NSString* deviceModel = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];


return [iOSDevices valueForKey:deviceModel];
}

plist文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>x86_64</key>
<string>Simulator</string>
<key>i386</key>
<string>Simulator</string>
<key>iPod1,1</key>
<string>iPod Touch 1st Gen</string>
<key>iPod2,1</key>
<string>iPod Touch 2nd Gen</string>
<key>iPod3,1</key>
<string>iPod Touch 3rd Gen</string>
<key>iPod4,1</key>
<string>iPod Touch 4th Gen</string>
<key>iPod5,1</key>
<string>iPod Touch 5th Gen</string>
<key>iPod7,1</key>
<string>iPod Touch 6th Gen</string>
<key>iPhone1,1</key>
<string>iPhone</string>
<key>iPhone1,2</key>
<string>iPhone 3G</string>
<key>iPhone2,1</key>
<string>iPhone 3GS</string>
<key>iPhone3,1</key>
<string>iPhone 4</string>
<key>iPhone3,2</key>
<string>iPhone 4</string>
<key>iPhone3,3</key>
<string>iPhone 4</string>
<key>iPhone4,1</key>
<string>iPhone 4S</string>
<key>iPhone5,1</key>
<string>iPhone 5 model A1428</string>
<key>iPhone5,2</key>
<string>iPhone 5 model A1429</string>
<key>iPhone5,3</key>
<string>iPhone 5C</string>
<key>iPhone5,4</key>
<string>iPhone 5C</string>
<key>iPhone6,1</key>
<string>iPhone 5S</string>
<key>iPhone6,2</key>
<string>iPhone 5S</string>
<key>iPhone7,2</key>
<string>iPhone 6</string>
<key>iPhone7,1</key>
<string>iPhone 6 Plus</string>
<key>iPhone8,1</key>
<string>iPhone 6S</string>
<key>iPhone8,2</key>
<string>iPhone 6S Plus</string>
<key>iPhone8,4</key>
<string>iPhone SE</string>
<key>iPhone9,1</key>
<string>iPhone 7</string>
<key>iPhone9,2</key>
<string>iPhone 7 Plus</string>
<key>iPhone9,3</key>
<string>iPhone 7</string>
<key>iPhone9,4</key>
<string>iPhone 7 Plus</string>
<key>iPhone10,1</key>
<string>iPhone 8</string>
<key>iPhone10,4</key>
<string>iPhone 8</string>
<key>iPhone10,2</key>
<string>iPhone 8 Plus</string>
<key>iPhone10,5</key>
<string>iPhone 8 Plus</string>
<key>iPhone10,3</key>
<string>iPhone X</string>
<key>iPhone10,6</key>
<string>iPhone X</string>
<key>iPhone11,2</key>
<string>iPhone XS</string>
<key>iPhone11,4</key>
<string>iPhone XS Max</string>
<key>iPhone11,6</key>
<string>iPhone XS Max</string>
<key>iPhone11,8</key>
<string>iPhone XR</string>
<key>iPad1,1</key>
<string>iPad</string>
<key>iPad2,1</key>
<string>iPad 2</string>
<key>iPad2,2</key>
<string>iPad 2</string>
<key>iPad2,3</key>
<string>iPad 2</string>
<key>iPad2,4</key>
<string>iPad 2</string>
<key>iPad3,1</key>
<string>iPad 3rd Gen</string>
<key>iPad3,2</key>
<string>iPad 3rd Gen</string>
<key>iPad3,3</key>
<string>iPad 3rd Gen</string>
<key>iPad3,4</key>
<string>iPad 4th Gen</string>
<key>iPad3,5</key>
<string>iPad 4th Gen</string>
<key>iPad3,6</key>
<string>iPad 4th Gen</string>
<key>iPad4,1</key>
<string>iPad Air</string>
<key>iPad4,2</key>
<string>iPad Air</string>
<key>iPad4,3</key>
<string>iPad Air</string>
<key>iPad2,5</key>
<string>iPad Mini 1st Gen</string>
<key>iPad2,6</key>
<string>iPad Mini 1st Gen</string>
<key>iPad2,7</key>
<string>iPad Mini 1st Gen</string>
<key>iPad4,4</key>
<string>iPad Mini 2nd Gen</string>
<key>iPad4,5</key>
<string>iPad Mini 2nd Gen</string>
<key>iPad4,6</key>
<string>iPad Mini 2nd Gen</string>
<key>iPad4,7</key>
<string>iPad Mini 3rd Gen</string>
<key>iPad4,8</key>
<string>iPad Mini 3rd Gen</string>
<key>iPad4,9</key>
<string>iPad Mini 3rd Gen</string>
<key>iPad5,1</key>
<string>iPad Mini 4</string>
<key>iPad5,2</key>
<string>iPad Mini 4</string>
<key>iPad5,3</key>
<string>iPad Air 2</string>
<key>iPad5,4</key>
<string>iPad Air 2</string>
<key>iPad6,3</key>
<string>iPad Pro 9.7 inch</string>
<key>iPad6,4</key>
<string>iPad Pro 9.7 inch</string>
<key>iPad6,7</key>
<string>iPad Pro 12.9 inch</string>
<key>iPad6,8</key>
<string>iPad Pro 12.9 inch</string>
<key>iPad7,1</key>
<string>iPad Pro 12.9 inch 2nd Gen</string>
<key>iPad7,2</key>
<string>iPad Pro 12.9 inch 2nd Gen</string>
<key>iPad7,3</key>
<string>iPad Pro 10.5 inch</string>
<key>iPad7,4</key>
<string>iPad Pro 10.5 inch</string>
<key>iPad8,1</key>
<string>iPad Pro 11 inch</string>
<key>iPad8,2</key>
<string>iPad Pro 11 inch</string>
<key>iPad8,3</key>
<string>iPad Pro 11 inch</string>
<key>iPad8,4</key>
<string>iPad Pro 11 inch</string>
<key>iPad8,5</key>
<string>iPad Pro 12.9 inch 3rd Gen</string>
<key>iPad8,6</key>
<string>iPad Pro 12.9 inch 3rd Gen</string>
<key>iPad8,7</key>
<string>iPad Pro 12.9 inch 3rd Gen</string>
<key>iPad8,8</key>
<string>iPad Pro 12.9 inch 3rd Gen</string>
</dict>
</plist>

扩展OhhMee上面的回答,我添加了一些故障保险,以支持未来未列入列表的设备:

#import <sys/utsname.h>
#import "MyClass.h"


@implementation MyClass
{
//(your private ivars)
}


- (NSString*) deviceName
{
struct utsname systemInfo;


uname(&systemInfo);


NSString* code = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];


static NSDictionary* deviceNamesByCode = nil;


if (!deviceNamesByCode) {


deviceNamesByCode = @{@"i386"      : @"Simulator",
@"x86_64"    : @"Simulator",
@"iPod1,1"   : @"iPod Touch",        // (Original)
@"iPod2,1"   : @"iPod Touch",        // (Second Generation)
@"iPod3,1"   : @"iPod Touch",        // (Third Generation)
@"iPod4,1"   : @"iPod Touch",        // (Fourth Generation)
@"iPod7,1"   : @"iPod Touch",        // (6th Generation)
@"iPhone1,1" : @"iPhone",            // (Original)
@"iPhone1,2" : @"iPhone",            // (3G)
@"iPhone2,1" : @"iPhone",            // (3GS)
@"iPad1,1"   : @"iPad",              // (Original)
@"iPad2,1"   : @"iPad 2",            //
@"iPad3,1"   : @"iPad",              // (3rd Generation)
@"iPhone3,1" : @"iPhone 4",          // (GSM)
@"iPhone3,3" : @"iPhone 4",          // (CDMA/Verizon/Sprint)
@"iPhone4,1" : @"iPhone 4S",         //
@"iPhone5,1" : @"iPhone 5",          // (model A1428, AT&T/Canada)
@"iPhone5,2" : @"iPhone 5",          // (model A1429, everything else)
@"iPad3,4"   : @"iPad",              // (4th Generation)
@"iPad2,5"   : @"iPad Mini",         // (Original)
@"iPhone5,3" : @"iPhone 5c",         // (model A1456, A1532 | GSM)
@"iPhone5,4" : @"iPhone 5c",         // (model A1507, A1516, A1526 (China), A1529 | Global)
@"iPhone6,1" : @"iPhone 5s",         // (model A1433, A1533 | GSM)
@"iPhone6,2" : @"iPhone 5s",         // (model A1457, A1518, A1528 (China), A1530 | Global)
@"iPhone7,1" : @"iPhone 6 Plus",     //
@"iPhone7,2" : @"iPhone 6",          //
@"iPhone8,1" : @"iPhone 6S",         //
@"iPhone8,2" : @"iPhone 6S Plus",    //
@"iPhone8,4" : @"iPhone SE",         //
@"iPhone9,1" : @"iPhone 7",          //
@"iPhone9,3" : @"iPhone 7",          //
@"iPhone9,2" : @"iPhone 7 Plus",     //
@"iPhone9,4" : @"iPhone 7 Plus",     //
@"iPhone10,1": @"iPhone 8",          // CDMA
@"iPhone10,4": @"iPhone 8",          // GSM
@"iPhone10,2": @"iPhone 8 Plus",     // CDMA
@"iPhone10,5": @"iPhone 8 Plus",     // GSM
@"iPhone10,3": @"iPhone X",          // CDMA
@"iPhone10,6": @"iPhone X",          // GSM
@"iPhone11,2": @"iPhone XS",         //
@"iPhone11,4": @"iPhone XS Max",     //
@"iPhone11,6": @"iPhone XS Max",     // China
@"iPhone11,8": @"iPhone XR",         //
@"iPhone12,1": @"iPhone 11",         //
@"iPhone12,3": @"iPhone 11 Pro",     //
@"iPhone12,5": @"iPhone 11 Pro Max", //


@"iPad4,1"   : @"iPad Air",          // 5th Generation iPad (iPad Air) - Wifi
@"iPad4,2"   : @"iPad Air",          // 5th Generation iPad (iPad Air) - Cellular
@"iPad4,4"   : @"iPad Mini",         // (2nd Generation iPad Mini - Wifi)
@"iPad4,5"   : @"iPad Mini",         // (2nd Generation iPad Mini - Cellular)
@"iPad4,7"   : @"iPad Mini",         // (3rd Generation iPad Mini - Wifi (model A1599))
@"iPad6,7"   : @"iPad Pro (12.9\")", // iPad Pro 12.9 inches - (model A1584)
@"iPad6,8"   : @"iPad Pro (12.9\")", // iPad Pro 12.9 inches - (model A1652)
@"iPad6,3"   : @"iPad Pro (9.7\")",  // iPad Pro 9.7 inches - (model A1673)
@"iPad6,4"   : @"iPad Pro (9.7\")"   // iPad Pro 9.7 inches - (models A1674 and A1675)
};
}


NSString* deviceName = [deviceNamesByCode objectForKey:code];


if (!deviceName) {
// Not found on database. At least guess main device type from string contents:


if ([code rangeOfString:@"iPod"].location != NSNotFound) {
deviceName = @"iPod Touch";
}
else if([code rangeOfString:@"iPad"].location != NSNotFound) {
deviceName = @"iPad";
}
else if([code rangeOfString:@"iPhone"].location != NSNotFound){
deviceName = @"iPhone";
}
else {
deviceName = @"Unknown";
}
}


return deviceName;
}


// (rest of class implementation omitted)


@end

我也省略了详细的信息(例如:“型号A1507, A1516, A1526(中国),A1529 |全球”),并将其放在评论中,以防你想将其用作面向用户的字符串,而不是吓坏他们。


编辑: 这个答案使用Swift 2提供了类似的实现。

编辑2:我刚刚添加了iPad Pro型号(两种尺寸)。型号等供日后参考。可以在iPhone的Wiki中找到。

增加对iPhone XS、iPhone XS Max和iPhone XR的支持。

增加对iPhone 11、iPhone 11 Pro和iPhone 11 Pro Max的支持。

我优化了NicolasMiari的实现,并在这里添加了Simulator:

+ (NSString*)deviceName {


static NSDictionary* deviceNamesByCode = nil;
static NSString* deviceName = nil;


if (deviceName) {
return deviceName;
}


deviceNamesByCode = @{
@"i386"      :@"Simulator",
@"iPod1,1"   :@"iPod Touch",      // (Original)
@"iPod2,1"   :@"iPod Touch",      // (Second Generation)
@"iPod3,1"   :@"iPod Touch",      // (Third Generation)
@"iPod4,1"   :@"iPod Touch",      // (Fourth Generation)
@"iPhone1,1" :@"iPhone",          // (Original)
@"iPhone1,2" :@"iPhone",          // (3G)
@"iPhone2,1" :@"iPhone",          // (3GS)
@"iPad1,1"   :@"iPad",            // (Original)
@"iPad2,1"   :@"iPad 2",          //
@"iPad3,1"   :@"iPad",            // (3rd Generation)
@"iPhone3,1" :@"iPhone 4",        //
@"iPhone4,1" :@"iPhone 4S",       //
@"iPhone5,1" :@"iPhone 5",        // (model A1428, AT&T/Canada)
@"iPhone5,2" :@"iPhone 5",        // (model A1429, everything else)
@"iPad3,4"   :@"iPad",            // (4th Generation)
@"iPad2,5"   :@"iPad Mini",       // (Original)
@"iPhone5,3" :@"iPhone 5c",       // (model A1456, A1532 | GSM)
@"iPhone5,4" :@"iPhone 5c",       // (model A1507, A1516, A1526 (China), A1529 | Global)
@"iPhone6,1" :@"iPhone 5s",       // (model A1433, A1533 | GSM)
@"iPhone6,2" :@"iPhone 5s",       // (model A1457, A1518, A1528 (China), A1530 | Global)
@"iPad4,1"   :@"iPad Air",        // 5th Generation iPad (iPad Air) - Wifi
@"iPad4,2"   :@"iPad Air",        // 5th Generation iPad (iPad Air) - Cellular
@"iPad4,4"   :@"iPad Mini",       // (2nd Generation iPad Mini - Wifi)
@"iPad4,5"   :@"iPad Mini"        // (2nd Generation iPad Mini - Cellular)
};


struct utsname systemInfo;
uname(&systemInfo);
NSString* code = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];


deviceName = [deviceNamesByCode objectForKey:code];


if (!deviceName) {
// Not found in database. At least guess main device type from string contents:


if ([code rangeOfString:@"iPod"].location != NSNotFound) {
deviceName = @"iPod Touch";
} else if([code rangeOfString:@"iPad"].location != NSNotFound) {
deviceName = @"iPad";
} else if([code rangeOfString:@"iPhone"].location != NSNotFound){
deviceName = @"iPhone";
} else {
deviceName = @"Simulator";
}
}


return deviceName;
}

' ' '

#import <sys/utsname.h>


#define HARDWARE @{@"i386": @"Simulator",@"x86_64": @"Simulator",@"iPod1,1": @"iPod Touch",@"iPod2,1": @"iPod Touch 2nd Generation",@"iPod3,1": @"iPod Touch 3rd Generation",@"iPod4,1": @"iPod Touch 4th Generation",@"iPhone1,1": @"iPhone",@"iPhone1,2": @"iPhone 3G",@"iPhone2,1": @"iPhone 3GS",@"iPhone3,1": @"iPhone 4",@"iPhone4,1": @"iPhone 4S",@"iPhone5,1": @"iPhone 5",@"iPhone5,2": @"iPhone 5",@"iPhone5,3": @"iPhone 5c",@"iPhone5,4": @"iPhone 5c",@"iPhone6,1": @"iPhone 5s",@"iPhone6,2": @"iPhone 5s",@"iPad1,1": @"iPad",@"iPad2,1": @"iPad 2",@"iPad3,1": @"iPad 3rd Generation ",@"iPad3,4": @"iPad 4th Generation ",@"iPad2,5": @"iPad Mini",@"iPad4,4": @"iPad Mini 2nd Generation - Wifi",@"iPad4,5": @"iPad Mini 2nd Generation - Cellular",@"iPad4,1": @"iPad Air 5th Generation - Wifi",@"iPad4,2": @"iPad Air 5th Generation - Cellular"}


@interface ViewController ()
@end


@implementation ViewController


- (void)viewDidLoad
{
[super viewDidLoad];
struct utsname systemInfo;
uname(&systemInfo);
NSLog(@"hardware: %@",[HARDWARE objectForKey:[NSString stringWithCString: systemInfo.machine encoding:NSUTF8StringEncoding]]);
}

一个从NSString描述中脱离的类别

通常,在整个代码中避免任意的字符串比较是可取的。最好在一个地方更新字符串,并在应用程序中隐藏神奇的字符串。为此,我在UIDevice上提供了一个类别。

对于我的特定需求,我需要知道我正在使用的设备,而不需要知道可以通过其他方式轻松检索的网络功能的细节。所以你会发现一个比不断增长的设备列表更粗粒度的enum

更新就是将设备添加到枚举和查找表中。

UIDevice + NTNUExtensions.h

typedef NS_ENUM(NSUInteger, NTNUDeviceType) {
DeviceAppleUnknown,
DeviceAppleSimulator,
DeviceAppleiPhone,
DeviceAppleiPhone3G,
DeviceAppleiPhone3GS,
DeviceAppleiPhone4,
DeviceAppleiPhone4S,
DeviceAppleiPhone5,
DeviceAppleiPhone5C,
DeviceAppleiPhone5S,
DeviceAppleiPhone6,
DeviceAppleiPhone6_Plus,
DeviceAppleiPhone6S,
DeviceAppleiPhone6S_Plus,
DeviceAppleiPhoneSE,
DeviceAppleiPhone7,
DeviceAppleiPhone7_Plus,
DeviceAppleiPodTouch,
DeviceAppleiPodTouch2G,
DeviceAppleiPodTouch3G,
DeviceAppleiPodTouch4G,
DeviceAppleiPad,
DeviceAppleiPad2,
DeviceAppleiPad3G,
DeviceAppleiPad4G,
DeviceAppleiPad5G_Air,
DeviceAppleiPadMini,
DeviceAppleiPadMini2G,
DeviceAppleiPadPro12,
DeviceAppleiPadPro9
};






@interface UIDevice (NTNUExtensions)


- (NSString *)ntnu_deviceDescription;
- (NTNUDeviceType)ntnu_deviceType;


@end

UIDevice + NTNUExtensions.m

#import <sys/utsname.h>
#import "UIDevice+NTNUExtensions.h"


@implementation UIDevice (NTNUExtensions)


- (NSString *)ntnu_deviceDescription
{
struct utsname systemInfo;
uname(&systemInfo);


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


- (NTNUDeviceType)ntnu_deviceType
{
NSNumber *deviceType = [[self ntnu_deviceTypeLookupTable] objectForKey:[self ntnu_deviceDescription]];
return [deviceType unsignedIntegerValue];
}


- (NSDictionary *)ntnu_deviceTypeLookupTable
{
return @{
@"i386": @(DeviceAppleSimulator),
@"x86_64": @(DeviceAppleSimulator),
@"iPod1,1": @(DeviceAppleiPodTouch),
@"iPod2,1": @(DeviceAppleiPodTouch2G),
@"iPod3,1": @(DeviceAppleiPodTouch3G),
@"iPod4,1": @(DeviceAppleiPodTouch4G),
@"iPhone1,1": @(DeviceAppleiPhone),
@"iPhone1,2": @(DeviceAppleiPhone3G),
@"iPhone2,1": @(DeviceAppleiPhone3GS),
@"iPhone3,1": @(DeviceAppleiPhone4),
@"iPhone3,3": @(DeviceAppleiPhone4),
@"iPhone4,1": @(DeviceAppleiPhone4S),
@"iPhone5,1": @(DeviceAppleiPhone5),
@"iPhone5,2": @(DeviceAppleiPhone5),
@"iPhone5,3": @(DeviceAppleiPhone5C),
@"iPhone5,4": @(DeviceAppleiPhone5C),
@"iPhone6,1": @(DeviceAppleiPhone5S),
@"iPhone6,2": @(DeviceAppleiPhone5S),
@"iPhone7,1": @(DeviceAppleiPhone6_Plus),
@"iPhone7,2": @(DeviceAppleiPhone6),
@"iPhone8,1" :@(DeviceAppleiPhone6S),
@"iPhone8,2" :@(DeviceAppleiPhone6S_Plus),
@"iPhone8,4" :@(DeviceAppleiPhoneSE),
@"iPhone9,1" :@(DeviceAppleiPhone7),
@"iPhone9,3" :@(DeviceAppleiPhone7),
@"iPhone9,2" :@(DeviceAppleiPhone7_Plus),
@"iPhone9,4" :@(DeviceAppleiPhone7_Plus),
@"iPad1,1": @(DeviceAppleiPad),
@"iPad2,1": @(DeviceAppleiPad2),
@"iPad3,1": @(DeviceAppleiPad3G),
@"iPad3,4": @(DeviceAppleiPad4G),
@"iPad2,5": @(DeviceAppleiPadMini),
@"iPad4,1": @(DeviceAppleiPad5G_Air),
@"iPad4,2": @(DeviceAppleiPad5G_Air),
@"iPad4,4": @(DeviceAppleiPadMini2G),
@"iPad4,5": @(DeviceAppleiPadMini2G),
@"iPad4,7":@(DeviceAppleiPadMini),
@"iPad6,7":@(DeviceAppleiPadPro12),
@"iPad6,8":@(DeviceAppleiPadPro12),
@"iPad6,3":@(DeviceAppleiPadPro9),
@"iPad6,4":@(DeviceAppleiPadPro9)
};
}


@end

下面是它的代码(代码可能不包含所有设备的字符串,我和其他人在GitHub上维护相同的代码,所以请从那里采取最新的代码)

__abc0: __abc1

__abc0: __abc1


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


- (NSString*)hardwareDescription {
NSString *hardware = [self hardwareString];
if ([hardware isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
if ([hardware isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
if ([hardware isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
if ([hardware isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
if ([hardware isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
if ([hardware isEqualToString:@"iPod1,1"]) return @"iPodTouch 1G";
if ([hardware isEqualToString:@"iPod2,1"]) return @"iPodTouch 2G";
if ([hardware isEqualToString:@"iPad1,1"]) return @"iPad";
if ([hardware isEqualToString:@"iPad2,6"]) return @"iPad Mini";
if ([hardware isEqualToString:@"iPad4,1"]) return @"iPad Air WIFI";
//there are lots of other strings too, checkout the github repo
//link is given at the top of this answer


if ([hardware isEqualToString:@"i386"]) return @"Simulator";
if ([hardware isEqualToString:@"x86_64"]) return @"Simulator";


return nil;
}


- (NSString*)hardwareString {
size_t size = 100;
char *hw_machine = malloc(size);
int name[] = {CTL_HW,HW_MACHINE};
sysctl(name, 2, hw_machine, &size, NULL, 0);
NSString *hardware = [NSString stringWithUTF8String:hw_machine];
free(hw_machine);
return hardware;
}

兼容Swift 3

// MARK: - UIDevice Extension -


private let DeviceList = [
/* iPod 5 */          "iPod5,1": "iPod Touch 5",
/* iPhone 4 */        "iPhone3,1":  "iPhone 4", "iPhone3,2": "iPhone 4", "iPhone3,3": "iPhone 4",
/* iPhone 4S */       "iPhone4,1": "iPhone 4S",
/* iPhone 5 */        "iPhone5,1": "iPhone 5", "iPhone5,2": "iPhone 5",
/* iPhone 5C */       "iPhone5,3": "iPhone 5C", "iPhone5,4": "iPhone 5C",
/* iPhone 5S */       "iPhone6,1": "iPhone 5S", "iPhone6,2": "iPhone 5S",
/* iPhone 6 */        "iPhone7,2": "iPhone 6",
/* iPhone 6 Plus */   "iPhone7,1": "iPhone 6 Plus",
/* iPhone 6S */       "iPhone8,1": "iPhone 6S",
/* iPhone 6S Plus */  "iPhone8,2": "iPhone 6S Plus",
/* iPhone SE */       "iPhone8,4": "iPhone SE",
/* iPhone 7 */        "iPhone9,1": "iPhone 7",
/* iPhone 7 */        "iPhone9,3": "iPhone 7",
/* iPhone 7 Plus */   "iPhone9,2": "iPhone 7 Plus",
/* iPhone 7 Plus */   "iPhone9,4": "iPhone 7 Plus",
/* iPad 2 */          "iPad2,1": "iPad 2", "iPad2,2": "iPad 2", "iPad2,3": "iPad 2", "iPad2,4": "iPad 2",
/* iPad 3 */          "iPad3,1": "iPad 3", "iPad3,2": "iPad 3", "iPad3,3":     "iPad 3",
/* iPad 4 */          "iPad3,4": "iPad 4", "iPad3,5": "iPad 4", "iPad3,6": "iPad 4",
/* iPad Air */        "iPad4,1": "iPad Air", "iPad4,2": "iPad Air", "iPad4,3": "iPad Air",
/* iPad Air 2 */      "iPad5,1": "iPad Air 2", "iPad5,3": "iPad Air 2", "iPad5,4": "iPad Air 2",
/* iPad Mini */       "iPad2,5": "iPad Mini 1", "iPad2,6": "iPad Mini 1", "iPad2,7": "iPad Mini 1",
/* iPad Mini 2 */     "iPad4,4": "iPad Mini 2", "iPad4,5": "iPad Mini 2", "iPad4,6": "iPad Mini 2",
/* iPad Mini 3 */     "iPad4,7": "iPad Mini 3", "iPad4,8": "iPad Mini 3", "iPad4,9": "iPad Mini 3",
/* iPad Pro 12.9 */   "iPad6,7": "iPad Pro 12.9", "iPad6,8": "iPad Pro 12.9",
/* iPad Pro  9.7 */   "iPad6,3": "iPad Pro 9.7", "iPad6,4": "iPad Pro 9.7",
/* Simulator */       "x86_64": "Simulator", "i386": "Simulator"
]


extension UIDevice {


static var modelName: String {
var systemInfo = utsname()
uname(&systemInfo)


let machine = systemInfo.machine
let mirror = Mirror(reflecting: machine)


var identifier = ""


for child in mirror.children {
if let value = child.value as? Int8, value != 0 {
identifier += String(UnicodeScalar(UInt8(value)))
}
}
return DeviceList[identifier] ?? identifier
}


static var isIphone4: Bool {
return modelName == "iPhone 5" || modelName == "iPhone 5C" || modelName == "iPhone 5S" || UIDevice.isSimulatorIPhone4
}


static var isIphone5: Bool {
return modelName == "iPhone 4S" || modelName == "iPhone 4" || UIDevice.isSimulatorIPhone5
}


static var isIphone6: Bool {
return modelName == "iPhone 6" || UIDevice.isSimulatorIPhone6
}
static var isIphone6Plus: Bool {
return modelName == "iPhone 6 Plus" || UIDevice.isSimulatorIPhone6Plus
}


static var isIpad: Bool {
if UIDevice.current.model.contains("iPad") {
return true
}
return false
}


static var isIphone: Bool {
return !self.isIpad
}


/// Check if current device is iPhone4S (and earlier) relying on screen heigth
static var isSimulatorIPhone4: Bool {
return UIDevice.isSimulatorWithScreenHeigth(480)
}


/// Check if current device is iPhone5 relying on screen heigth
static var isSimulatorIPhone5: Bool {
return UIDevice.isSimulatorWithScreenHeigth(568)
}


/// Check if current device is iPhone6 relying on screen heigth
static var isSimulatorIPhone6: Bool {
return UIDevice.isSimulatorWithScreenHeigth(667)
}


/// Check if current device is iPhone6 Plus relying on screen heigth
static var isSimulatorIPhone6Plus: Bool {
return UIDevice.isSimulatorWithScreenHeigth(736)
}


private static func isSimulatorWithScreenHeigth(_ heigth: CGFloat) -> Bool {
let screenSize: CGRect = UIScreen.main.bounds
return modelName == "Simulator" && screenSize.height == heigth
}


}

在Swift的iOS7或更高版本上完全正常工作

func DeviceName()-> String {


var myDeviceName : String = String()


var systemInfo = [UInt8](count: sizeof(utsname), repeatedValue: 0)


let model = systemInfo.withUnsafeMutableBufferPointer { (inout body: UnsafeMutableBufferPointer<UInt8>) -> String? in


if uname(UnsafeMutablePointer(body.baseAddress)) != 0 {
return nil
}


return String.fromCString(UnsafePointer(body.baseAddress.advancedBy(Int(_SYS_NAMELEN * 4))))
}


let deviceNamesByCode : [String: String] = ["iPod1,1":"iPod Touch 1",
"iPod2,1":"iPod Touch 2",
"iPod3,1":"iPod Touch 3",
"iPod4,1":"iPod Touch 4",
"iPod5,1":"iPod Touch 5",
"iPod7,1":"iPod Touch 6",
"iPhone1,1":"iPhone",
"iPhone1,2":"iPhone ",
"iPhone2,1":"iPhone ",
"iPhone3,1":"iPhone 4",
"iPhone3,2":"iPhone 4",
"iPhone3,3":"iPhone 4",
"iPhone4,1":"iPhone 4s",
"iPhone5,1":"iPhone 5",
"iPhone5,2":"iPhone 5",
"iPhone5,3":"iPhone 5c",
"iPhone5,4":"iPhone 5c",
"iPhone6,1":"iPhone 5s",
"iPhone6,2":"iPhone 5s",
"iPhone7,2":"iPhone 6",
"iPhone7,1":"iPhone 6 Plus",
"iPhone8,1":"iPhone 6s",
"iPhone8,2":"iPhone 6s Plus",
"iPhone8,4":"iPhone SE",
"iPad2,1":"iPad 2",
"iPad2,2":"iPad 2",
"iPad2,3":"iPad 2",
"iPad2,4":"iPad 2",
"iPad3,1":"iPad 3",
"iPad3,2":"iPad 3",
"iPad3,3":"iPad 3",
"iPad3,4":"iPad 4",
"iPad3,5":"iPad 4",
"iPad3,6":"iPad 4",
"iPad4,1":"iPad Air",
"iPad4,2":"iPad Air",
"iPad4,3":"iPad Air",
"iPad5,3":"iPad Air 2",
"iPad5,4":"iPad Air 2",
"iPad2,5":"iPad Mini",
"iPad2,6":"iPad Mini",
"iPad2,7":"iPad Mini",
"iPad4,4":"iPad Mini 2",
"iPad4,5":"iPad Mini 2",
"iPad4,6":"iPad Mini 2",
"iPad4,7":"iPad Mini 3",
"iPad4,8":"iPad Mini 3",
"iPad4,9":"iPad Mini 3",
"iPad5,1":"iPad Mini 4",
"iPad5,2":"iPad Mini 4",
"iPad6,3":"iPad Pro",
"iPad6,4":"iPad Pro",
"iPad6,7":"iPad Pro",
"iPad6,8":"iPad Pro",
"AppleTV5,3":"Apple TV",
"i386":"Simulator",
"x86_64":"Simulator"


]


if model!.characters.count > 0 {
myDeviceName = deviceNamesByCode[model!]!
}else{
myDeviceName = UIDevice.currentDevice().model
}


print("myDeviceName==\(myDeviceName)")
return myDeviceName


}

设备名称和机器名称,基于iOS真实设备硬件

我对这个问题的解决方案基本上看起来与这个线程中的@NicolasMiari答案有关。单独的实用程序类具有一组预定义的设备名和机器名,然后根据实际的机器名检索设备名。

注意:这个答案和它的链接GitHub项目已经更新,以确定截至2017年10月当前最新的iPhone (iPhone 8、8+、X)。这也适用于iOS11。请访问GitHub回购和看到,并给我反馈,如果有什么错误。

/*
* Retrieves back the device name or if not the machine name.
*/
+ (NSString*)deviceModelName {
struct utsname systemInfo;
uname(&systemInfo);
NSString *machineName = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    

//MARK: More official list is at
//http://theiphonewiki.com/wiki/Models
//MARK: You may just return machineName. Following is for convenience
    

NSDictionary *commonNamesDictionary =
@{
@"i386":     @"i386 Simulator",
@"x86_64":   @"x86_64 Simulator",


@"iPhone1,1":    @"iPhone",
@"iPhone1,2":    @"iPhone 3G",
@"iPhone2,1":    @"iPhone 3GS",
@"iPhone3,1":    @"iPhone 4",
@"iPhone3,2":    @"iPhone 4(Rev A)",
@"iPhone3,3":    @"iPhone 4(CDMA)",
@"iPhone4,1":    @"iPhone 4S",
@"iPhone5,1":    @"iPhone 5(GSM)",
@"iPhone5,2":    @"iPhone 5(GSM+CDMA)",
@"iPhone5,3":    @"iPhone 5c(GSM)",
@"iPhone5,4":    @"iPhone 5c(GSM+CDMA)",
@"iPhone6,1":    @"iPhone 5s(GSM)",
@"iPhone6,2":    @"iPhone 5s(GSM+CDMA)",
  

@"iPhone7,1":    @"iPhone 6+(GSM+CDMA)",
@"iPhone7,2":    @"iPhone 6(GSM+CDMA)",
  

@"iPhone8,1":    @"iPhone 6S(GSM+CDMA)",
@"iPhone8,2":    @"iPhone 6S+(GSM+CDMA)",
@"iPhone8,4":    @"iPhone SE(GSM+CDMA)",
@"iPhone9,1":    @"iPhone 7(GSM+CDMA)",
@"iPhone9,2":    @"iPhone 7+(GSM+CDMA)",
@"iPhone9,3":    @"iPhone 7(GSM+CDMA)",
@"iPhone9,4":    @"iPhone 7+(GSM+CDMA)",
  

@"iPad1,1":  @"iPad",
@"iPad2,1":  @"iPad 2(WiFi)",
@"iPad2,2":  @"iPad 2(GSM)",
@"iPad2,3":  @"iPad 2(CDMA)",
@"iPad2,4":  @"iPad 2(WiFi Rev A)",
@"iPad2,5":  @"iPad Mini 1G (WiFi)",
@"iPad2,6":  @"iPad Mini 1G (GSM)",
@"iPad2,7":  @"iPad Mini 1G (GSM+CDMA)",
@"iPad3,1":  @"iPad 3(WiFi)",
@"iPad3,2":  @"iPad 3(GSM+CDMA)",
@"iPad3,3":  @"iPad 3(GSM)",
@"iPad3,4":  @"iPad 4(WiFi)",
@"iPad3,5":  @"iPad 4(GSM)",
@"iPad3,6":  @"iPad 4(GSM+CDMA)",
  

@"iPad4,1":  @"iPad Air(WiFi)",
@"iPad4,2":  @"iPad Air(GSM)",
@"iPad4,3":  @"iPad Air(GSM+CDMA)",
  

@"iPad5,3":  @"iPad Air 2 (WiFi)",
@"iPad5,4":  @"iPad Air 2 (GSM+CDMA)",
  

@"iPad4,4":  @"iPad Mini 2G (WiFi)",
@"iPad4,5":  @"iPad Mini 2G (GSM)",
@"iPad4,6":  @"iPad Mini 2G (GSM+CDMA)",
  

@"iPad4,7":  @"iPad Mini 3G (WiFi)",
@"iPad4,8":  @"iPad Mini 3G (GSM)",
@"iPad4,9":  @"iPad Mini 3G (GSM+CDMA)",
  

@"iPod1,1":  @"iPod 1st Gen",
@"iPod2,1":  @"iPod 2nd Gen",
@"iPod3,1":  @"iPod 3rd Gen",
@"iPod4,1":  @"iPod 4th Gen",
@"iPod5,1":  @"iPod 5th Gen",
@"iPod7,1":  @"iPod 6th Gen",
};
    

NSString *deviceName = commonNamesDictionary[machineName];
    

if (deviceName == nil) {
deviceName = machineName;
}
    

return deviceName;
}

我已经在一个类中添加了这个实现和其他一些方便的实用程序方法,并将其放在GitHub库中。你也可以在这个Wiki页面中找到最新的设备信息列表。

请访问并使用它。

更新:

您可能需要导入sys框架,

#import <sys/utsname.h>

如果你有一个plist的设备(例如在https://stackoverflow.com/a/17655825/849616中由@Tib维护)来处理它,如果Swift 3你会使用:

extension UIDevice {
/// Fetches the information about the name of the device.
///
/// - Returns: Should return meaningful device name, if not found will return device system code.
public static func modelName() -> String {
let physicalName = deviceSystemCode()
if let deviceTypes = deviceTypes(), let modelName = deviceTypes[physicalName] as? String {
return modelName
}
return physicalName
}
}


private extension UIDevice {
/// Fetches from system the code of the device
static func deviceSystemCode() -> String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
return identifier
}


/// Fetches the plist entries from plist maintained in https://stackoverflow.com/a/17655825/849616
///
/// - Returns: A dictionary with pairs of deviceSystemCode <-> meaningfulDeviceName.
static func deviceTypes() -> NSDictionary? {
if let fileUrl = Bundle.main.url(forResource: "your plist name", withExtension: "plist"),
let configurationDictionary = NSDictionary(contentsOf: fileUrl) {
return configurationDictionary
}
return nil
}
}

以后你可以使用UIDevice.modelName()调用它。

额外的荣誉归于@Tib(用于plist), @Aniruddh Joshi(用于deviceSystemCode()函数)。

这个解决方案适用于物理设备和iOS模拟器,模拟器返回的模型与物理设备返回的模型相同。iPhone X (GSM)为iPhone10,6,而不是“x86_64”。

定义- Swift 4:

import UIKit


extension UIDevice {
var modelName: String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
if let value = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] {
return value
} else {
return identifier
}
}
}

用法:

print(UIDevice.current.modelName)
//
//  UIDevice+Hardware.h
//  gauravds
//


#import <UIKit/UIKit.h>


@interface UIDevice (Hardware)


- (NSString *)modelIdentifier;
- (NSString *)modelName;


@end

为什么不创建一个分类呢?不要使用malloc方法安全泄露问题。使用安全的函数。

NSLog(@"%@ %@", [[UIDevice currentDevice] modelName], [[UIDevice currentDevice] modelIdentifier]);

查看实现

//
//  UIDevice+Hardware.m
//  gauravds
//


#import "UIDevice+Hardware.h"
#import <sys/utsname.h>


@implementation UIDevice (Hardware)


- (NSString *)modelIdentifier {
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}


- (NSString *)modelName {
return [self modelNameForModelIdentifier:[self modelIdentifier]];
}


- (NSString *)modelNameForModelIdentifier:(NSString *)modelIdentifier {
// iPhone http://theiphonewiki.com/wiki/IPhone


if ([modelIdentifier isEqualToString:@"iPhone1,1"])    return @"iPhone 1G";
if ([modelIdentifier isEqualToString:@"iPhone1,2"])    return @"iPhone 3G";
if ([modelIdentifier isEqualToString:@"iPhone2,1"])    return @"iPhone 3GS";
if ([modelIdentifier isEqualToString:@"iPhone3,1"])    return @"iPhone 4 (GSM)";
if ([modelIdentifier isEqualToString:@"iPhone3,2"])    return @"iPhone 4 (GSM Rev A)";
if ([modelIdentifier isEqualToString:@"iPhone3,3"])    return @"iPhone 4 (CDMA)";
if ([modelIdentifier isEqualToString:@"iPhone4,1"])    return @"iPhone 4S";
if ([modelIdentifier isEqualToString:@"iPhone5,1"])    return @"iPhone 5 (GSM)";
if ([modelIdentifier isEqualToString:@"iPhone5,2"])    return @"iPhone 5 (Global)";
if ([modelIdentifier isEqualToString:@"iPhone5,3"])    return @"iPhone 5c (GSM)";
if ([modelIdentifier isEqualToString:@"iPhone5,4"])    return @"iPhone 5c (Global)";
if ([modelIdentifier isEqualToString:@"iPhone6,1"])    return @"iPhone 5s (GSM)";
if ([modelIdentifier isEqualToString:@"iPhone6,2"])    return @"iPhone 5s (Global)";
if ([modelIdentifier isEqualToString:@"iPhone7,1"])    return @"iPhone 6 Plus";
if ([modelIdentifier isEqualToString:@"iPhone7,2"])    return @"iPhone 6";
if ([modelIdentifier isEqualToString:@"iPhone8,1"])    return @"iPhone 6s";
if ([modelIdentifier isEqualToString:@"iPhone8,2"])    return @"iPhone 6s Plus";
if ([modelIdentifier isEqualToString:@"iPhone8,4"])    return @"iPhone SE";
if ([modelIdentifier isEqualToString:@"iPhone9,1"])    return @"iPhone 7";
if ([modelIdentifier isEqualToString:@"iPhone9,2"])    return @"iPhone 7 Plus";
if ([modelIdentifier isEqualToString:@"iPhone9,3"])    return @"iPhone 7";
if ([modelIdentifier isEqualToString:@"iPhone9,4"])    return @"iPhone 7 Plus";
if ([modelIdentifier isEqualToString:@"iPhone10,1"])   return @"iPhone 8";          // US (Verizon), China, Japan
if ([modelIdentifier isEqualToString:@"iPhone10,2"])   return @"iPhone 8 Plus";     // US (Verizon), China, Japan
if ([modelIdentifier isEqualToString:@"iPhone10,3"])   return @"iPhone X";          // US (Verizon), China, Japan
if ([modelIdentifier isEqualToString:@"iPhone10,4"])   return @"iPhone 8";          // AT&T, Global
if ([modelIdentifier isEqualToString:@"iPhone10,5"])   return @"iPhone 8 Plus";     // AT&T, Global
if ([modelIdentifier isEqualToString:@"iPhone10,6"])   return @"iPhone X";          // AT&T, Global


// iPad http://theiphonewiki.com/wiki/IPad


if ([modelIdentifier isEqualToString:@"iPad1,1"])      return @"iPad 1G";
if ([modelIdentifier isEqualToString:@"iPad2,1"])      return @"iPad 2 (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad2,2"])      return @"iPad 2 (GSM)";
if ([modelIdentifier isEqualToString:@"iPad2,3"])      return @"iPad 2 (CDMA)";
if ([modelIdentifier isEqualToString:@"iPad2,4"])      return @"iPad 2 (Rev A)";
if ([modelIdentifier isEqualToString:@"iPad3,1"])      return @"iPad 3 (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad3,2"])      return @"iPad 3 (GSM)";
if ([modelIdentifier isEqualToString:@"iPad3,3"])      return @"iPad 3 (Global)";
if ([modelIdentifier isEqualToString:@"iPad3,4"])      return @"iPad 4 (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad3,5"])      return @"iPad 4 (GSM)";
if ([modelIdentifier isEqualToString:@"iPad3,6"])      return @"iPad 4 (Global)";
if ([modelIdentifier isEqualToString:@"iPad6,11"])     return @"iPad (5th gen) (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad6,12"])     return @"iPad (5th gen) (Cellular)";


if ([modelIdentifier isEqualToString:@"iPad4,1"])      return @"iPad Air (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad4,2"])      return @"iPad Air (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad5,3"])      return @"iPad Air 2 (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad5,4"])      return @"iPad Air 2 (Cellular)";


// iPad Mini http://theiphonewiki.com/wiki/IPad_mini


if ([modelIdentifier isEqualToString:@"iPad2,5"])      return @"iPad mini 1G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad2,6"])      return @"iPad mini 1G (GSM)";
if ([modelIdentifier isEqualToString:@"iPad2,7"])      return @"iPad mini 1G (Global)";
if ([modelIdentifier isEqualToString:@"iPad4,4"])      return @"iPad mini 2G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad4,5"])      return @"iPad mini 2G (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad4,6"])      return @"iPad mini 2G (Cellular)"; // TD-LTE model see https://support.apple.com/en-us/HT201471#iPad-mini2
if ([modelIdentifier isEqualToString:@"iPad4,7"])      return @"iPad mini 3G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad4,8"])      return @"iPad mini 3G (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad4,9"])      return @"iPad mini 3G (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad5,1"])      return @"iPad mini 4G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad5,2"])      return @"iPad mini 4G (Cellular)";


// iPad Pro https://www.theiphonewiki.com/wiki/IPad_Pro


if ([modelIdentifier isEqualToString:@"iPad6,3"])      return @"iPad Pro (9.7 inch) 1G (Wi-Fi)"; // http://pdadb.net/index.php?m=specs&id=9938&c=apple_ipad_pro_9.7-inch_a1673_wifi_32gb_apple_ipad_6,3
if ([modelIdentifier isEqualToString:@"iPad6,4"])      return @"iPad Pro (9.7 inch) 1G (Cellular)"; // http://pdadb.net/index.php?m=specs&id=9981&c=apple_ipad_pro_9.7-inch_a1675_td-lte_32gb_apple_ipad_6,4
if ([modelIdentifier isEqualToString:@"iPad6,7"])      return @"iPad Pro (12.9 inch) 1G (Wi-Fi)"; // http://pdadb.net/index.php?m=specs&id=8960&c=apple_ipad_pro_wifi_a1584_128gb
if ([modelIdentifier isEqualToString:@"iPad6,8"])      return @"iPad Pro (12.9 inch) 1G (Cellular)"; // http://pdadb.net/index.php?m=specs&id=8965&c=apple_ipad_pro_td-lte_a1652_32gb_apple_ipad_6,8
if ([modelIdentifier isEqualToString:@"iPad 7,1"])     return @"iPad Pro (12.9 inch) 2G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad 7,2"])     return @"iPad Pro (12.9 inch) 2G (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad 7,3"])     return @"iPad Pro (10.5 inch) 1G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad 7,4"])     return @"iPad Pro (10.5 inch) 1G (Cellular)";


// iPod http://theiphonewiki.com/wiki/IPod


if ([modelIdentifier isEqualToString:@"iPod1,1"])      return @"iPod touch 1G";
if ([modelIdentifier isEqualToString:@"iPod2,1"])      return @"iPod touch 2G";
if ([modelIdentifier isEqualToString:@"iPod3,1"])      return @"iPod touch 3G";
if ([modelIdentifier isEqualToString:@"iPod4,1"])      return @"iPod touch 4G";
if ([modelIdentifier isEqualToString:@"iPod5,1"])      return @"iPod touch 5G";
if ([modelIdentifier isEqualToString:@"iPod7,1"])      return @"iPod touch 6G"; // as 6,1 was never released 7,1 is actually 6th generation


// Apple TV https://www.theiphonewiki.com/wiki/Apple_TV


if ([modelIdentifier isEqualToString:@"AppleTV1,1"])      return @"Apple TV 1G";
if ([modelIdentifier isEqualToString:@"AppleTV2,1"])      return @"Apple TV 2G";
if ([modelIdentifier isEqualToString:@"AppleTV3,1"])      return @"Apple TV 3G";
if ([modelIdentifier isEqualToString:@"AppleTV3,2"])      return @"Apple TV 3G"; // small, incremental update over 3,1
if ([modelIdentifier isEqualToString:@"AppleTV5,3"])      return @"Apple TV 4G"; // as 4,1 was never released, 5,1 is actually 4th generation


// Simulator
if ([modelIdentifier hasSuffix:@"86"] || [modelIdentifier isEqual:@"x86_64"])
{
BOOL smallerScreen = ([[UIScreen mainScreen] bounds].size.width < 768.0);
return (smallerScreen ? @"iPhone Simulator" : @"iPad Simulator");
}


return modelIdentifier;
}


@end

为他人节省时间。 因为接受,必须投票回答建议库使用私人API和我的应用程序被拒绝,因为uidevice-extension就在昨天! 我正在切换到GBDeviceInfo库,安装为pod,目前它看起来不错,维护和更新到最新的设备

Swift 4或更高版本

extension UIDevice {
var modelName: String {
if let modelName = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] { return modelName }
var info = utsname()
uname(&info)
return String(String.UnicodeScalarView(
Mirror(reflecting: info.machine)
.children
.compactMap {
guard let value = $0.value as? Int8 else { return nil }
let unicode = UnicodeScalar(UInt8(value))
return unicode.isASCII ? unicode : nil
}))
}
}

UIDevice.current.modelName   // "iPad6,4"

使用ideviceinfo来获取这些值怎么样?应该能够安装它使用brew install ideviceinfo

然后运行:

PRODUCT_NAME=$(ideviceinfo --udid $DEVICE_UDID --key ProductName)
PRODUCT_TYPE=$(ideviceinfo --udid $DEVICE_UDID --key ProductType)
PRODUCT_VERSION=$(ideviceinfo --udid $DEVICE_UDID --key ProductVersion)

添加一个带有以下代码的新文件,并简单地调用UIDevice.modelName。该文件包含迄今为止发布的所有型号,包括iPhone 13系列和斯威夫特5.0

import UIKit
import SystemConfiguration


public extension UIDevice {
static let modelName: String = {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
        

let deviceMapping = ["i386": "iPhone Simulator",
"x86_64": "iPhone Simulator",
"arm64": "iPhone Simulator",
"iPhone1,1": "iPhone",
"iPhone1,2": "iPhone 3G",
"iPhone2,1": "iPhone 3GS",
"iPhone3,1": "iPhone 4",
"iPhone3,2": "iPhone 4 GSM Rev A",
"iPhone3,3": "iPhone 4 CDMA",
"iPhone4,1": "iPhone 4S",
"iPhone5,1": "iPhone 5 (GSM)",
"iPhone5,2": "iPhone 5 (GSM+CDMA)",
"iPhone5,3": "iPhone 5C (GSM)",
"iPhone5,4": "iPhone 5C (Global)",
"iPhone6,1": "iPhone 5S (GSM)",
"iPhone6,2": "iPhone 5S (Global)",
"iPhone7,1": "iPhone 6 Plus",
"iPhone7,2": "iPhone 6",
"iPhone8,1": "iPhone 6s",
"iPhone8,2": "iPhone 6s Plus",
"iPhone8,4": "iPhone SE (GSM)",
"iPhone9,1": "iPhone 7",
"iPhone9,2": "iPhone 7 Plus",
"iPhone9,3": "iPhone 7",
"iPhone9,4": "iPhone 7 Plus",
"iPhone10,1": "iPhone 8",
"iPhone10,2": "iPhone 8 Plus",
"iPhone10,3": "iPhone X Global",
"iPhone10,4": "iPhone 8",
"iPhone10,5": "iPhone 8 Plus",
"iPhone10,6": "iPhone X GSM",
"iPhone11,2": "iPhone XS",
"iPhone11,4": "iPhone XS Max",
"iPhone11,6": "iPhone XS Max Global",
"iPhone11,8": "iPhone XR",
"iPhone12,1": "iPhone 11",
"iPhone12,3": "iPhone 11 Pro",
"iPhone12,5": "iPhone 11 Pro Max",
"iPhone12,8": "iPhone SE 2nd Gen",
"iPhone13,1": "iPhone 12 Mini",
"iPhone13,2": "iPhone 12",
"iPhone13,3": "iPhone 12 Pro",
"iPhone13,4": "iPhone 12 Pro Max",
"iPhone14,2": "iPhone 13 Pro",
"iPhone14,3": "iPhone 13 Pro Max",
"iPhone14,4": "iPhone 13 Mini",
"iPhone14,5": "iPhone 13",
"iPod1,1": "1st Gen iPod",
"iPod2,1": "2nd Gen iPod",
"iPod3,1": "3rd Gen iPod",
"iPod4,1": "4th Gen iPod",
"iPod5,1": "5th Gen iPod",
"iPod7,1": "6th Gen iPod",
"iPod9,1": "7th Gen iPod",
"iPad1,1": "iPad",
"iPad1,2": "iPad 3G",
"iPad2,1": "2nd Gen iPad",
"iPad2,2": "2nd Gen iPad GSM",
"iPad2,3": "2nd Gen iPad CDMA",
"iPad2,4": "2nd Gen iPad New Revision",
"iPad3,1": "3rd Gen iPad",
"iPad3,2": "3rd Gen iPad CDMA",
"iPad3,3": "3rd Gen iPad GSM",
"iPad2,5": "iPad mini",
"iPad2,6": "iPad mini GSM+LTE",
"iPad2,7": "iPad mini CDMA+LTE",
"iPad3,4": "4th Gen iPad",
"iPad3,5": "4th Gen iPad GSM+LTE",
"iPad3,6": "4th Gen iPad CDMA+LTE",
"iPad4,1": "iPad Air (WiFi)",
"iPad4,2": "iPad Air (GSM+CDMA)",
"iPad4,3": "1st Gen iPad Air (China)",
"iPad4,4": "iPad mini Retina (WiFi)",
"iPad4,5": "iPad mini Retina (GSM+CDMA)",
"iPad4,6": "iPad mini Retina (China)",
"iPad4,7": "iPad mini 3 (WiFi)",
"iPad4,8": "iPad mini 3 (GSM+CDMA)",
"iPad4,9": "iPad Mini 3 (China)",
"iPad5,1": "iPad mini 4 (WiFi)",
"iPad5,2": "4th Gen iPad mini (WiFi+Cellular)",
"iPad5,3": "iPad Air 2 (WiFi)",
"iPad5,4": "iPad Air 2 (Cellular)",
"iPad6,3": "iPad Pro (9.7 inch, WiFi)",
"iPad6,4": "iPad Pro (9.7 inch, WiFi+LTE)",
"iPad6,7": "iPad Pro (12.9 inch, WiFi)",
"iPad6,8": "iPad Pro (12.9 inch, WiFi+LTE)",
"iPad6,11": "iPad (2017)",
"iPad6,12": "iPad (2017)",
"iPad7,1": "iPad Pro 2nd Gen (WiFi)",
"iPad7,2": "iPad Pro 2nd Gen (WiFi+Cellular)",
"iPad7,3": "iPad Pro 10.5-inch",
"iPad7,4": "iPad Pro 10.5-inch",
"iPad7,5": "iPad 6th Gen (WiFi)",
"iPad7,6": "iPad 6th Gen (WiFi+Cellular)",
"iPad7,11": "iPad 7th Gen 10.2-inch (WiFi)",
"iPad7,12": "iPad 7th Gen 10.2-inch (WiFi+Cellular)",
"iPad8,1": "iPad Pro 11 inch 3rd Gen (WiFi)",
"iPad8,2": "iPad Pro 11 inch 3rd Gen (1TB, WiFi)",
"iPad8,3": "iPad Pro 11 inch 3rd Gen (WiFi+Cellular)",
"iPad8,4": "iPad Pro 11 inch 3rd Gen (1TB, WiFi+Cellular)",
"iPad8,5": "iPad Pro 12.9 inch 3rd Gen (WiFi)",
"iPad8,6": "iPad Pro 12.9 inch 3rd Gen (1TB, WiFi)",
"iPad8,7": "iPad Pro 12.9 inch 3rd Gen (WiFi+Cellular)",
"iPad8,8": "iPad Pro 12.9 inch 3rd Gen (1TB, WiFi+Cellular)",
"iPad8,9": "iPad Pro 11 inch 4th Gen (WiFi)",
"iPad8,10": "iPad Pro 11 inch 4th Gen (WiFi+Cellular)",
"iPad8,11": "iPad Pro 12.9 inch 4th Gen (WiFi)",
"iPad8,12": "iPad Pro 12.9 inch 4th Gen (WiFi+Cellular)",
"iPad11,1": "iPad mini 5th Gen (WiFi)",
"iPad11,2": "iPad mini 5th Gen",
"iPad11,3": "iPad Air 3rd Gen (WiFi)",
"iPad11,4": "iPad Air 3rd Gen",
"iPad11,6": "iPad 8th Gen (WiFi)",
"iPad11,7": "iPad 8th Gen (WiFi+Cellular)",
"iPad13,1": "iPad air 4th Gen (WiFi)",
"iPad13,2": "iPad air 4th Gen (WiFi+Cellular)",
"iPad13,4": "iPad Pro 11 inch 3rd Gen",
"iPad13,5": "iPad Pro 11 inch 3rd Gen",
"iPad13,6": "iPad Pro 11 inch 3rd Gen",
"iPad13,7": "iPad Pro 11 inch 3rd Gen",
"iPad13,8": "iPad Pro 12.9 inch 5th Gen",
"iPad13,9": "iPad Pro 12.9 inch 5th Gen",
"iPad13,10": "iPad Pro 12.9 inch 5th Gen",
"iPad13,11": "iPad Pro 12.9 inch 5th Gen"]
return deviceMapping[identifier] ?? identifier
}()
}

芬兰湾的科特林本机:

memScoped {
val q = alloc<utsname>()
uname(q.ptr)
val identifier = NSString.stringWithCString(q.machine, encoding = NSUTF8StringEncoding)
}

下面是一个现代版本的Aniruddh基于__abc0的方法,它不依赖于Mirror,应该适用于Swift 4.2及更高版本:

import UIKit


extension UIDevice {
var machineName: String {
var info = utsname()
return withUnsafeMutablePointer(to: &info) { info in
// We could alternatively return nil here, or handle
// errors some other way.
guard uname(info) == 0 else { return model }
let offset = MemoryLayout.offset(of: \utsname.machine)!
let machine = UnsafeRawPointer(info).advanced(by: offset).assumingMemoryBound(to: CChar.self)
return String(cString: machine)
}
}
}

不使用镜像也可以在Swift中获取设备名称。Swift可以在需要的地方自动将内容转换为指针。其实很简单:

/// Returns "iPhone1,1", etc.
var deviceName: String {
var sysinfo = utsname()
uname(&sysinfo)
return String(cString: &sysinfo.machine.0)
}

(向这个被低估的答案https://stackoverflow.com/a/43599474/843454致敬)

虽然这个问题在2012年就被提出了,但苹果仍然没有给出一种将设备模式标识符转换为设备名称的方法。 有很多答案依赖于硬编码这些名称,不幸的是,当苹果发布新设备时,这些名称很快就过时了

我们需要的是一种方法来获取一个不断更新的列表,它存在于这里:https://github.com/ptrkstr/Devices

每次添加新设备时,这个Swift包都会更新,你所需要做的就是更新你的依赖项来获得它们。

对于那些不想使用Swift的Mirror的人来说,这里有一个使用普通类型的解决方案(也支持模拟器):

#if targetEnvironment(simulator)
@objc public protocol UIDevicePrivate {
@objc func _deviceInfoForKey(_:String) -> Any?
}
#endif


extension UIDevice {
var hardwareModel: String {
#if targetEnvironment(simulator)
let privateSelf = unsafeBitCast(self, to:UIDevicePrivate.self)
if let model = privateSelf._deviceInfoForKey("HWModelStr") as? String {
return model + " (Simulator)"
}
#endif
var systemInfo = utsname()
uname(&systemInfo)
return String(characters: systemInfo.machine)
}
}


typealias StaticArray256<Element> = (Element, Element, Element,Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element)


// This function is necessary because Swift really doesn't like creating a 256 element long static array


func enumerate<T>(tuple: StaticArray256<T>, body: (Int, T) -> Void) {
body(0, tuple.0)
body(1, tuple.1)
body(2, tuple.2)
body(3, tuple.3)
body(4, tuple.4)
body(5, tuple.5)
body(6, tuple.6)
body(7, tuple.7)
body(8, tuple.8)
body(9, tuple.9)
body(10, tuple.10)
body(11, tuple.11)
body(12, tuple.12)
body(13, tuple.13)
body(14, tuple.14)
body(15, tuple.15)
body(16, tuple.16)
body(17, tuple.17)
body(18, tuple.18)
body(19, tuple.19)
body(20, tuple.20)
body(21, tuple.21)
body(22, tuple.22)
body(23, tuple.23)
body(24, tuple.24)
body(25, tuple.25)
body(26, tuple.26)
body(27, tuple.27)
body(28, tuple.28)
body(29, tuple.29)
body(30, tuple.30)
body(31, tuple.31)
body(32, tuple.32)
body(33, tuple.33)
body(34, tuple.34)
body(35, tuple.35)
body(36, tuple.36)
body(37, tuple.37)
body(38, tuple.38)
body(39, tuple.39)
body(40, tuple.40)
body(41, tuple.41)
body(42, tuple.42)
body(43, tuple.43)
body(44, tuple.44)
body(45, tuple.45)
body(46, tuple.46)
body(47, tuple.47)
body(48, tuple.48)
body(49, tuple.49)
body(50, tuple.50)
body(51, tuple.51)
body(52, tuple.52)
body(53, tuple.53)
body(54, tuple.54)
body(55, tuple.55)
body(56, tuple.56)
body(57, tuple.57)
body(58, tuple.58)
body(59, tuple.59)
body(60, tuple.60)
body(61, tuple.61)
body(62, tuple.62)
body(63, tuple.63)
body(64, tuple.64)
body(65, tuple.65)
body(66, tuple.66)
body(67, tuple.67)
body(68, tuple.68)
body(69, tuple.69)
body(70, tuple.70)
body(71, tuple.71)
body(72, tuple.72)
body(73, tuple.73)
body(74, tuple.74)
body(75, tuple.75)
body(76, tuple.76)
body(77, tuple.77)
body(78, tuple.78)
body(79, tuple.79)
body(80, tuple.80)
body(81, tuple.81)
body(82, tuple.82)
body(83, tuple.83)
body(84, tuple.84)
body(85, tuple.85)
body(86, tuple.86)
body(87, tuple.87)
body(88, tuple.88)
body(89, tuple.89)
body(90, tuple.90)
body(91, tuple.91)
body(92, tuple.92)
body(93, tuple.93)
body(94, tuple.94)
body(95, tuple.95)
body(96, tuple.96)
body(97, tuple.97)
body(98, tuple.98)
body(99, tuple.99)
body(100, tuple.100)
body(101, tuple.101)
body(102, tuple.102)
body(103, tuple.103)
body(104, tuple.104)
body(105, tuple.105)
body(106, tuple.106)
body(107, tuple.107)
body(108, tuple.108)
body(109, tuple.109)
body(110, tuple.110)
body(111, tuple.111)
body(112, tuple.112)
body(113, tuple.113)
body(114, tuple.114)
body(115, tuple.115)
body(116, tuple.116)
body(117, tuple.117)
body(118, tuple.118)
body(119, tuple.119)
body(120, tuple.120)
body(121, tuple.121)
body(122, tuple.122)
body(123, tuple.123)
body(124, tuple.124)
body(125, tuple.125)
body(126, tuple.126)
body(127, tuple.127)
body(128, tuple.128)
body(129, tuple.129)
body(130, tuple.130)
body(131, tuple.131)
body(132, tuple.132)
body(133, tuple.133)
body(134, tuple.134)
body(135, tuple.135)
body(136, tuple.136)
body(137, tuple.137)
body(138, tuple.138)
body(139, tuple.139)
body(140, tuple.140)
body(141, tuple.141)
body(142, tuple.142)
body(143, tuple.143)
body(144, tuple.144)
body(145, tuple.145)
body(146, tuple.146)
body(147, tuple.147)
body(148, tuple.148)
body(149, tuple.149)
body(150, tuple.150)
body(151, tuple.151)
body(152, tuple.152)
body(153, tuple.153)
body(154, tuple.154)
body(155, tuple.155)
body(156, tuple.156)
body(157, tuple.157)
body(158, tuple.158)
body(159, tuple.159)
body(160, tuple.160)
body(161, tuple.161)
body(162, tuple.162)
body(163, tuple.163)
body(164, tuple.164)
body(165, tuple.165)
body(166, tuple.166)
body(167, tuple.167)
body(168, tuple.168)
body(169, tuple.169)
body(170, tuple.170)
body(171, tuple.171)
body(172, tuple.172)
body(173, tuple.173)
body(174, tuple.174)
body(175, tuple.175)
body(176, tuple.176)
body(177, tuple.177)
body(178, tuple.178)
body(179, tuple.179)
body(180, tuple.180)
body(181, tuple.181)
body(182, tuple.182)
body(183, tuple.183)
body(184, tuple.184)
body(185, tuple.185)
body(186, tuple.186)
body(187, tuple.187)
body(188, tuple.188)
body(189, tuple.189)
body(190, tuple.190)
body(191, tuple.191)
body(192, tuple.192)
body(193, tuple.193)
body(194, tuple.194)
body(195, tuple.195)
body(196, tuple.196)
body(197, tuple.197)
body(198, tuple.198)
body(199, tuple.199)
body(200, tuple.200)
body(201, tuple.201)
body(202, tuple.202)
body(203, tuple.203)
body(204, tuple.204)
body(205, tuple.205)
body(206, tuple.206)
body(207, tuple.207)
body(208, tuple.208)
body(209, tuple.209)
body(210, tuple.210)
body(211, tuple.211)
body(212, tuple.212)
body(213, tuple.213)
body(214, tuple.214)
body(215, tuple.215)
body(216, tuple.216)
body(217, tuple.217)
body(218, tuple.218)
body(219, tuple.219)
body(220, tuple.220)
body(221, tuple.221)
body(222, tuple.222)
body(223, tuple.223)
body(224, tuple.224)
body(225, tuple.225)
body(226, tuple.226)
body(227, tuple.227)
body(228, tuple.228)
body(229, tuple.229)
body(230, tuple.230)
body(231, tuple.231)
body(232, tuple.232)
body(233, tuple.233)
body(234, tuple.234)
body(235, tuple.235)
body(236, tuple.236)
body(237, tuple.237)
body(238, tuple.238)
body(239, tuple.239)
body(240, tuple.240)
body(241, tuple.241)
body(242, tuple.242)
body(243, tuple.243)
body(244, tuple.244)
body(245, tuple.245)
body(246, tuple.246)
body(247, tuple.247)
body(248, tuple.248)
body(249, tuple.249)
body(250, tuple.250)
body(251, tuple.251)
body(252, tuple.252)
body(253, tuple.253)
body(254, tuple.254)
body(255, tuple.255)
}


extension Array {
init(staticArray: StaticArray256<Element>) {
var array = [Element]()
enumerate(tuple: staticArray) { array.append($1) }
self = array
}
}


extension String {
init(characters: StaticArray256<CChar>) {
self.init(String.UnicodeScalarView(Array(staticArray: characters).compactMap(Int.init).filter({ $0 > 0 }).compactMap(UnicodeScalar.init)))
}
}