关于iOS:如何确定当前的iPhone/设备型号?

How to determine the current iPhone/device model?

is the Way to get there a device name(iPhone 4S模式的iPhone,iPhone 5、5S等)迅速?P></

我知道UIDevice.currentDevice().modelbut there is only a named property恩归来device type(iPhone,iPad,iPod,iPhone simulator,等)。P></

它也知道can be done的easily在Objective-C with this method:P></

1
2
3
4
5
6
7
#import <sys/utsname.h>

struct utsname systemInfo;
uname(&systemInfo);

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

但我知道我的iPhone应用程序开发一个快速的方式帮助我Please to this with the等价快速解决?P></


我在UIDevice上做了这个"纯粹的快速"扩展。

此版本适用于Swift 2或更高版本如果使用较早版本,请使用较早版本的我的答案。

如果您正在寻找更优雅的解决方案,您可以使用我在Github上发布的μ-框架DeviceKit(也可通过Cocoapods、Carthage和Swift Package Manager获得)。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import UIKit

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)))
        }

        func mapToDevice(identifier: String) -> String { // swiftlint:disable:this cyclomatic_complexity
            #if os(iOS)
            switch identifier {
            case"iPod5,1":                                 return"iPod Touch 5"
            case"iPod7,1":                                 return"iPod Touch 6"
            case"iPhone3,1","iPhone3,2","iPhone3,3":     return"iPhone 4"
            case"iPhone4,1":                               return"iPhone 4s"
            case"iPhone5,1","iPhone5,2":                  return"iPhone 5"
            case"iPhone5,3","iPhone5,4":                  return"iPhone 5c"
            case"iPhone6,1","iPhone6,2":                  return"iPhone 5s"
            case"iPhone7,2":                               return"iPhone 6"
            case"iPhone7,1":                               return"iPhone 6 Plus"
            case"iPhone8,1":                               return"iPhone 6s"
            case"iPhone8,2":                               return"iPhone 6s Plus"
            case"iPhone9,1","iPhone9,3":                  return"iPhone 7"
            case"iPhone9,2","iPhone9,4":                  return"iPhone 7 Plus"
            case"iPhone8,4":                               return"iPhone SE"
            case"iPhone10,1","iPhone10,4":                return"iPhone 8"
            case"iPhone10,2","iPhone10,5":                return"iPhone 8 Plus"
            case"iPhone10,3","iPhone10,6":                return"iPhone X"
            case"iPhone11,2":                              return"iPhone XS"
            case"iPhone11,4","iPhone11,6":                return"iPhone XS Max"
            case"iPhone11,8":                              return"iPhone XR"
            case"iPad2,1","iPad2,2","iPad2,3","iPad2,4":return"iPad 2"
            case"iPad3,1","iPad3,2","iPad3,3":           return"iPad 3"
            case"iPad3,4","iPad3,5","iPad3,6":           return"iPad 4"
            case"iPad4,1","iPad4,2","iPad4,3":           return"iPad Air"
            case"iPad5,3","iPad5,4":                      return"iPad Air 2"
            case"iPad6,11","iPad6,12":                    return"iPad 5"
            case"iPad7,5","iPad7,6":                      return"iPad 6"
            case"iPad11,4","iPad11,5":                    return"iPad Air (3rd generation)"
            case"iPad2,5","iPad2,6","iPad2,7":           return"iPad Mini"
            case"iPad4,4","iPad4,5","iPad4,6":           return"iPad Mini 2"
            case"iPad4,7","iPad4,8","iPad4,9":           return"iPad Mini 3"
            case"iPad5,1","iPad5,2":                      return"iPad Mini 4"
            case"iPad11,1","iPad11,2":                    return"iPad Mini 5"
            case"iPad6,3","iPad6,4":                      return"iPad Pro (9.7-inch)"
            case"iPad6,7","iPad6,8":                      return"iPad Pro (12.9-inch)"
            case"iPad7,1","iPad7,2":                      return"iPad Pro (12.9-inch) (2nd generation)"
            case"iPad7,3","iPad7,4":                      return"iPad Pro (10.5-inch)"
            case"iPad8,1","iPad8,2","iPad8,3","iPad8,4":return"iPad Pro (11-inch)"
            case"iPad8,5","iPad8,6","iPad8,7","iPad8,8":return"iPad Pro (12.9-inch) (3rd generation)"
            case"AppleTV5,3":                              return"Apple TV"
            case"AppleTV6,2":                              return"Apple TV 4K"
            case"AudioAccessory1,1":                       return"HomePod"
            case"i386","x86_64":                          return"Simulator \(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ??"iOS"))"
            default:                                        return identifier
            }
            #elseif os(tvOS)
            switch identifier {
            case"AppleTV5,3": return"Apple TV 4"
            case"AppleTV6,2": return"Apple TV 4K"
            case"i386","x86_64": return"Simulator \(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ??"tvOS"))"
            default: return identifier
            }
            #endif
        }

        return mapToDevice(identifier: identifier)
    }()

}

你这样称呼它:

1
let modelName = UIDevice.modelName

对于真实设备,它返回"ipad pro 9.7英寸",对于模拟器,它返回"模拟器"+模拟器标识符,例如"ipad pro 9.7英寸模拟器"


这个swift 3.0示例将当前设备模型返回为enum常量(以避免直接与字符串文本进行比较)。枚举的原始值是包含人类可读的iOS设备名称的String。由于它是Swift,因此识别设备的列表仅包括最近足以支持iOS版本(包括Swift)的型号。下面的使用示例使用此答案末尾的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    switch UIDevice().type {
    case .iPhone5:
              print("No TouchID sensor")
    case .iPhone5S:
              fallthrough
    case .iPhone6:
              fallthrough
    case .iPhone6plus:
              fallthrough
    case .iPad_Pro9_7:
              fallthrough
    case .iPad_Pro12_9:
              fallthrough
    case .iPhone7:
              fallthrough
    case .iPhone7plus:
              print("Put your thumb on the" +
                     UIDevice().type.rawValue +" TouchID sensor")
    case .unrecognized:
              print("Device model unrecognized");
    default:
              print(UIDevice().type.rawValue +" not supported by this app");
    }

当苹果为同一个设备系列添加新型号时,您的应用程序应保持最新,以适应新的设备版本。例如,iphone3,1 iphone3,2 iphone3,4都是"iphone4"。避免编写不适用于新型号的代码,这样算法就不会意外地无法配置或响应新设备。您可以参考此维护的iOS设备型号列表,在战略时刻更新您的应用程序。

iOS包括独立于设备的接口,用于检测硬件功能和屏幕大小等参数。苹果提供的通用接口通常是最安全、最受支持的机制,可以动态地使应用程序的行为适应不同的硬件。然而,以下代码对于原型、调试、测试或任何时候代码需要针对特定设备系列都很有用。该技术还可以用来描述当前设备的通用/公开识别名称。

斯威夫特3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// 1. Declare outside class definition (or in its own file).
// 2. UIKit must be included in file where this code is added.
// 3. Extends UIDevice class, thus is available anywhere in app.
//
// Usage example:
//
//    if UIDevice().type == .simulator {
//       print("You're running on the simulator... boring!")
//    } else {
//       print("Wow! Running on a \(UIDevice().type.rawValue)")
//    }
import UIKit

