如何确定当前的iPhone/设备型号?

有没有办法在Swift中获得设备型号名称(iPhone 4S, iPhone 5, iPhone 5S等)?

我知道有一个名为UIDevice.currentDevice().model的属性,但它只返回设备类型(iPod touch, iPhone, iPad, iPhone模拟器等)。

我也知道在Objective-C中使用以下方法可以轻松完成:

#import <sys/utsname.h>


struct utsname systemInfo;
uname(&systemInfo);


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

但是我正在Swift中开发我的iPhone应用程序,所以有人可以帮助我用等效的方法在Swift中解决这个问题吗?

365990 次浏览

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

@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

在迅捷的一面:

let deviceModel = DeviceInfo.model()

我做了这个“纯斯威夫特”;扩展UIDevice

如果你正在寻找一个更优雅的解决方案,你可以使用在GitHub上发布的我的µ-framework DeviceKit(也可以通过CocoaPods, Carthage和Swift Package Manager获得)。

代码如下:

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 (5th generation)"
case "iPod7,1":                                       return "iPod touch (6th generation)"
case "iPod9,1":                                       return "iPod touch (7th generation)"
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 "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 "iPhone12,1":                                    return "iPhone 11"
case "iPhone12,3":                                    return "iPhone 11 Pro"
case "iPhone12,5":                                    return "iPhone 11 Pro Max"
case "iPhone13,1":                                    return "iPhone 12 mini"
case "iPhone13,2":                                    return "iPhone 12"
case "iPhone13,3":                                    return "iPhone 12 Pro"
case "iPhone13,4":                                    return "iPhone 12 Pro Max"
case "iPhone14,4":                                    return "iPhone 13 mini"
case "iPhone14,5":                                    return "iPhone 13"
case "iPhone14,2":                                    return "iPhone 13 Pro"
case "iPhone14,3":                                    return "iPhone 13 Pro Max"
case "iPhone14,7":                                    return "iPhone 14"
case "iPhone14,8":                                    return "iPhone 14 Plus"
case "iPhone15,2":                                    return "iPhone 14 Pro"
case "iPhone15,3":                                    return "iPhone 14 Pro Max"
case "iPhone8,4":                                     return "iPhone SE"
case "iPhone12,8":                                    return "iPhone SE (2nd generation)"
case "iPhone14,6":                                    return "iPhone SE (3rd generation)"
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":      return "iPad 2"
case "iPad3,1", "iPad3,2", "iPad3,3":                 return "iPad (3rd generation)"
case "iPad3,4", "iPad3,5", "iPad3,6":                 return "iPad (4th generation)"
case "iPad6,11", "iPad6,12":                          return "iPad (5th generation)"
case "iPad7,5", "iPad7,6":                            return "iPad (6th generation)"
case "iPad7,11", "iPad7,12":                          return "iPad (7th generation)"
case "iPad11,6", "iPad11,7":                          return "iPad (8th generation)"
case "iPad12,1", "iPad12,2":                          return "iPad (9th generation)"
case "iPad13,18", "iPad13,19":                        return "iPad (10th generation)"
case "iPad4,1", "iPad4,2", "iPad4,3":                 return "iPad Air"
case "iPad5,3", "iPad5,4":                            return "iPad Air 2"
case "iPad11,3", "iPad11,4":                          return "iPad Air (3rd generation)"
case "iPad13,1", "iPad13,2":                          return "iPad Air (4th generation)"
case "iPad13,16", "iPad13,17":                        return "iPad Air (5th 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 (5th generation)"
case "iPad14,1", "iPad14,2":                          return "iPad mini (6th generation)"
case "iPad6,3", "iPad6,4":                            return "iPad Pro (9.7-inch)"
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) (1st generation)"
case "iPad8,9", "iPad8,10":                           return "iPad Pro (11-inch) (2nd generation)"
case "iPad13,4", "iPad13,5", "iPad13,6", "iPad13,7":  return "iPad Pro (11-inch) (3rd generation)"
case "iPad14,3", "iPad14,4":                          return "iPad Pro (11-inch) (4th generation)"
case "iPad6,7", "iPad6,8":                            return "iPad Pro (12.9-inch) (1st generation)"
case "iPad7,1", "iPad7,2":                            return "iPad Pro (12.9-inch) (2nd generation)"
case "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8":      return "iPad Pro (12.9-inch) (3rd generation)"
case "iPad8,11", "iPad8,12":                          return "iPad Pro (12.9-inch) (4th generation)"
case "iPad13,8", "iPad13,9", "iPad13,10", "iPad13,11":return "iPad Pro (12.9-inch) (5th generation)"
case "iPad14,5", "iPad14,6":                          return "iPad Pro (12.9-inch) (6th generation)"
case "AppleTV5,3":                                    return "Apple TV"
case "AppleTV6,2":                                    return "Apple TV 4K"
case "AudioAccessory1,1":                             return "HomePod"
case "AudioAccessory5,1":                             return "HomePod mini"
case "i386", "x86_64", "arm64":                       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)
}()


}