public enum Model : String {
    case simulator   ="simulator/sandbox",
    iPod1            ="iPod 1",
    iPod2            ="iPod 2",
    iPod3            ="iPod 3",
    iPod4            ="iPod 4",
    iPod5            ="iPod 5",
    iPad2            ="iPad 2",
    iPad3            ="iPad 3",
    iPad4            ="iPad 4",
    iPhone4          ="iPhone 4",
    iPhone4S         ="iPhone 4S",
    iPhone5          ="iPhone 5",
    iPhone5S         ="iPhone 5S",
    iPhone5C         ="iPhone 5C",
    iPadMini1        ="iPad Mini 1",
    iPadMini2        ="iPad Mini 2",
    iPadMini3        ="iPad Mini 3",
    iPadAir1         ="iPad Air 1",
    iPadAir2         ="iPad Air 2",
    iPadPro9_7       ="iPad Pro 9.7"",
    iPadPro9_7_cell  ="iPad Pro 9.7" cellular",
    iPadPro10_5      ="iPad Pro 10.5"",
    iPadPro10_5_cell ="iPad Pro 10.5" cellular",
    iPadPro12_9      ="iPad Pro 12.9"",
    iPadPro12_9_cell ="iPad Pro 12.9" cellular",
    iPhone6          ="iPhone 6",
    iPhone6plus      ="iPhone 6 Plus",
    iPhone6S         ="iPhone 6S",
    iPhone6Splus     ="iPhone 6S Plus",
    iPhoneSE         ="iPhone SE",
    iPhone7          ="iPhone 7",
    iPhone7plus      ="iPhone 7 Plus",
    iPhone8          ="iPhone 8",
    iPhone8plus      ="iPhone 8 Plus",
    iPhoneX          ="iPhone X",
    iPhoneXS         ="iPhone XS",
    iPhoneXSmax      ="iPhone XS Max",
    iPhoneXR         ="iPhone XR",
    unrecognized     ="?unrecognized?"
}

public extension UIDevice {
    public var type: Model {
        var systemInfo = utsname()
        uname(&systemInfo)
        let modelCode = withUnsafePointer(to: &systemInfo.machine) {
            $0.withMemoryRebound(to: CChar.self, capacity: 1) {
                ptr in String.init(validatingUTF8: ptr)

            }
        }
        var modelMap : [ String : Model ] = [
           "i386"       : .simulator,
           "x86_64"     : .simulator,
           "iPod1,1"    : .iPod1,
           "iPod2,1"    : .iPod2,
           "iPod3,1"    : .iPod3,
           "iPod4,1"    : .iPod4,
           "iPod5,1"    : .iPod5,
           "iPad2,1"    : .iPad2,
           "iPad2,2"    : .iPad2,
           "iPad2,3"    : .iPad2,
           "iPad2,4"    : .iPad2,
           "iPad2,5"    : .iPadMini1,
           "iPad2,6"    : .iPadMini1,
           "iPad2,7"    : .iPadMini1,
           "iPhone3,1"  : .iPhone4,
           "iPhone3,2"  : .iPhone4,
           "iPhone3,3"  : .iPhone4,
           "iPhone4,1"  : .iPhone4S,
           "iPhone5,1"  : .iPhone5,
           "iPhone5,2"  : .iPhone5,
           "iPhone5,3"  : .iPhone5C,
           "iPhone5,4"  : .iPhone5C,
           "iPad3,1"    : .iPad3,
           "iPad3,2"    : .iPad3,
           "iPad3,3"    : .iPad3,
           "iPad3,4"    : .iPad4,
           "iPad3,5"    : .iPad4,
           "iPad3,6"    : .iPad4,
           "iPhone6,1"  : .iPhone5S,
           "iPhone6,2"  : .iPhone5S,
           "iPad4,1"    : .iPadAir1,
           "iPad4,2"    : .iPadAir2,
           "iPad4,4"    : .iPadMini2,
           "iPad4,5"    : .iPadMini2,
           "iPad4,6"    : .iPadMini2,
           "iPad4,7"    : .iPadMini3,
           "iPad4,8"    : .iPadMini3,
           "iPad4,9"    : .iPadMini3,
           "iPad6,3"    : .iPadPro9_7,
           "iPad6,11"   : .iPadPro9_7,
           "iPad6,4"    : .iPadPro9_7_cell,
           "iPad6,12"   : .iPadPro9_7_cell,
           "iPad6,7"    : .iPadPro12_9,
           "iPad6,8"    : .iPadPro12_9_cell,
           "iPad7,3"    : .iPadPro10_5,
           "iPad7,4"    : .iPadPro10_5_cell,
           "iPhone7,1"  : .iPhone6plus,
           "iPhone7,2"  : .iPhone6,
           "iPhone8,1"  : .iPhone6S,
           "iPhone8,2"  : .iPhone6Splus,
           "iPhone8,4"  : .iPhoneSE,
           "iPhone9,1"  : .iPhone7,
           "iPhone9,2"  : .iPhone7plus,
           "iPhone9,3"  : .iPhone7,
           "iPhone9,4"  : .iPhone7plus,
           "iPhone10,1" : .iPhone8,
           "iPhone10,2" : .iPhone8plus,
           "iPhone10,3" : .iPhoneX,
           "iPhone10,6" : .iPhoneX,
           "iPhone11,2" : .iPhoneXS,
           "iPhone11,4" : .iPhoneXSmax,
           "iPhone11,6" : .iPhoneXSmax,
           "iPhone11,8" : .iPhoneXR
        ]

    if let model = modelMap[String.init(validatingUTF8: modelCode!)!] {
            return model
        }
        return Model.unrecognized
    }
}


还有另一种/简单的替代方法(模型标识符引用可在https://www.theiphonewiki.com/wiki/models上找到):

更新了Swift 3/4/5的答案,包括字符串修剪和模拟器支持:

1
2
3
4
5
6
func modelIdentifier() -> String {
    if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] { return simulatorModelIdentifier }
    var sysinfo = utsname()
    uname(&sysinfo) // ignore return value
    return String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)
}

Swift 2的原始答案:

1
2
3
4
5
func modelIdentifier() -> String {
    var sysinfo = utsname()
    uname(&sysinfo) // ignore return value
    return NSString(bytes: &sysinfo.machine, length: Int(_SYS_NAMELEN), encoding: NSASCIIStringEncoding)! as String
    }


Swift 5两个设备/模拟器

以及最新的ipad pro 11",ipad air 3 gen.和ipad pro 3 gen.

P.S.(此方法还检测正确的模型(如果是模拟器)和所用模拟器设备模型的确切名称….):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
public enum Model : String {
    case simulator     ="simulator/sandbox",
    //iPod
    iPod1              ="iPod 1",
    iPod2              ="iPod 2",
    iPod3              ="iPod 3",
    iPod4              ="iPod 4",
    iPod5              ="iPod 5",
    //iPad
    iPad2              ="iPad 2",
    iPad3              ="iPad 3",
    iPad4              ="iPad 4",
    iPadAir            ="iPad Air",
    iPadAir2           ="iPad Air 2",
    iPadAir3           ="iPad Air 3",
    iPad5              ="iPad 5", //aka iPad 2017
    iPad6              ="iPad 6", //aka iPad 2018
    //iPad mini
    iPadMini           ="iPad Mini",
    iPadMini2          ="iPad Mini 2",
    iPadMini3          ="iPad Mini 3",
    iPadMini4          ="iPad Mini 4",
    //iPad pro
    iPadPro9_7         ="iPad Pro 9.7"",
    iPadPro10_5        ="iPad Pro 10.5"",
    iPadPro11          ="iPad Pro 11"",
    iPadPro12_9        ="iPad Pro 12.9"",
    iPadPro2_12_9      ="iPad Pro 2 12.9"",
    iPadPro3_12_9      ="iPad Pro 3 12.9"",
    //iPhone
    iPhone4            ="iPhone 4",
    iPhone4S           ="iPhone 4S",
    iPhone5            ="iPhone 5",
    iPhone5S           ="iPhone 5S",
    iPhone5C           ="iPhone 5C",
    iPhone6            ="iPhone 6",
    iPhone6plus        ="iPhone 6 Plus",
    iPhone6S           ="iPhone 6S",
    iPhone6Splus       ="iPhone 6S Plus",
    iPhoneSE           ="iPhone SE",
    iPhone7            ="iPhone 7",
    iPhone7plus        ="iPhone 7 Plus",
    iPhone8            ="iPhone 8",
    iPhone8plus        ="iPhone 8 Plus",
    iPhoneX            ="iPhone X",
    iPhoneXS           ="iPhone XS",
    iPhoneXSMax        ="iPhone XS Max",
    iPhoneXR           ="iPhone XR",
    //Apple TV
    AppleTV            ="Apple TV",
    AppleTV_4K         ="Apple TV 4K",
    unrecognized       ="?unrecognized?"
}

// #-#-#-#-#-#-#-#-#-#-#-#-#-#-#
//MARK: UIDevice extensions
// #-#-#-#-#-#-#-#-#-#-#-#-#-#-#

public extension UIDevice {
    var type: Model {
        var systemInfo = utsname()
        uname(&systemInfo)
        let modelCode = withUnsafePointer(to: &systemInfo.machine) {
            $0.withMemoryRebound(to: CChar.self, capacity: 1) {
                ptr in String.init(validatingUTF8: ptr)

            }
        }
        var modelMap : [ String : Model ] = [
           "i386"      : .simulator,
           "x86_64"    : .simulator,
            //iPod
           "iPod1,1"   : .iPod1,
           "iPod2,1"   : .iPod2,
           "iPod3,1"   : .iPod3,
           "iPod4,1"   : .iPod4,
           "iPod5,1"   : .iPod5,
            //iPad
           "iPad2,1"   : .iPad2,
           "iPad2,2"   : .iPad2,
           "iPad2,3"   : .iPad2,
           "iPad2,4"   : .iPad2,
           "iPad3,1"   : .iPad3,
           "iPad3,2"   : .iPad3,
           "iPad3,3"   : .iPad3,
           "iPad3,4"   : .iPad4,
           "iPad3,5"   : .iPad4,
           "iPad3,6"   : .iPad4,
           "iPad4,1"   : .iPadAir,
           "iPad4,2"   : .iPadAir,
           "iPad4,3"   : .iPadAir,
           "iPad5,3"   : .iPadAir2,
           "iPad5,4"   : .iPadAir2,
           "iPad6,11"  : .iPad5, //aka iPad 2017
           "iPad6,12"  : .iPad5,
           "iPad7,5"   : .iPad6, //aka iPad 2018
           "iPad7,6"   : .iPad6,
            //iPad mini
           "iPad2,5"   : .iPadMini,
           "iPad2,6"   : .iPadMini,
           "iPad2,7"   : .iPadMini,
           "iPad4,4"   : .iPadMini2,
           "iPad4,5"   : .iPadMini2,
           "iPad4,6"   : .iPadMini2,
           "iPad4,7"   : .iPadMini3,
           "iPad4,8"   : .iPadMini3,
           "iPad4,9"   : .iPadMini3,
           "iPad5,1"   : .iPadMini4,
           "iPad5,2"   : .iPadMini4,
            //iPad pro
           "iPad6,3"   : .iPadPro9_7,
           "iPad6,4"   : .iPadPro9_7,
           "iPad7,3"   : .iPadPro10_5,
           "iPad7,4"   : .iPadPro10_5,
           "iPad6,7"   : .iPadPro12_9,
           "iPad6,8"   : .iPadPro12_9,
           "iPad7,1"   : .iPadPro2_12_9,
           "iPad7,2"   : .iPadPro2_12_9,
           "iPad8,1"   : .iPadPro11,
           "iPad8,2"   : .iPadPro11,
           "iPad8,3"   : .iPadPro11,
           "iPad8,4"   : .iPadPro11,
           "iPad8,5"   : .iPadPro3_12_9,
           "iPad8,6"   : .iPadPro3_12_9,
           "iPad8,7"   : .iPadPro3_12_9,
           "iPad8,8"   : .iPadPro3_12_9,
            //iPad air
           "iPad11,3"  : .iPadAir3,
           "iPad11,4"  : .iPadAir3,

            //iPhone
           "iPhone3,1" : .iPhone4,
           "iPhone3,2" : .iPhone4,
           "iPhone3,3" : .iPhone4,
           "iPhone4,1" : .iPhone4S,
           "iPhone5,1" : .iPhone5,
           "iPhone5,2" : .iPhone5,
           "iPhone5,3" : .iPhone5C,
           "iPhone5,4" : .iPhone5C,
           "iPhone6,1" : .iPhone5S,
           "iPhone6,2" : .iPhone5S,
           "iPhone7,1" : .iPhone6plus,
           "iPhone7,2" : .iPhone6,
           "iPhone8,1" : .iPhone6S,
           "iPhone8,2" : .iPhone6Splus,
           "iPhone8,4" : .iPhoneSE,
           "iPhone9,1" : .iPhone7,
           "iPhone9,3" : .iPhone7,
           "iPhone9,2" : .iPhone7plus,
           "iPhone9,4" : .iPhone7plus,
           "iPhone10,1" : .iPhone8,
           "iPhone10,4" : .iPhone8,
           "iPhone10,2" : .iPhone8plus,
           "iPhone10,5" : .iPhone8plus,
           "iPhone10,3" : .iPhoneX,
           "iPhone10,6" : .iPhoneX,
           "iPhone11,2" : .iPhoneXS,
           "iPhone11,4" : .iPhoneXSMax,
           "iPhone11,6" : .iPhoneXSMax,
           "iPhone11,8" : .iPhoneXR,
            //AppleTV
           "AppleTV5,3" : .AppleTV,
           "AppleTV6,2" : .AppleTV_4K
        ]

        if let model = modelMap[String.init(validatingUTF8: modelCode!)!] {
            if model == .simulator {
                if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
                    if let simModel = modelMap[String.init(validatingUTF8: simModelCode)!] {
                        return simModel
                    }
                }
            }
            return model
        }
        return Model.unrecognized
    }
}

用途:您的模型只需:

1
let deviceType = UIDevice().type

或者打印精确的字符串:

1
print("running on: \(UIDevice().type)")

输出:

1
iPhone X

其他例子:

1
2
3
4
5
6
var myDefaultFontSize:CGFloat = 26.0
switch UIDevice().type {
    case .iPhoneSE,.iPhone5,.iPhone5S: print("default value")
    case .iPhone6,.iPhone7,.iPhone8,.iPhone6S, .iPhoneX  : myDefaultFontSize += 4
    default:break
}

对于Apple设备型号,请访问:https://www.theiphonewiki.com/wiki/models