你这样称呼它:

let modelName = UIDevice.modelName

对于真实设备,它返回“iPad Pro(12.9英寸)(第五代)”,对于模拟器,它返回“模拟器iPad Pro(12.9英寸)(第五代)”。

下面是模型参考:

斯威夫特3.0示例将当前设备模型作为enum常量返回(以避免与字符串字面值直接比较)。枚举的值是一个包含人类可读的iOS设备名称的String。因为它是Swift,所以认可的设备列表只包括最新的机型,足以支持包含Swift的iOS版本。下面的使用示例利用了这个答案末尾的实现:

    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都是“iPhone 4”。避免编写不考虑新型号的代码,这样你的算法就不会意外地配置失败或对新设备做出响应。你可以参考这个维护的iOS设备型号#'s 列表来在关键时刻更新你的应用程序。

iOS包括与设备无关的接口,用于检测硬件功能和屏幕大小等参数。苹果提供的通用接口通常是最安全、最受支持的机制,可以动态调整应用程序的行为以适应不同的硬件。尽管如此,下面的代码对于原型、调试、测试或任何需要针对特定设备系列的代码都是有用的。这种技术还可以用于用通用/公众认可的名称来描述当前设备。

斯威夫特3

// 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",
iPhone11         = "iPhone 11",
iPhone11Pro      = "iPhone 11 Pro",
iPhone11ProMax   = "iPhone 11 Pro Max",
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,
"iPhone12,1" : .iPhone11,
"iPhone12,3" : .iPhone11Pro,
"iPhone12,5" : .iPhone11ProMax
]


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

还有另一个/简单的替代方案(在https://www.theiphonewiki.com/wiki/Models中找到模型标识符引用):

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

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

我已经基于一些给出的答案实现了超轻量的库来检测使用的设备: https://github.com/schickling/Device.swift

它可以通过迦太基安装,并像这样使用:

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

斯威夫特5

/// Obtain the machine hardware platform from the `uname()` unix command
///
/// Example of return values
///  - `"iPhone8,1"` = iPhone 6s
///  - `"iPad6,7"` = iPad Pro (12.9-inch)
static var unameMachine: String {
var utsnameInstance = utsname()
uname(&utsnameInstance)
let optionalString: String? = withUnsafePointer(to: &utsnameInstance.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
ptr in String.init(validatingUTF8: ptr)
}
}
return optionalString ?? "N/A"
}

下面是获取硬件字符串的代码,但是您需要比较这些硬件字符串才能知道它是哪个设备。我已经创建了一个类,包含几乎所有的设备字符串(我们保持字符串最新的新设备)。使用方便,请检查

__abc0: __abc1

__abc0: __abc1

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
}

对于设备和模拟器, 创建一个名为UIDevice.swift

的新的swift文件

添加以下代码

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

然后在你的视图控制器中,

 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")
}
当你使用Swift 3时,接受的答案有一些问题! 这个答案(灵感来自NAZIK)适用于Swift 3和新的iPhone型号:

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中是这样的

 UIDevice.current.model

如果你不想每次苹果向设备家族添加新型号时都更新你的代码,可以使用下面的方法只返回型号代码。

func platform() -> String {
var systemInfo = utsname()
uname(&systemInfo)
let modelCode = withUnsafeMutablePointer(&systemInfo.machine) {
ptr in String.fromCString(UnsafePointer<CChar>(ptr))
}


return String.fromCString(modelCode!)!
}

我发现很多答案都用了字符串。我决定改变@HAS答案使用一个enum:

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


}
struct utsname systemInfo;
uname(&systemInfo);


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

这里有一个没有强制unwrap和Swift 3.0的修改:

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

使用Swift 3 (Xcode 8.3)

    func deviceName() -> String {
var systemInfo = utsname()
uname(&systemInfo)
let str = withUnsafePointer(to: &systemInfo.machine.0) { ptr in
return String(cString: ptr)
}
return str
}

注意:根据官方开发论坛的回答,以这种方式使用元组是安全的。大Int8元组的内存对齐方式将与大Int8数组相同。即:连续且无填充。

斯威夫特3.1

我对简单地调用utsname的看法是:

    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和后面的所有复杂的东西更清楚一点。 ): < / p >

返回值如"x86_64"

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

Swift 3.0或更高版本

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

并添加以下扩展

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

斯威夫特5。X,两者装置&模拟器更新至2022年

(总是检查和更新!)

最后:iPhone 14所有版本,iPhone SE第三代2022第五代iPad AiriPhone 13(所有型号)2021年第9代iPad2021年第六代iPad mini苹果手表系列7, iPad Pro(11英寸)(第三代),iPad Pro(12.9英寸)(第五代)和Apple TV 4K(第二代),(更新也为所有的ipod、苹果手表和苹果电视)

即使是模拟器,该方法也能检测出正确的模型。(在模拟器中运行的模拟器设备模型的确切名称)

有了这个答案,由于枚举,您可以在几行中检查多个设备

例子:

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
}

这是代码:

public enum Model : String {


//Simulator
case simulator     = "simulator/sandbox",


//iPod
iPod1              = "iPod 1",
iPod2              = "iPod 2",
iPod3              = "iPod 3",
iPod4              = "iPod 4",
iPod5              = "iPod 5",
iPod6              = "iPod 6",
iPod7              = "iPod 7",


//iPad
iPad2              = "iPad 2",
iPad3              = "iPad 3",
iPad4              = "iPad 4",
iPadAir            = "iPad Air ",
iPadAir2           = "iPad Air 2",
iPadAir3           = "iPad Air 3",
iPadAir4           = "iPad Air 4",
iPadAir5           = "iPad Air 5",
iPad5              = "iPad 5", //iPad 2017
iPad6              = "iPad 6", //iPad 2018
iPad7              = "iPad 7", //iPad 2019
iPad8              = "iPad 8", //iPad 2020
iPad9              = "iPad 9", //iPad 2021


//iPad Mini
iPadMini           = "iPad Mini",
iPadMini2          = "iPad Mini 2",
iPadMini3          = "iPad Mini 3",
iPadMini4          = "iPad Mini 4",
iPadMini5          = "iPad Mini 5",
iPadMini6          = "iPad Mini 6",


//iPad Pro
iPadPro9_7         = "iPad Pro 9.7\"",
iPadPro10_5        = "iPad Pro 10.5\"",
iPadPro11          = "iPad Pro 11\"",
iPadPro2_11        = "iPad Pro 11\" 2nd gen",
iPadPro3_11        = "iPad Pro 11\" 3rd gen",
iPadPro12_9        = "iPad Pro 12.9\"",
iPadPro2_12_9      = "iPad Pro 2 12.9\"",
iPadPro3_12_9      = "iPad Pro 3 12.9\"",
iPadPro4_12_9      = "iPad Pro 4 12.9\"",
iPadPro5_12_9      = "iPad Pro 5 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",
iPhone11           = "iPhone 11",
iPhone11Pro        = "iPhone 11 Pro",
iPhone11ProMax     = "iPhone 11 Pro Max",
iPhoneSE2          = "iPhone SE 2nd gen",
iPhone12Mini       = "iPhone 12 Mini",
iPhone12           = "iPhone 12",
iPhone12Pro        = "iPhone 12 Pro",
iPhone12ProMax     = "iPhone 12 Pro Max",
iPhone13Mini       = "iPhone 13 Mini",
iPhone13           = "iPhone 13",
iPhone13Pro        = "iPhone 13 Pro",
iPhone13ProMax     = "iPhone 13 Pro Max",
iPhoneSE3          = "iPhone SE 3nd gen",
iPhone14           = "iPhone 14",
iPhone14Plus       = "iPhone 14 Plus",
iPhone14Pro        = "iPhone 14 Pro",
iPhone14ProMax     = "iPhone 14 Pro Max",


// Apple Watch
AppleWatch1         = "Apple Watch 1gen",
AppleWatchS1        = "Apple Watch Series 1",
AppleWatchS2        = "Apple Watch Series 2",
AppleWatchS3        = "Apple Watch Series 3",
AppleWatchS4        = "Apple Watch Series 4",
AppleWatchS5        = "Apple Watch Series 5",
AppleWatchSE        = "Apple Watch Special Edition",
AppleWatchS6        = "Apple Watch Series 6",
AppleWatchS7        = "Apple Watch Series 7",


//Apple TV
AppleTV1           = "Apple TV 1gen",
AppleTV2           = "Apple TV 2gen",
AppleTV3           = "Apple TV 3gen",
AppleTV4           = "Apple TV 4gen",
AppleTV_4K         = "Apple TV 4K",
AppleTV2_4K        = "Apple TV 4K 2gen",


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

let modelMap : [String: Model] = [
    

//Simulator
"i386"      : .simulator,
"x86_64"    : .simulator,
    

//iPod
"iPod1,1"   : .iPod1,
"iPod2,1"   : .iPod2,
"iPod3,1"   : .iPod3,
"iPod4,1"   : .iPod4,
"iPod5,1"   : .iPod5,
"iPod7,1"   : .iPod6,
"iPod9,1"   : .iPod7,
    

//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,
"iPad6,11"  : .iPad5, //iPad 2017
"iPad6,12"  : .iPad5,
"iPad7,5"   : .iPad6, //iPad 2018
"iPad7,6"   : .iPad6,
"iPad7,11"  : .iPad7, //iPad 2019
"iPad7,12"  : .iPad7,
"iPad11,6"  : .iPad8, //iPad 2020
"iPad11,7"  : .iPad8,
"iPad12,1"  : .iPad9, //iPad 2021
"iPad12,2"  : .iPad9,
    

//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,
"iPad11,1"  : .iPadMini5,
"iPad11,2"  : .iPadMini5,
"iPad14,1"  : .iPadMini6,
"iPad14,2"  : .iPadMini6,
    

//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,9"   : .iPadPro2_11,
"iPad8,10"  : .iPadPro2_11,
"iPad13,4"  : .iPadPro3_11,
"iPad13,5"  : .iPadPro3_11,
"iPad13,6"  : .iPadPro3_11,
"iPad13,7"  : .iPadPro3_11,
"iPad8,5"   : .iPadPro3_12_9,
"iPad8,6"   : .iPadPro3_12_9,
"iPad8,7"   : .iPadPro3_12_9,
"iPad8,8"   : .iPadPro3_12_9,
"iPad8,11"  : .iPadPro4_12_9,
"iPad8,12"  : .iPadPro4_12_9,
"iPad13,8"  : .iPadPro5_12_9,
"iPad13,9"  : .iPadPro5_12_9,
"iPad13,10" : .iPadPro5_12_9,
"iPad13,11" : .iPadPro5_12_9,
    

//iPad Air
"iPad4,1"   : .iPadAir,
"iPad4,2"   : .iPadAir,
"iPad4,3"   : .iPadAir,
"iPad5,3"   : .iPadAir2,
"iPad5,4"   : .iPadAir2,
"iPad11,3"  : .iPadAir3,
"iPad11,4"  : .iPadAir3,
"iPad13,1"  : .iPadAir4,
"iPad13,2"  : .iPadAir4,
"iPad13,16" : .iPadAir5,
"iPad13,17" : .iPadAir5,
    

//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,
"iPhone12,1" : .iPhone11,
"iPhone12,3" : .iPhone11Pro,
"iPhone12,5" : .iPhone11ProMax,
"iPhone12,8" : .iPhoneSE2,
"iPhone13,1" : .iPhone12Mini,
"iPhone13,2" : .iPhone12,
"iPhone13,3" : .iPhone12Pro,
"iPhone13,4" : .iPhone12ProMax,
"iPhone14,4" : .iPhone13Mini,
"iPhone14,5" : .iPhone13,
"iPhone14,2" : .iPhone13Pro,
"iPhone14,3" : .iPhone13ProMax,
"iPhone14,6" : .iPhoneSE3,
"iPhone14,7" : .iPhone14,
"iPhone14,8" : .iPhone14Plus,
"iPhone15,2" : .iPhone14Pro,
"iPhone15,3" : .iPhone14ProMax,
            

// Apple Watch
"Watch1,1" : .AppleWatch1,
"Watch1,2" : .AppleWatch1,
"Watch2,6" : .AppleWatchS1,
"Watch2,7" : .AppleWatchS1,
"Watch2,3" : .AppleWatchS2,
"Watch2,4" : .AppleWatchS2,
"Watch3,1" : .AppleWatchS3,
"Watch3,2" : .AppleWatchS3,
"Watch3,3" : .AppleWatchS3,
"Watch3,4" : .AppleWatchS3,
"Watch4,1" : .AppleWatchS4,
"Watch4,2" : .AppleWatchS4,
"Watch4,3" : .AppleWatchS4,
"Watch4,4" : .AppleWatchS4,
"Watch5,1" : .AppleWatchS5,
"Watch5,2" : .AppleWatchS5,
"Watch5,3" : .AppleWatchS5,
"Watch5,4" : .AppleWatchS5,
"Watch5,9" : .AppleWatchSE,
"Watch5,10" : .AppleWatchSE,
"Watch5,11" : .AppleWatchSE,
"Watch5,12" : .AppleWatchSE,
"Watch6,1" : .AppleWatchS6,
"Watch6,2" : .AppleWatchS6,
"Watch6,3" : .AppleWatchS6,
"Watch6,4" : .AppleWatchS6,
"Watch6,6" : .AppleWatchS7,
"Watch6,7" : .AppleWatchS7,
"Watch6,8" : .AppleWatchS7,
"Watch6,9" : .AppleWatchS7,
    

//Apple TV
"AppleTV1,1" : .AppleTV1,
"AppleTV2,1" : .AppleTV2,
"AppleTV3,1" : .AppleTV3,
"AppleTV3,2" : .AppleTV3,
"AppleTV5,3" : .AppleTV4,
"AppleTV6,2" : .AppleTV_4K,
"AppleTV11,1" : .AppleTV2_4K
]
    

guard let mcode = modelCode, let map = String(validatingUTF8: mcode), let model = modelMap[map] else { return Model.unrecognized }
if model == .simulator {
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
if let simMap = String(validatingUTF8: simModelCode), let simModel = modelMap[simMap] {
return simModel
}
}
}
return model
}
}
< p > 使用: 您可以简单地使用