我对uidevice进行了另一个示例扩展,以包含基于@has's答案的模拟器模型标识符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public extension UIDevice {


    /// pares the deveice name as the standard name
    var modelName: String {

        #if (arch(i386) || arch(x86_64)) && os(iOS)
        let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"]!
        #else
        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)))
        }
        #endif

        switch identifier {
        case"iPod5,1":                                 return"iPod Touch 5"
        case"iPod7,1":                                 return"iPod Touch 6"
        case"iPhone3,1","iPhone3,2","iPhone3,3":     return"iPhone 4"
        case"iPhone4,1":                               return"iPhone 4s"
        case"iPhone5,1","iPhone5,2":                  return"iPhone 5"
        case"iPhone5,3","iPhone5,4":                  return"iPhone 5c"
        case"iPhone6,1","iPhone6,2":                  return"iPhone 5s"
        case"iPhone7,2":                               return"iPhone 6"
        case"iPhone7,1":                               return"iPhone 6 Plus"
        case"iPhone8,1":                               return"iPhone 6s"
        case"iPhone8,2":                               return"iPhone 6s Plus"
        case"iPhone9,1","iPhone9,3":                  return"iPhone 7"
        case"iPhone9,2","iPhone9,4":                  return"iPhone 7 Plus"
        case"iPhone8,4":                               return"iPhone SE"
        case"iPhone10,1","iPhone10,4":                return"iPhone 8"
        case"iPhone10,2","iPhone10,5":                return"iPhone 8 Plus"
        case"iPhone10,3","iPhone10,6":                return"iPhone X"
        case"iPhone11,2":                              return"iPhone XS"
        case"iPhone11,4","iPhone11,6":                return"iPhone XS Max"
        case"iPhone11,8":                              return"iPhone XR"
        case"iPad2,1","iPad2,2","iPad2,3","iPad2,4":return"iPad 2"
        case"iPad3,1","iPad3,2","iPad3,3":           return"iPad 3"
        case"iPad3,4","iPad3,5","iPad3,6":           return"iPad 4"
        case"iPad4,1","iPad4,2","iPad4,3":           return"iPad Air"
        case"iPad5,3","iPad5,4":                      return"iPad Air 2"
        case"iPad6,11","iPad6,12":                    return"iPad 5"
        case"iPad7,5","iPad7,6":                      return"iPad 6"
        case"iPad2,5","iPad2,6","iPad2,7":           return"iPad Mini"
        case"iPad4,4","iPad4,5","iPad4,6":           return"iPad Mini 2"
        case"iPad4,7","iPad4,8","iPad4,9":           return"iPad Mini 3"
        case"iPad5,1","iPad5,2":                      return"iPad Mini 4"
        case"iPad6,3","iPad6,4":                      return"iPad Pro 9.7 Inch"
        case"iPad6,7","iPad6,8":                      return"iPad Pro 12.9 Inch"
        case"iPad7,1","iPad7,2":                      return"iPad Pro (12.9-inch) (2nd generation)"
        case"iPad7,3","iPad7,4":                      return"iPad Pro (10.5-inch)"
        case"iPad8,1","iPad8,2","iPad8,3","iPad8,4":return"iPad Pro (11-inch)"
        case"iPad8,5","iPad8,6","iPad8,7","iPad8,8":return"iPad Pro (12.9-inch) (3rd generation)"
        case"AppleTV5,3":                              return"Apple TV"
        case"AppleTV6,2":                              return"Apple TV 4K"
        case"AudioAccessory1,1":                       return"HomePod"
        default:                                        return identifier
        }
    }

}

Swift 4.x版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public extension UIDevice {

    /// pares the deveice name as the standard name
    var modelName: String {

        #if targetEnvironment(simulator)
            let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"]!
        #else
            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)))
            }
        #endif

        switch identifier {
        case"iPod5,1":                                 return"iPod Touch 5"
        case"iPod7,1":                                 return"iPod Touch 6"
        case"iPhone3,1","iPhone3,2","iPhone3,3":     return"iPhone 4"
        case"iPhone4,1":                               return"iPhone 4s"
        case"iPhone5,1","iPhone5,2":                  return"iPhone 5"
        case"iPhone5,3","iPhone5,4":                  return"iPhone 5c"
        case"iPhone6,1","iPhone6,2":                  return"iPhone 5s"
        case"iPhone7,2":                               return"iPhone 6"
        case"iPhone7,1":                               return"iPhone 6 Plus"
        case"iPhone8,1":                               return"iPhone 6s"
        case"iPhone8,2":                               return"iPhone 6s Plus"
        case"iPhone9,1","iPhone9,3":                  return"iPhone 7"
        case"iPhone9,2","iPhone9,4":                  return"iPhone 7 Plus"
        case"iPhone8,4":                               return"iPhone SE"
        case"iPhone10,1","iPhone10,4":                return"iPhone 8"
        case"iPhone10,2","iPhone10,5":                return"iPhone 8 Plus"
        case"iPhone10,3","iPhone10,6":                return"iPhone X"
        case"iPhone11,2":                              return"iPhone XS"
        case"iPhone11,4","iPhone11,6":                return"iPhone XS Max"
        case"iPhone11,8":                              return"iPhone XR"
        case"iPad2,1","iPad2,2","iPad2,3","iPad2,4":return"iPad 2"
        case"iPad3,1","iPad3,2","iPad3,3":           return"iPad 3"
        case"iPad3,4","iPad3,5","iPad3,6":           return"iPad 4"
        case"iPad4,1","iPad4,2","iPad4,3":           return"iPad Air"
        case"iPad5,3","iPad5,4":                      return"iPad Air 2"
        case"iPad6,11","iPad6,12":                    return"iPad 5"
        case"iPad7,5","iPad7,6":                      return"iPad 6"
        case"iPad2,5","iPad2,6","iPad2,7":           return"iPad Mini"
        case"iPad4,4","iPad4,5","iPad4,6":           return"iPad Mini 2"
        case"iPad4,7","iPad4,8","iPad4,9":           return"iPad Mini 3"
        case"iPad5,1","iPad5,2":                      return"iPad Mini 4"
        case"iPad6,3","iPad6,4":                      return"iPad Pro 9.7 Inch"
        case"iPad6,7","iPad6,8":                      return"iPad Pro 12.9 Inch"
        case"iPad7,1","iPad7,2":                      return"iPad Pro (12.9-inch) (2nd generation)"
        case"iPad7,3","iPad7,4":                      return"iPad Pro (10.5-inch)"
        case"iPad8,1","iPad8,2","iPad8,3","iPad8,4":return"iPad Pro (11-inch)"
        case"iPad8,5","iPad8,6","iPad8,7","iPad8,8":return"iPad Pro (12.9-inch) (3rd generation)"
        case"AppleTV5,3":                              return"Apple TV"
        case"AppleTV6,2":                              return"Apple TV 4K"
        case"AudioAccessory1,1":                       return"HomePod"
        default:                                        return identifier
        }
    }

}

它与上面的swift3.2一起工作正常:

1
let modelName = UIDevice.current.modelName

对于设备和模拟器,创建名为uidevice.swift的新swift文件

添加以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import UIKit


public extension UIDevice {

var modelName: String {
    #if (arch(i386) || arch(x86_64)) && os(iOS)
        let DEVICE_IS_SIMULATOR = true
    #else
        let DEVICE_IS_SIMULATOR = false
    #endif

    var machineString : String =""

    if DEVICE_IS_SIMULATOR == true
    {

        if let dir = NSProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
            machineString = dir
        }
    }
    else {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        machineString = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8 where value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
    }
    switch machineString {
    case"iPod5,1":                                 return"iPod Touch 5"
    case"iPod7,1":                                 return"iPod Touch 6"
    case"iPhone3,1","iPhone3,2","iPhone3,3":     return"iPhone 4"
    case"iPhone4,1":                               return"iPhone 4s"
    case"iPhone5,1","iPhone5,2":                  return"iPhone 5"
    case"iPhone5,3","iPhone5,4":                  return"iPhone 5c"
    case"iPhone6,1","iPhone6,2":                  return"iPhone 5s"
    case"iPhone7,2":                               return"iPhone 6"
    case"iPhone7,1":                               return"iPhone 6 Plus"
    case"iPhone8,1":                               return"iPhone 6s"
    case"iPhone8,2":                               return"iPhone 6s Plus"
    case"iPad2,1","iPad2,2","iPad2,3","iPad2,4":return"iPad 2"
    case"iPad3,1","iPad3,2","iPad3,3":           return"iPad 3"
    case"iPad3,4","iPad3,5","iPad3,6":           return"iPad 4"
    case"iPad4,1","iPad4,2","iPad4,3":           return"iPad Air"
    case"iPad5,3","iPad5,4":                      return"iPad Air 2"
    case"iPad2,5","iPad2,6","iPad2,7":           return"iPad Mini"
    case"iPad4,4","iPad4,5","iPad4,6":           return"iPad Mini 2"
    case"iPad4,7","iPad4,8","iPad4,9":           return"iPad Mini 3"
    case"iPad5,1","iPad5,2":                      return"iPad Mini 4"
    case"iPad6,7","iPad6,8":                      return"iPad Pro"
    case"AppleTV5,3":                              return"Apple TV"
    default:                                        return machineString
    }
}
}