获取设备模型
let deviceType = UIDevice().type

或打印精确的字符串:

print("Running on: \(UIDevice().type)")
Output -> "iPhone X"

另一个带有case的例子 < / >强:

var myDefaultHeight: CGFloat = 30.0
switch UIDevice().type {
case .iPhoneSE, .iPhone5, .iPhone5S: print("default value")
case .iPhone6, .iPhone7, .iPhone8, .iPhone6S, .iPhoneX: myDefaultHeight+= 5
case .iPhone11, .iPhone12, .iPhone13: myDefaultHeight+= 10
default: break
}

苹果设备型号访问: https://www.theiphonewiki.com/wiki/Models < / p >

我已经做了一个小小的新的异步实验在这里(直接连接到iphonewiki站点,没有长静态设备列表在源代码。

我在UIDevice上做了另一个示例扩展,包括基于@HAS的回答的模拟器模型标识符。它在上面的Swift3.2(包括Swift 4)中工作得很好。x, Swift 5):

let modelName = UIDevice.current.modelName

新增型号:iPod touch(第七代),iPhone SE(第二代),iPhone 12 mini, iPhone 12 Pro, iPhone 12 Pro Max, iPad Pro(12.9英寸)(第四代)

import UIKit


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 "iPod9,1":                                 return "iPod touch (7th generation)"
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 "iPhone12,1":                              return "iPhone 11"
case "iPhone12,3":                              return "iPhone 11 Pro"
case "iPhone12,5":                              return "iPhone 11 Pro Max"
case "iPhone12,8":                              return "iPhone SE (2nd generation)"
case "iPhone13,1":                              return "iPhone 12 mini"
case "iPhone13,2":                              return "iPhone 12"
case "iPhone13,3":                              return "iPhone 12 Pro"
case "iPhone13,4":                              return "iPhone 12 Pro Max"
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 "iPad8,11", "iPad8,12":                    return "iPad Pro (12.9-inch) (4th generation)"
case "AppleTV5,3":                              return "Apple TV"
case "AppleTV6,2":                              return "Apple TV 4K"
case "AudioAccessory1,1":                       return "HomePod"
default:                                        return identifier
}
}
}

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

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