然后在视图控制器中,

1
2
3
4
5
6
7
8
9
10
11
 let deviceType = UIDevice.currentDevice().modelName

    if deviceType.lowercaseString.rangeOfString("iphone 4") != nil {
       print("iPhone 4 or iphone 4s")
    }
    else if deviceType.lowercaseString.rangeOfString("iphone 5") != nil {
        print("iPhone 5 or iphone 5s or iphone 5c")
    }
   else if deviceType.lowercaseString.rangeOfString("iphone 6") != nil {
        print("iPhone 6 Series")
    }


处理C结构是很痛苦的。尤其是如果它们中有某种C数组。这里是我的解决方案:继续使用objective-c。只需创建一个包装器objective-c类来完成这个工作,然后在swift中使用这个类。下面是一个这样做的示例类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@interface DeviceInfo : NSObject

+ (NSString *)model;

@end

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

@implementation DeviceInfo

+ (NSString *)model
{
    struct utsname systemInfo;
    uname(&systemInfo);

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

@end

在SWIFT方面:

1
let deviceModel = DeviceInfo.model()


我发现很多答案都使用字符串。我决定更改@has answer以使用枚举:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public enum Devices: String {
    case IPodTouch5
    case IPodTouch6
    case IPhone4
    case IPhone4S
    case IPhone5
    case IPhone5C
    case IPhone5S
    case IPhone6
    case IPhone6Plus
    case IPhone6S
    case IPhone6SPlus
    case IPhone7
    case IPhone7Plus
    case IPhoneSE
    case IPad2
    case IPad3
    case IPad4
    case IPadAir
    case IPadAir2
    case IPadMini
    case IPadMini2
    case IPadMini3
    case IPadMini4
    case IPadPro
    case AppleTV
    case Simulator
    case Other
}

public extension UIDevice {

    public var modelName: Devices {
        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)))
        }

        switch identifier {
        case"iPod5,1":                                 return Devices.IPodTouch5
        case"iPod7,1":                                 return Devices.IPodTouch6
        case"iPhone3,1","iPhone3,2","iPhone3,3":     return Devices.IPhone4
        case"iPhone4,1":                               return Devices.IPhone4S
        case"iPhone5,1","iPhone5,2":                  return Devices.IPhone5
        case"iPhone5,3","iPhone5,4":                  return Devices.IPhone5C
        case"iPhone6,1","iPhone6,2":                  return Devices.IPhone5S
        case"iPhone7,2":                               return Devices.IPhone6
        case"iPhone7,1":                               return Devices.IPhone6Plus
        case"iPhone8,1":                               return Devices.IPhone6S
        case"iPhone8,2":                               return Devices.IPhone6SPlus
        case"iPhone9,1","iPhone9,3":                  return Devices.IPhone7
        case"iPhone9,2","iPhone9,4":                  return Devices.IPhone7Plus
        case"iPhone8,4":                               return Devices.IPhoneSE
        case"iPad2,1","iPad2,2","iPad2,3","iPad2,4":return Devices.IPad2
        case"iPad3,1","iPad3,2","iPad3,3":           return Devices.IPad3
        case"iPad3,4","iPad3,5","iPad3,6":           return Devices.IPad4
        case"iPad4,1","iPad4,2","iPad4,3":           return Devices.IPadAir
        case"iPad5,3","iPad5,4":                      return Devices.IPadAir2
        case"iPad2,5","iPad2,6","iPad2,7":           return Devices.IPadMini
        case"iPad4,4","iPad4,5","iPad4,6":           return Devices.IPadMini2
        case"iPad4,7","iPad4,8","iPad4,9":           return Devices.IPadMini3
        case"iPad5,1","iPad5,2":                      return Devices.IPadMini4
        case"iPad6,3","iPad6,4","iPad6,7","iPad6,8":return Devices.IPadPro
        case"AppleTV5,3":                              return Devices.AppleTV
        case"i386","x86_64":                          return Devices.Simulator
        default:                                        return Devices.Other
        }
    }

}

我已经实现了一个超轻量库,根据给定的一些答案来检测使用过的设备:https://github.com/schickling/device.swift

它可以通过迦太基安装,使用方法如下:

1
2
3
4
5
6
7
8
9
import Device

let deviceType = UIDevice.currentDevice().deviceType

switch deviceType {
case .IPhone6: print("Do stuff for iPhone6")
case .IPadMini: print("Do stuff for iPad mini")
default: print("Check other available cases of DeviceType")
}


使用Swift 3时,接受的答案有一些问题!这个答案(灵感来自纳齐克)适用于Swift 3和新款iPhone:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import UIKit


public extension UIDevice {
var modelName: String {
    #if (arch(i386) || arch(x86_64)) && os(iOS)
        let DEVICE_IS_SIMULATOR = true
    #else
        let DEVICE_IS_SIMULATOR = false
    #endif

    var machineString = String()

    if DEVICE_IS_SIMULATOR == true
    {
        if let dir = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
            machineString = dir
        }
    }
    else {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        machineString = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8 , value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
    }
    switch machineString {
    case"iPod4,1":                                 return"iPod Touch 4G"
    case"iPod5,1":                                 return"iPod Touch 5G"
    case"iPod7,1":                                 return"iPod Touch 6G"
    case"iPhone3,1","iPhone3,2","iPhone3,3":     return"iPhone 4"
    case"iPhone4,1":                               return"iPhone 4s"
    case"iPhone5,1","iPhone5,2":                  return"iPhone 5"
    case"iPhone5,3","iPhone5,4":                  return"iPhone 5c"
    case"iPhone6,1","iPhone6,2":                  return"iPhone 5s"
    case"iPhone7,2":                               return"iPhone 6"
    case"iPhone7,1":                               return"iPhone 6 Plus"
    case"iPhone8,1":                               return"iPhone 6s"
    case"iPhone8,2":                               return"iPhone 6s Plus"
    case"iPhone8,4":                               return"iPhone SE"
    case"iPhone9,1","iPhone9,3":                  return"iPhone 7"
    case"iPhone9,2","iPhone 9,4":                 return"iPhone 7 Plus"
    case"iPad2,1","iPad2,2","iPad2,3","iPad2,4":return"iPad 2"
    case"iPad3,1","iPad3,2","iPad3,3":           return"iPad 3"
    case"iPad3,4","iPad3,5","iPad3,6":           return"iPad 4"
    case"iPad4,1","iPad4,2","iPad4,3":           return"iPad Air"
    case"iPad5,3","iPad5,4":                      return"iPad Air 2"
    case"iPad2,5","iPad2,6","iPad2,7":           return"iPad Mini"
    case"iPad4,4","iPad4,5","iPad4,6":           return"iPad Mini 2"
    case"iPad4,7","iPad4,8","iPad4,9":           return"iPad Mini 3"
    case"iPad5,1","iPad5,2":                      return"iPad Mini 4"
    case"iPad6,3","iPad6,4":                      return"iPad Pro (9.7 inch)"
    case"iPad6,7","iPad6,8":                      return"iPad Pro (12.9 inch)"
    case"AppleTV5,3":                              return"Apple TV"
    default:                                        return machineString
    }
}
}

使用swift 3(xcode 8.3)

1
2
3
4
5
6
7
8
 func deviceName() -> String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let str = withUnsafePointer(to: &systemInfo.machine.0) { ptr in
            return String(cString: ptr)
        }
        return str
    }

注意:根据官方的dev论坛答案,以这种方式使用元组是安全的。大Int8元组的内存对齐方式将与它是大Int8数组时相同。即:连续的,不加衬垫。