和使用:

switch UIDevice.current.modelName {
case "iPhone 4":
case "iPhone 5":
case "iPhone 6,7,8":
case "iPhone Plus":
case "iPhone X":
case "Simulator":
default:
}
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
}

基于这个回答和这个回答。我已经创建了一个公共要点

如何使用它

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...

这是要点里面的代码

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

你可以使用BDLocalizedDevicesModels框架来解析设备信息并获得名称。

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

获取模型名称(营销名称)的最简单方法

小心使用私有API -[UIDevice _deviceInfoForKey:],你不会被Apple拒绝。

// works on both simulators and real devices, iOS 8 to iOS 12
NSString *deviceModelName(void) {
// For Simulator
NSString *modelName = NSProcessInfo.processInfo.environment[@"SIMULATOR_DEVICE_NAME"];
if (modelName.length > 0) {
return modelName;
}


// For real devices and simulators, except simulators running on iOS 8.x
UIDevice *device = [UIDevice currentDevice];
NSString *selName = [NSString stringWithFormat:@"_%@ForKey:", @"deviceInfo"];
SEL selector = NSSelectorFromString(selName);
if ([device respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
modelName = [device performSelector:selector withObject:@"marketing-name"];
#pragma clang diagnostic pop
}
return modelName;
}

我是怎么得到“营销名称”这个关键字的?

运行在模拟器上的NSProcessInfo.processInfo.environment包含一个名为“simulator_capabilities”的键,该键的值是一个plist文件。然后你打开plist文件,你会得到模型名称的关键字“marketing-name”。

这里有一个帮助器图书馆

斯威夫特5

'DeviceKit', '~> 2.0'

Swift 4.0 - Swift 4.2

'DeviceKit', '~> 1.3'

如果你只是想确定模型并做出相应的东西。

你可以这样用:

let isIphoneX = Device().isOneOf([.iPhoneX, .simulator(.iPhoneX)])

在函数中:

func isItIPhoneX() -> Bool {
let device = Device()
let check = device.isOneOf([.iPhoneX, .iPhoneXr , .iPhoneXs , .iPhoneXsMax ,
.simulator(.iPhoneX), .simulator(.iPhoneXr) , .simulator(.iPhoneXs) , .simulator(.iPhoneXsMax) ])
return check
}

对于swift4.0及以上使用以下代码:

let udid = UIDevice.current.identifierForVendor?.uuidString
let name = UIDevice.current.name
let version = UIDevice.current.systemVersion
let modelName = UIDevice.current.model
let osName = UIDevice.current.systemName
let localized = UIDevice.current.localizedModel


print(udid ?? "")
print(name)
print(version)
print(modelName)
print(osName)
print(localized)

WikiDevice

异步库,从iphonewiki给你答案

对于像我这样的自动化爱好者来说,这是一个疯狂的小实验。我做了这个算法,读取设备的识别码,物理或模拟,并加载theiphonewiki页,以根据识别码推断模型名称(示例iPhone11 2 ->iPhone XS)。该算法使用内部WIKI API沙盒工具与WIKI页面进行接口,该工具允许您有一个JSON响应,但是内容无法以JSON形式获得(只是需要的部分,即wikitables),因此我解析了HTML内容以获得设备名称,而不使用第三方HTML解析库。

优点:总是更新,你不需要添加新的设备

缺点:使用wiki页面从web异步回答

P.S. 请随意改进我的代码,以获得更精确的结果和更优雅的语法 P.S.S. 如果你需要一个更直接的答案,请使用我之前的答案here in this page < / p >

public extension UIDevice {
var identifier: String {
var systemInfo = utsname()
uname(&systemInfo)
let modelCode = withUnsafePointer(to: &systemInfo.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
ptr in String.init(validatingUTF8: ptr)
}
}
if modelCode == "x86_64" {
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
if let simMap = String(validatingUTF8: simModelCode) {
return simMap
}
}
}
return modelCode ?? "?unrecognized?"
}
}
class WikiDevice {
static func model(_ completion: @escaping ((String) -> ())){
let unrecognized = "?unrecognized?"
guard let wikiUrl=URL(string:"https://www.theiphonewiki.com//w/api.php?action=parse&format=json&page=Models") else { return completion(unrecognized) }
var identifier: String {
var systemInfo = utsname()
uname(&systemInfo)
let modelCode = withUnsafePointer(to: &systemInfo.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
ptr in String.init(validatingUTF8: ptr)
}
}
if modelCode == "x86_64" {
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
if let simMap = String(validatingUTF8: simModelCode) {
return simMap
}
}
}
return modelCode ?? unrecognized
}
guard identifier != unrecognized else { return completion(unrecognized)}
let request = URLRequest(url: wikiUrl)
URLSession.shared.dataTask(with: request) { (data, response, error) in
do {
guard let data = data,
let response = response as? HTTPURLResponse, (200 ..< 300) ~= response.statusCode,
error == nil else { return completion(unrecognized) }
guard let convertedString = String(data: data, encoding: String.Encoding.utf8) else { return completion(unrecognized) }
var wikiTables = convertedString.components(separatedBy: "wikitable")
wikiTables.removeFirst()
var tables = [[String]]()
wikiTables.enumerated().forEach{ index,table in
let rawRows = table.components(separatedBy: #"<tr>\n<td"#)
var counter = 0
var rows = [String]()
while counter < rawRows.count {
let rawRow = rawRows[counter]
if let subRowsNum = rawRow.components(separatedBy: #"rowspan=\""#).dropFirst().compactMap({ sub in
(sub.range(of: #"\">"#)?.lowerBound).flatMap { endRange in
String(sub[sub.startIndex ..< endRange])
}
}).first {
if let subRowsTot = Int(subRowsNum) {
var otherRows = ""
for i in counter..<counter+subRowsTot {
otherRows += rawRows[i]
}
let row = rawRow + otherRows
rows.append(row)
counter += subRowsTot-1
}
} else {
rows.append(rawRows[counter])
}
counter += 1
}
tables.append(rows)
}
for table in tables {
if let rowIndex = table.firstIndex(where: {$0.lowercased().contains(identifier.lowercased())}) {
let rows = table[rowIndex].components(separatedBy: "<td>")
if rows.count>0 {
if rows[0].contains("title") { //hyperlink
if let (cleanedGen) = rows[0].components(separatedBy: #">"#).dropFirst().compactMap({ sub in
(sub.range(of: "</")?.lowerBound).flatMap { endRange in
String(sub[sub.startIndex ..< endRange]).replacingOccurrences(of: #"\n"#, with: "")
}
}).first {
completion(cleanedGen)
}
} else {
let raw = rows[0].replacingOccurrences(of: "<td>", with: "")
let cleanedGen = raw.replacingOccurrences(of: #"\n"#, with: "")
completion(cleanedGen)
}
return
}
}
}
completion(unrecognized)
}
}.resume()
}
}