1
2
3
4
5
var platform: String? {
    var systemInfo = utsname()
    uname(&systemInfo)
    return withUnsafeMutablePointer(&systemInfo.machine) { ptr in String.fromCString(UnsafePointer<CChar>(ptr)) }
}

Swift 3.0或更高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import UIKit

class ViewController: UIViewController {

    let device = UIDevice.current

    override func viewDidLoad() {
        super.viewDidLoad()

        let model = device.model
        print(model) // e.g."iPhone"

        let modelName = device.modelName
        print(modelName) // e.g."iPhone 6"  /* see the extension */

        let deviceName = device.name
        print(deviceName) // e.g."My iPhone"

        let systemName = device.systemName
        print(systemName) // e.g."iOS"

        let systemVersion = device.systemVersion
        print(systemVersion) // e.g."10.3.2"

        if let identifierForVendor = device.identifierForVendor {

            print(identifierForVendor) // e.g."E1X2XX34-5X6X-7890-123X-XXX456C78901"
        }
    }
}

并添加以下扩展名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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)))
        }

        switch identifier {

        case"iPod5,1":                                 return"iPod Touch 5"
        case"iPod7,1":                                 return"iPod Touch 6"
        case"iPhone3,1","iPhone3,2","iPhone3,3":     return"iPhone 4"
        case"iPhone4,1":                               return"iPhone 4s"
        case"iPhone5,1","iPhone5,2":                  return"iPhone 5"
        case"iPhone5,3","iPhone5,4":                  return"iPhone 5c"
        case"iPhone6,1","iPhone6,2":                  return"iPhone 5s"
        case"iPhone7,2":                               return"iPhone 6"
        case"iPhone7,1":                               return"iPhone 6 Plus"
        case"iPhone8,1":                               return"iPhone 6s"
        case"iPhone8,2":                               return"iPhone 6s Plus"
        case"iPhone9,1","iPhone9,3":                  return"iPhone 7"
        case"iPhone9,2","iPhone9,4":                  return"iPhone 7 Plus"
        case"iPhone8,4":                               return"iPhone SE"
        case"iPad2,1","iPad2,2","iPad2,3","iPad2,4":return"iPad 2"
        case"iPad3,1","iPad3,2","iPad3,3":           return"iPad 3"
        case"iPad3,4","iPad3,5","iPad3,6":           return"iPad 4"
        case"iPad4,1","iPad4,2","iPad4,3":           return"iPad Air"
        case"iPad5,3","iPad5,4":                      return"iPad Air 2"
        case"iPad6,11","iPad6,12":                    return"iPad 5"
        case"iPad2,5","iPad2,6","iPad2,7":           return"iPad Mini"
        case"iPad4,4","iPad4,5","iPad4,6":           return"iPad Mini 2"
        case"iPad4,7","iPad4,8","iPad4,9":           return"iPad Mini 3"
        case"iPad5,1","iPad5,2":                      return"iPad Mini 4"
        case"iPad6,3","iPad6,4":                      return"iPad Pro 9.7 Inch"
        case"iPad6,7","iPad6,8":                      return"iPad Pro 12.9 Inch"
        case"iPad7,1","iPad7,2":                      return"iPad Pro 12.9 Inch 2. Generation"
        case"iPad7,3","iPad7,4":                      return"iPad Pro 10.5 Inch"
        case"AppleTV5,3":                              return"Apple TV"
        case"i386","x86_64":                          return"Simulator"
        default:                                        return identifier
        }
    }
}

在斯威夫特3号里

1
 UIDevice.current.model


这里是一个没有强制打开和swift 3.0的修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import Foundation
import UIKit


public enum Model : String {
    case simulator ="simulator/sandbox",
    iPod1          ="iPod 1",
    iPod2          ="iPod 2",
    iPod3          ="iPod 3",
    iPod4          ="iPod 4",
    iPod5          ="iPod 5",
    iPad2          ="iPad 2",
    iPad3          ="iPad 3",
    iPad4          ="iPad 4",
    iPhone4        ="iPhone 4",
    iPhone4S       ="iPhone 4S",
    iPhone5        ="iPhone 5",
    iPhone5S       ="iPhone 5S",
    iPhone5C       ="iPhone 5C",
    iPadMini1      ="iPad Mini 1",
    iPadMini2      ="iPad Mini 2",
    iPadMini3      ="iPad Mini 3",
    iPadAir1       ="iPad Air 1",
    iPadAir2       ="iPad Air 2",
    iPhone6        ="iPhone 6",
    iPhone6plus    ="iPhone 6 Plus",
    iPhone6S       ="iPhone 6S",
    iPhone6Splus   ="iPhone 6S Plus",
    iPhoneSE       ="iPhone SE",
    iPhone7        ="iPhone 7",
    iPhone7plus    ="iPhone 7 Plus",
    unrecognized   ="?unrecognized?"
}

public extension UIDevice {
    public var type: Model {
        var systemInfo = utsname()
        uname(&systemInfo)
        let modelCode = withUnsafePointer(to: &systemInfo.machine) {
            $0.withMemoryRebound(to: CChar.self, capacity: 1) {
                ptr in String.init(validatingUTF8: ptr)

            }
        }
        var modelMap : [ String : Model ] = [
           "i386"      : .simulator,
           "x86_64"    : .simulator,
           "iPod1,1"   : .iPod1,
           "iPod2,1"   : .iPod2,
           "iPod3,1"   : .iPod3,
           "iPod4,1"   : .iPod4,
           "iPod5,1"   : .iPod5,
           "iPad2,1"   : .iPad2,
           "iPad2,2"   : .iPad2,
           "iPad2,3"   : .iPad2,
           "iPad2,4"   : .iPad2,
           "iPad2,5"   : .iPadMini1,
           "iPad2,6"   : .iPadMini1,
           "iPad2,7"   : .iPadMini1,
           "iPhone3,1" : .iPhone4,
           "iPhone3,2" : .iPhone4,
           "iPhone3,3" : .iPhone4,
           "iPhone4,1" : .iPhone4S,
           "iPhone5,1" : .iPhone5,
           "iPhone5,2" : .iPhone5,
           "iPhone5,3" : .iPhone5C,
           "iPhone5,4" : .iPhone5C,
           "iPad3,1"   : .iPad3,
           "iPad3,2"   : .iPad3,
           "iPad3,3"   : .iPad3,
           "iPad3,4"   : .iPad4,
           "iPad3,5"   : .iPad4,
           "iPad3,6"   : .iPad4,
           "iPhone6,1" : .iPhone5S,
           "iPhone6,2" : .iPhone5S,
           "iPad4,1"   : .iPadAir1,
           "iPad4,2"   : .iPadAir2,
           "iPad4,4"   : .iPadMini2,
           "iPad4,5"   : .iPadMini2,
           "iPad4,6"   : .iPadMini2,
           "iPad4,7"   : .iPadMini3,
           "iPad4,8"   : .iPadMini3,
           "iPad4,9"   : .iPadMini3,
           "iPhone7,1" : .iPhone6plus,
           "iPhone7,2" : .iPhone6,
           "iPhone8,1" : .iPhone6S,
           "iPhone8,2" : .iPhone6Splus,
           "iPhone8,4" : .iPhoneSE,
           "iPhone9,1" : .iPhone7,
           "iPhone9,2" : .iPhone7plus,
           "iPhone9,3" : .iPhone7,
           "iPhone9,4" : .iPhone7plus,
            ]

        guard let safeModelCode = modelCode else {
            return Model.unrecognized
        }

        guard let modelString = String.init(validatingUTF8: safeModelCode) else {
            return Model.unrecognized
        }

        guard let model = modelMap[modelString] else {
            return Model.unrecognized
        }

        return model
    }
}

可以使用bdLocalizedDevicesModels框架分析设备信息并获取名称。

然后在代码中调用UIDevice.currentDevice.productName


斯威夫特3.1

我打电话给尤特斯南的两分钱:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    func platform() -> String {
    var systemInfo = utsname()
    uname(&systemInfo)
    let size = Int(_SYS_NAMELEN) // is 32, but posix AND its init is 256....

    let s = withUnsafeMutablePointer(to: &systemInfo.machine) {p in

        p.withMemoryRebound(to: CChar.self, capacity: size, {p2 in
            return String(cString: p2)
        })

    }
    return s
}

和其他人一样,但对C/Swift和Back的复杂性有点清楚。):

返回值,如"x86_64"


下面是获取硬件字符串的代码,但您需要比较这些硬件字符串以了解它是哪个设备。我已经为它创建了一个类,该类包含几乎所有的设备字符串(我们用新设备保持字符串最新)。很容易用,请检查

银行代码:github/deviceguur

目标C:Github/DeviceUtil

1
2
3
4
5
6
7
8
9
10
public func hardwareString() -> String {
  var name: [Int32] = [CTL_HW, HW_MACHINE]
  var size: Int = 2
  sysctl(&name, 2, nil, &size, &name, 0)
  var hw_machine = [CChar](count: Int(size), repeatedValue: 0)
  sysctl(&name, 2, &hw_machine, &size, &name, 0)

  let hardware: String = String.fromCString(hw_machine)!
  return hardware
}

我的简单解决方案按设备分组,支持Swift 3中的新设备iPhone 8iPhone X

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public 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)))
        }

        switch identifier {
        case"iPhone3,1","iPhone3,2","iPhone3,3","iPhone4,1":
            return"iPhone 4"

        case"iPhone5,1","iPhone5,2","iPhone5,3","iPhone5,4","iPhone6,1","iPhone6,2","iPhone8,4":
            return"iPhone 5"

        case"iPhone7,2","iPhone8,1","iPhone9,1","iPhone9,3","iPhone10,1","iPhone10,4":
            return"iPhone 6,7,8"

        case"iPhone7,1","iPhone8,2","iPhone9,2","iPhone9,4","iPhone10,2","iPhone10,5":
            return"iPhone Plus"

        case"iPhone10,3","iPhone10,6":
            return"iPhone X"

        case"i386","x86_64":
            return"Simulator"
        default:
            return identifier
        }
    }
}

用途:

1
2
3
4
5
6
7
8
9
switch UIDevice.current.modelName {
  case"iPhone 4":
  case"iPhone 5":
  case"iPhone 6,7,8":
  case"iPhone Plus":
  case"iPhone X":
  case"Simulator":
  default:
}


使用swift"开关盒":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
func platformString() -> String {

    var devSpec: String

    switch platform() {

    case"iPhone1,2": devSpec ="iPhone 3G"
    case"iPhone2,1": devSpec ="iPhone 3GS"
    case"iPhone3,1": devSpec ="iPhone 4"
    case"iPhone3,3": devSpec ="Verizon iPhone 4"
    case"iPhone4,1": devSpec ="iPhone 4S"
    case"iPhone5,1": devSpec ="iPhone 5 (GSM)"
    case"iPhone5,2": devSpec ="iPhone 5 (GSM+CDMA)"
    case"iPhone5,3": devSpec ="iPhone 5c (GSM)"
    case"iPhone5,4": devSpec ="iPhone 5c (GSM+CDMA)"
    case"iPhone6,1": devSpec ="iPhone 5s (GSM)"
    case"iPhone6,2": devSpec ="iPhone 5s (GSM+CDMA)"
    case"iPhone7,1": devSpec ="iPhone 6 Plus"
    case"iPhone7,2": devSpec ="iPhone 6"
    case"iPod1,1": devSpec ="iPod Touch 1G"
    case"iPod2,1": devSpec ="iPod Touch 2G"
    case"iPod3,1": devSpec ="iPod Touch 3G"
    case"iPod4,1": devSpec ="iPod Touch 4G"
    case"iPod5,1": devSpec ="iPod Touch 5G"
    case"iPad1,1": devSpec ="iPad"
    case"iPad2,1": devSpec ="iPad 2 (WiFi)"
    case"iPad2,2": devSpec ="iPad 2 (GSM)"
    case"iPad2,3": devSpec ="iPad 2 (CDMA)"
    case"iPad2,4": devSpec ="iPad 2 (WiFi)"
    case"iPad2,5": devSpec ="iPad Mini (WiFi)"
    case"iPad2,6": devSpec ="iPad Mini (GSM)"
    case"iPad2,7": devSpec ="iPad Mini (GSM+CDMA)"
    case"iPad3,1": devSpec ="iPad 3 (WiFi)"
    case"iPad3,2": devSpec ="iPad 3 (GSM+CDMA)"
    case"iPad3,3": devSpec ="iPad 3 (GSM)"
    case"iPad3,4": devSpec ="iPad 4 (WiFi)"
    case"iPad3,5": devSpec ="iPad 4 (GSM)"
    case"iPad3,6": devSpec ="iPad 4 (GSM+CDMA)"
    case"iPad4,1": devSpec ="iPad Air (WiFi)"
    case"iPad4,2": devSpec ="iPad Air (Cellular)"
    case"iPad4,4": devSpec ="iPad mini 2G (WiFi)"
    case"iPad4,5": devSpec ="iPad mini 2G (Cellular)"

    case"iPad4,7": devSpec ="iPad mini 3 (WiFi)"
    case"iPad4,8": devSpec ="iPad mini 3 (Cellular)"
    case"iPad4,9": devSpec ="iPad mini 3 (China Model)"

    case"iPad5,3": devSpec ="iPad Air 2 (WiFi)"
    case"iPad5,4": devSpec ="iPad Air 2 (Cellular)"

    case"i386": devSpec ="Simulator"
    case"x86_64": devSpec ="Simulator"

    default: devSpec ="Unknown"
    }

    return devSpec
}

如果您不想每次苹果向设备系列添加新型号时都更新您的代码,请使用下面的方法仅返回型号代码。

1
2
3
4
5
6
7
8
9
func platform() -> String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let modelCode = withUnsafeMutablePointer(&systemInfo.machine) {
            ptr in String.fromCString(UnsafePointer<CChar>(ptr))
        }

        return String.fromCString(modelCode!)!
}


1
2
3
4
5
6
7
8
9
10
11
12
13
extension UIDevice {

    public static let hardwareModel: String = {
        var path = [CTL_HW, HW_MACHINE]
        var n = 0
        sysctl(&path, 2, nil, &n, nil, 0)
        var a: [UInt8] = .init(repeating: 0, count: n)
        sysctl(&path, 2, &a, &n, nil, 0)
        return .init(cString: a)
    }()
}

UIDevice.hardwareModel // → iPhone9,3

基于这个答案和这个答案。我创造了一个公共要点

如何使用

1
2
3
4
5
6
7
8
9
10
11
12
let boolean: Bool = UIDevice.isDevice(ofType: .iPhoneX)
// true or false

let specificDevice: DeviceModel.Model = UIDevice.modelType
// iPhone6s, iPhoneX, iPad etc...

let model: DeviceModel = UIDevice.model
// .simulator(let specificDevice), .real(let specificDevice),
// .unrecognizedSimulator(let string), .unrecognized(let string)

let modelName: String = UIDevice.model.name
// iPhone 6, iPhone X, etc...