用法:

var deviceModel:String = ""
WikiDevice.model { (model) in
print("Using WikiDevice, running on: \(model)")
deviceModel = model
}

输出:

Using WikiDevice, running on: iPhone 11 Pro Max

GitHUB:

如果你需要测试这个库,你可以从在这里下载测试项目

下面是一个用于检测apple设备的新图书馆

import DeviceDetector


let detector = DeviceDetector.shared
let deviceName = detector.currentDeviceName
let deviceSet = detector.currentDevice
        

let information = """
Model: \(deviceName)
iPhone?: \(detector.isiPhone)
iPad?: \(detector.isiPad)
Notch?: \(detector.hasSafeArea)
        

4inch?: \(DeviceSet.iPhone4inchSet.contains(deviceSet))
4.7inch?: \(DeviceSet.iPhone4_7inchSet.contains(deviceSet))
iPhoneSE?: \(DeviceSet.iPhoneSESet.contains(deviceSet))
iPhonePlus?: \(DeviceSet.iPhonePlusSet.contains(deviceSet))
iPadPro?: \(DeviceSet.iPadProSet.contains(deviceSet))
"""
< p >结果 enter image description here < / p >

对我有用

var sysinfo = utsname()
uname(&sysinfo)
let data = Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN))
let model = String(cString: [UInt8](data) //iPhone13,1