这是GIST中的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
public extension UIDevice {
    public static var modelCode: String {
        if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] { return simulatorModelIdentifier }
        var systemInfo = utsname()
        uname(&systemInfo)
        return withUnsafeMutablePointer(to: &systemInfo.machine) {
            ptr in String(cString: UnsafeRawPointer(ptr).assumingMemoryBound(to: CChar.self))
        }
    }

    public static var model: DeviceModel {
        // Thanks https://stackoverflow.com/a/26962452/5928180
        var systemInfo = utsname()
        uname(&systemInfo)
        let modelCode = withUnsafeMutablePointer(to: &systemInfo.machine) {
            ptr in String(cString: UnsafeRawPointer(ptr).assumingMemoryBound(to: CChar.self))
        }

        // Thanks https://stackoverflow.com/a/33495869/5928180
        if modelCode =="i386" || modelCode =="x86_64" {
            if let simulatorModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"], let model = DeviceModel.Model(modelCode: simulatorModelCode) {
                return DeviceModel.simulator(model)
            } else if let simulatorModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
                return DeviceModel.unrecognizedSimulator(simulatorModelCode)
            } else {
                return DeviceModel.unrecognized(modelCode)
            }
        } else if let model = DeviceModel.Model(modelCode: modelCode) {
            return DeviceModel.real(model)
        } else {
            return DeviceModel.unrecognized(modelCode)
        }
    }

    public static var modelType: DeviceModel.Model? {
        return UIDevice.model.model
    }

    public static func isDevice(ofType model: DeviceModel.Model) -> Bool {
        return UIDevice.modelType == model
    }
}


public enum DeviceModel {
    case simulator(Model)
    case unrecognizedSimulator(String)
    case real(Model)
    case unrecognized(String)

    public enum Model: String {
        case iPod1            ="iPod 1"
        case iPod2            ="iPod 2"
        case iPod3            ="iPod 3"
        case iPod4            ="iPod 4"
        case iPod5            ="iPod 5"
        case iPad2            ="iPad 2"
        case iPad3            ="iPad 3"
        case iPad4            ="iPad 4"
        case iPhone4          ="iPhone 4"
        case iPhone4S         ="iPhone 4S"
        case iPhone5          ="iPhone 5"
        case iPhone5S         ="iPhone 5S"
        case iPhone5C         ="iPhone 5C"
        case iPadMini1        ="iPad Mini 1"
        case iPadMini2        ="iPad Mini 2"
        case iPadMini3        ="iPad Mini 3"
        case iPadAir1         ="iPad Air 1"
        case iPadAir2         ="iPad Air 2"
        case iPadPro9_7       ="iPad Pro 9.7""
        case iPadPro9_7_cell  ="iPad Pro 9.7" cellular"
        case iPadPro10_5      ="iPad Pro 10.5""
        case iPadPro10_5_cell ="iPad Pro 10.5" cellular"
        case iPadPro12_9      ="iPad Pro 12.9""
        case iPadPro12_9_cell ="iPad Pro 12.9" cellular"
        case iPhone6          ="iPhone 6"
        case iPhone6plus      ="iPhone 6 Plus"
        case iPhone6S         ="iPhone 6S"
        case iPhone6Splus     ="iPhone 6S Plus"
        case iPhoneSE         ="iPhone SE"
        case iPhone7          ="iPhone 7"
        case iPhone7plus      ="iPhone 7 Plus"
        case iPhone8          ="iPhone 8"
        case iPhone8plus      ="iPhone 8 Plus"
        case iPhoneX          ="iPhone X"

        init?(modelCode: String) {
            switch modelCode {
            case"iPod1,1":    self = .iPod1
            case"iPod2,1":    self = .iPod2
            case"iPod3,1":    self = .iPod3
            case"iPod4,1":    self = .iPod4
            case"iPod5,1":    self = .iPod5
            case"iPad2,1":    self = .iPad2
            case"iPad2,2":    self = .iPad2
            case"iPad2,3":    self = .iPad2
            case"iPad2,4":    self = .iPad2
            case"iPad2,5":    self = .iPadMini1
            case"iPad2,6":    self = .iPadMini1
            case"iPad2,7":    self = .iPadMini1
            case"iPhone3,1":  self = .iPhone4
            case"iPhone3,2":  self = .iPhone4
            case"iPhone3,3":  self = .iPhone4
            case"iPhone4,1":  self = .iPhone4S
            case"iPhone5,1":  self = .iPhone5
            case"iPhone5,2":  self = .iPhone5
            case"iPhone5,3":  self = .iPhone5C
            case"iPhone5,4":  self = .iPhone5C
            case"iPad3,1":    self = .iPad3
            case"iPad3,2":    self = .iPad3
            case"iPad3,3":    self = .iPad3
            case"iPad3,4":    self = .iPad4
            case"iPad3,5":    self = .iPad4
            case"iPad3,6":    self = .iPad4
            case"iPhone6,1":  self = .iPhone5S
            case"iPhone6,2":  self = .iPhone5S
            case"iPad4,1":    self = .iPadAir1
            case"iPad4,2":    self = .iPadAir2
            case"iPad4,4":    self = .iPadMini2
            case"iPad4,5":    self = .iPadMini2
            case"iPad4,6":    self = .iPadMini2
            case"iPad4,7":    self = .iPadMini3
            case"iPad4,8":    self = .iPadMini3
            case"iPad4,9":    self = .iPadMini3
            case"iPad6,3":    self = .iPadPro9_7
            case"iPad6,11":   self = .iPadPro9_7
            case"iPad6,4":    self = .iPadPro9_7_cell
            case"iPad6,12":   self = .iPadPro9_7_cell
            case"iPad6,7":    self = .iPadPro12_9
            case"iPad6,8":    self = .iPadPro12_9_cell
            case"iPad7,3":    self = .iPadPro10_5
            case"iPad7,4":    self = .iPadPro10_5_cell
            case"iPhone7,1":  self = .iPhone6plus
            case"iPhone7,2":  self = .iPhone6
            case"iPhone8,1":  self = .iPhone6S
            case"iPhone8,2":  self = .iPhone6Splus
            case"iPhone8,4":  self = .iPhoneSE
            case"iPhone9,1":  self = .iPhone7
            case"iPhone9,2":  self = .iPhone7plus
            case"iPhone9,3":  self = .iPhone7
            case"iPhone9,4":  self = .iPhone7plus
            case"iPhone10,1": self = .iPhone8
            case"iPhone10,2": self = .iPhone8plus
            case"iPhone10,3": self = .iPhoneX
            case"iPhone10,6": self = .iPhoneX
            default:           return nil
            }
        }
    }

    public var name: String {
        switch self {
        case .simulator(let model):         return"Simulator[\(model.rawValue)]"
        case .unrecognizedSimulator(let s): return"UnrecognizedSimulator[\(s)]"
        case .real(let model):              return model.rawValue
        case .unrecognized(let s):          return"Unrecognized[\(s)]"
        }
    }

    public var model: DeviceModel.Model? {
        switch self {
        case .simulator(let model):         return model
        case .real(let model):              return model
        case .unrecognizedSimulator(_):     return nil
        case .unrecognized(_):              return nil
        }
    }
}

1
2
3
4
5
6
7
struct DeviceType {
        static let IS_IPHONE_4_OR_LESS = UIDevice.current.userInterfaceIdiom == .phone && Constants.SCREEN_MAX_LENGTH < 568
        static let IS_IPHONE_5 = UIDevice.current.userInterfaceIdiom == .phone && Constants.SCREEN_MAX_LENGTH == 568
        static let IS_IPHONE_6 = UIDevice.current.userInterfaceIdiom == .phone && Constants.SCREEN_MAX_LENGTH == 667
        static let IS_IPHONE_6P = UIDevice.current.userInterfaceIdiom == .phone && Constants.SCREEN_MAX_LENGTH == 736
        static let IS_IPAD = UIDevice.current.userInterfaceIdiom == .pad && Constants.SCREEN_MAX_LENGTH == 1024
    }


1
2
3
4
5
struct utsname systemInfo;
uname(&systemInfo);

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