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

542

有没有一种方法可以在Swift中获取设备型号名称(iPhone 4S,iPhone 5,iPhone 5S等)?

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

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

#import <sys/utsname.h>

struct utsname systemInfo;
uname(&systemInfo);

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

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


5
用 Objective C 编写代码,然后在 Swift 中调用它。 - Kevin
1
请看这里 https://dev59.com/h1YO5IYBdhLWcg3wMO1y#52821290 - ale_stro
@jww CarPlay 运行在 iOS 设备上。iOS 只使用汽车(音响)的显示器、触摸输入、扬声器等,所有操作都在 iOS 设备上执行,而不是在汽车(音响)上执行。 - d4Rk
Xamarin iOS: https://github.com/dannycabrera/Get-iOS-Model - Nick Kovalsky
有没有简单的方法可以获得它? - flymaxelib
显示剩余2条评论
32个回答

1244
我在UIDevice上创建了这个“纯Swift”扩展。
如果你正在寻找更优雅的解决方案,你可以使用我在GitHub上发布的我的µ框架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 "iPhone15,4":                                    return "iPhone 15"
            case "iPhone15,5":                                    return "iPhone 15 Plus"
            case "iPhone16,1":                                    return "iPhone 15 Pro"
            case "iPhone16,2":                                    return "iPhone 15 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
我修改了你的示例,并在下面发布了一个新的示例。所有繁重的工作都是由你和其他人完成的,我只是进行了实验、组合和精炼。 - clearlight
2
@HAS reflect在iOS 9中抛出错误,他们是否已经弃用它了? - Dan Beaulieu
3
@Doug 很好的问题,我可能应该在答案中包含那个... https://www.theiphonewiki.com/wiki/Models - HAS
4
可以请你更新一下,适用于 iPhone XS、XS Max 和 XR 吗? - Jordan H
3
@AlexanderVolkov哪一个是不正确的,应该怎么做才能更好?让我们一起改进它,而不只是说它错了。如果您知道,请与我们分享! - CyberMew
显示剩余45条评论

256
Swift 5.x,无论是设备还是模拟器,都支持ENUMS(用于检查您偏好的任何组或型号)。

- 截至2023年9月更新 -

(始终检查和更新!)

最新的设备有:iPad 第10代iPhone 15 所有版本,iPhone SE 第3代 2022iPad Air 第5代iPhone 13(所有型号)iPad 第9代 2021iPad mini 第6代 2021Apple Watch Series 7,iPad Pro(11英寸)(第3代),iPad Pro(12.9英寸)(第5代)和 Apple TV 4K(第2代),(也适用于所有iPods、Apple Watches和Apple TVs

即使是模拟器,该方法也可以检测到正确的型号。(您模拟器中运行的模拟器设备型号的确切名称)

通过这个答案,您可以用几行代码检查多个设备

示例:

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
iPad10             = "iPad 10", //iPad 2022

//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",
iPhone15           = "iPhone 15",
iPhone15Plus       = "iPhone 15 Plus",
iPhone15Pro        = "iPhone 15 Pro",
iPhone15ProMax     = "iPhone 15 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,
            "iPad13,18" : .iPad10,
            "iPad13,19" : .iPad10,
    
            //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,
            "iPhone15,4" : .iPhone15,
            "iPhone15,5" : .iPhone15Plus,
            "iPhone16,1" : .iPhone15Pro,
            "iPhone16,2" : .iPhone15ProMax,
            
            // 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
    }
}

使用方法: 您可以简单地通过以下方式获取设备型号:
let deviceType = UIDevice().type

或者使用以下代码打印完整的字符串:
print("Running on: \(UIDevice().type)")
Output -> "iPhone X"

另一个带有案例的例子:
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 附注: 我在这里进行了一个小的异步实验here(直接连接到THEIPHONEWIKI网站,而不是在源代码中长时间静态设备列表)。

3
你的输出有误,你需要请求 UIDevice().type.rawValue 以获取带空格的设备名称。 - Radu Ursache
1
请添加iPhone SE第二代。iPhone12,8 - tperei
3
它在苹果硅片(M1 Mac Mini)上无法工作。在模拟器中,它总是返回Model.unrecognized。尽管在真实设备中按预期工作(已在iPhone X和12 mini上进行测试)。 编辑:修复添加“arm64”:.simulator到字典中。 - juanjovn
2
感谢 @AlessandroOrnano 的更新。 - Mehul
5
Xcode 14显示'init(validatingUTF8:)'已弃用:请使用字符串参数的副本,我不确定要替换成什么。你能帮忙吗? - Arjan
显示剩余25条评论

162

这个Swift 3.0的例子返回当前设备模型作为一个enum常量(避免直接比较字符串文字)。枚举的raw值是一个包含人类可读的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 设备型号列表 在适当的时间更新您的应用程序。

iOS 包含独立于设备的接口,用于检测硬件能力和参数,如屏幕大小。苹果提供的通用接口通常是动态适应不同硬件的应用程序行为的最安全、最受支持的机制。尽管如此,以下代码对于原型设计、调试、测试或任何需要针对特定设备系列进行编程的时候都可能有用。此技术还可以描述当前设备的公共认可名称。

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

在Swift 2中替换:let machinePtr = advance(ptr.baseAddress, Int(_SYS_NAMELEN * 4))let machinePtr = ptr.baseAddress.advancedBy(Int(_SYS_NAMELEN * 4)) - DrPatience
您在 modelMap 中有重复的键,这会导致iOS报错:Duplicate literals in keys - alekperos
3
最新的Swift 3.0.2在部分代码if let model = modelMap[String.fromCString(modelCode!)!]中出现了问题。解决方法是先解码CString,然后将解码后的字符串提供给modelMap如果让(str, _) = String.decodeCString(modelCode, as: UTF8.self, repairingInvalidCodeUnits: false),则如果有可用的model,则返回这个model。 - alekperos
3
正如 @alekperos 所说,这段代码中有一个打字错误。应该是:if let model = modelMap[String.init(validatingUTF8: deviceModelCode()!)!] { return model } - wuf810
@clearlight,iPad Pro 属于哪个维度类别? - ItsMeAgain
显示剩余4条评论

142

另一个/简单的替代方案(模型标识符参考资料可在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)
}

4
好的,最简单的答案。 - Sazzad Hissain Khan
1
嗨@JafarKhoshtabiat :) 它是UNIX的一部分,我已经在App Store上使用它多年了 :) - Jens Schwarzer
2
用于模拟器检测: #if targetEnvironment(simulator) #endif - gutte
1
@Houman 标识符与设备型号不同。因此,预计输出为“12,1”。请检查答案中的链接。 - Luke
1
@KyLeggiero 糟糕!嗯,我非常确定它从未失败过。但如果这让你夜不能寐,请随意在您自己的代码中添加一个测试;) - Jens Schwarzer
显示剩余8条评论

40

我在UIDevice上创建了另一个样本扩展,基于@HAS的答案包含模拟器型号标识符。它在Swift3.2及以上版本(包括Swift 4.x、Swift 5)中都可以正常使用:

let modelName = UIDevice.current.modelName

新增型号:iPod touch(第7代),iPhone SE(第2代),iPhone 12 mini,iPhone 12,iPhone 12 Pro,iPhone 12 Pro Max,iPad Pro(12.9英寸)(第4代)

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

31

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

3
这个内容具有额外的好处,不依赖于UIKit。 - bshirley
很遗憾,这个解决方案看起来很棒。但是我无法在Swift 5上使其工作。有什么建议吗? - Houman
请注意,这不会返回iPhone 6s,而是返回iPhone8,1。 - Jordan H
不建议使用此功能,因为它会将 iPhone6 更换为 iPhone7。 - idej1234
2
人们误解了:苹果不会给你“iPhone 12 Max”,它会给你这些用逗号分隔的字符串,然后你需要将它们映射到它们的“纯文本”型号名称!他甚至在代码块标题中都指出了这一点!!! - David H

18

使用 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 数组相同。也就是说:连续并且没有填充。


这个与UIKit无关的程序还有额外的好处。 - bshirley
这个答案被低估了!比使用镜像简单得多。你甚至可以进一步简化它,像这样省略 withUnsafePointer 调用:return String(cString: &sysinfo.machine.0) - mklbtz
@mklbtz 不错的建议,只是它返回一个可选字符串。我期望像 deviceName() 这样的返回值是非可选的,否则我会使用你的建议。 - Stunner
@Stunner 嗯,也许你误解了我的意思,但这并不使其变成可选项。func deviceName() -> String { var systemInfo = utsname() uname(&systemInfo) return String(cString: &systemInfo.machine.0) } - mklbtz
这是在Xcode 14/Swift 5.7中的操作方式。同时,由于String(cString:)实现的最近更改,return String(cString: &sysinfo.machine.0)将会导致崩溃。 - apparition47

16

无论是设备还是模拟器, 创建一个名为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")
    }

XCode 7.2表示,该行if let dir = NSProcessInfo()。environment["SIMULATOR_MODEL_IDENTIFIER"]将永远不会被执行。 - Deepak Thakur
@DeepakThakur,你试过在模拟器上运行吗?我也在使用Xcode 7.2,它正常工作。 - Nazik
iPhone 6和iPhone 6 Plus的尺寸不同。如何处理? - Jayprakash Dubey
@JayprakashDubey,在那个方法中它会返回“iPhone 6 Plus”作为6 Plus,你可以检查一下... - Nazik
1
获取模拟器类型的 Objective-C 等效方法是:[NSProcessInfo processInfo].environment[@"SIMULATOR_MODEL_IDENTIFIER"]。 - jk7

13

在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

在 Swift 方面:

let deviceModel = DeviceInfo.model()

谢谢mstysf。但我认为我在这里找到了一个解决方案https://dev59.com/hYLba4cB1Zd3GeqPg5sH#25380129。然而,你知道是否可能区分iPhone模拟器(iPhone4s,iPhone5,iPhone6)吗?因为对我来说,它似乎只返回“x86_64”用于所有iPhone模拟器,无论我选择哪个型号。 - The Mach System
抱歉,我认为复制时出现了错误。这是链接: https://dev59.com/hYLba4cB1Zd3GeqPg5sH#25380129 - The Mach System
1
@TheMachSystem 这种方法的整个问题就在于此。在大多数情况下,这不是适应您的应用程序行为的正确方式。您应该尽可能使用更通用的标准iOS接口来嗅探硬件配置和特性,尽管这可能需要更多的研究和编码工作。 - clearlight
@TheMachSystem 可能有点晚了,但是回答你的问题(模拟器是否可以区分iDevice型号)是不行的。你从utsname得到x86_64的原因是模拟器实际上是你的电脑,它的machine属性是x86_64。尝试将你的方法中的.machine更改为.nodename,返回值将会是类似于My-iMac.local的东西。 - xoudini

13
这是2023年1月更新的解决方案。它包括最新的iPhone、iPad、Watch、iPod、Apple TV和HomePod。
extension UIDevice {
    
    static 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 {
            // MARK: - iPhone
            case "i386": return "iPhone Simulator"
            case "x86_64": return "iPhone Simulator"
            case "arm64": return "iPhone Simulator"
            case "iPhone1,1": return "iPhone"
            case "iPhone1,2": return "iPhone 3G"
            case "iPhone2,1": return "iPhone 3GS"
            case "iPhone3,1": return "iPhone 4"
            case "iPhone3,2": return "iPhone 4 GSM Rev A"
            case "iPhone3,3": return "iPhone 4 CDMA"
            case "iPhone4,1": return "iPhone 4S"
            case "iPhone5,1": return "iPhone 5 (GSM)"
            case "iPhone5,2": return "iPhone 5 (GSM+CDMA)"
            case "iPhone5,3": return "iPhone 5C (GSM)"
            case "iPhone5,4": return "iPhone 5C (Global)"
            case "iPhone6,1": return "iPhone 5S (GSM)"
            case "iPhone6,2": return "iPhone 5S (Global)"
            case "iPhone7,1": return "iPhone 6 Plus"
            case "iPhone7,2": return "iPhone 6"
            case "iPhone8,1": return "iPhone 6s"
            case "iPhone8,2": return "iPhone 6s Plus"
            case "iPhone8,4": return "iPhone SE (GSM)"
            case "iPhone9,1": return "iPhone 7"
            case "iPhone9,2": return "iPhone 7 Plus"
            case "iPhone9,3": return "iPhone 7"
            case "iPhone9,4": return "iPhone 7 Plus"
            case "iPhone10,1": return "iPhone 8"
            case "iPhone10,2": return "iPhone 8 Plus"
            case "iPhone10,3": return "iPhone X Global"
            case "iPhone10,4": return "iPhone 8"
            case "iPhone10,5": return "iPhone 8 Plus"
            case "iPhone10,6": return "iPhone X GSM"
            case "iPhone11,2": return "iPhone XS"
            case "iPhone11,4": return "iPhone XS Max"
            case "iPhone11,6": return "iPhone XS Max Global"
            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 Gen"
            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,2": return "iPhone 13 Pro"
            case "iPhone14,3": return "iPhone 13 Pro Max"
            case "iPhone14,4": return "iPhone 13 Mini"
            case "iPhone14,5": return "iPhone 13"
            case "iPhone14,6": return "iPhone SE 3rd Gen"
            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 "iPhone15,4": return "iPhone 15"
            case "iPhone15,5": return "iPhone 15 Plus"
            case "iPhone16,1": return "iPhone 15 Pro"
            case "iPhone16,2": return "iPhone 15 Pro Max"
            
            // MARK: - iPod
            case "iPod1,1": return "1st Gen iPod"
            case "iPod2,1": return "2nd Gen iPod"
            case "iPod3,1": return "3rd Gen iPod"
            case "iPod4,1": return "4th Gen iPod"
            case "iPod5,1": return "5th Gen iPod"
            case "iPod7,1": return "6th Gen iPod"
            case "iPod9,1": return "7th Gen iPod"
            
            // MARK: - iPad
            case "iPad1,1": return "iPad"
            case "iPad1,2": return "iPad 3G"
            case "iPad2,1": return "2nd Gen iPad"
            case "iPad2,2": return "2nd Gen iPad GSM"
            case "iPad2,3": return "2nd Gen iPad CDMA"
            case "iPad2,4": return "2nd Gen iPad New Revision"
            case "iPad3,1": return "3rd Gen iPad"
            case "iPad3,2": return "3rd Gen iPad CDMA"
            case "iPad3,3": return "3rd Gen iPad GSM"
            case "iPad2,5": return "iPad mini"
            case "iPad2,6": return "iPad mini GSM+LTE"
            case "iPad2,7": return "iPad mini CDMA+LTE"
            case "iPad3,4": return "4th Gen iPad"
            case "iPad3,5": return "4th Gen iPad GSM+LTE"
            case "iPad3,6": return "4th Gen iPad CDMA+LTE"
            case "iPad4,1": return "iPad Air (WiFi)"
            case "iPad4,2": return "iPad Air (GSM+CDMA)"
            case "iPad4,3": return "1st Gen iPad Air (China)"
            case "iPad4,4": return "iPad mini Retina (WiFi)"
            case "iPad4,5": return "iPad mini Retina (GSM+CDMA)"
            case "iPad4,6": return "iPad mini Retina (China)"
            case "iPad4,7": return "iPad mini 3 (WiFi)"
            case "iPad4,8": return "iPad mini 3 (GSM+CDMA)"
            case "iPad4,9": return "iPad Mini 3 (China)"
            case "iPad5,1": return "iPad mini 4 (WiFi)"
            case "iPad5,2": return "4th Gen iPad mini (WiFi+Cellular)"
            case "iPad5,3": return "iPad Air 2 (WiFi)"
            case "iPad5,4": return "iPad Air 2 (Cellular)"
            case "iPad6,3": return "iPad Pro (9.7 inch, WiFi)"
            case "iPad6,4": return "iPad Pro (9.7 inch, WiFi+LTE)"
            case "iPad6,7": return "iPad Pro (12.9 inch, WiFi)"
            case "iPad6,8": return "iPad Pro (12.9 inch, WiFi+LTE)"
            case "iPad6,11": return "iPad (2017)"
            case "iPad6,12": return "iPad (2017)"
            case "iPad7,1": return "iPad Pro 2nd Gen (WiFi)"
            case "iPad7,2": return "iPad Pro 2nd Gen (WiFi+Cellular)"
            case "iPad7,3": return "iPad Pro 10.5-inch 2nd Gen"
            case "iPad7,4": return "iPad Pro 10.5-inch 2nd Gen"
            case "iPad7,5": return "iPad 6th Gen (WiFi)"
            case "iPad7,6": return "iPad 6th Gen (WiFi+Cellular)"
            case "iPad7,11": return "iPad 7th Gen 10.2-inch (WiFi)"
            case "iPad7,12": return "iPad 7th Gen 10.2-inch (WiFi+Cellular)"
            case "iPad8,1": return "iPad Pro 11 inch 3rd Gen (WiFi)"
            case "iPad8,2": return "iPad Pro 11 inch 3rd Gen (1TB, WiFi)"
            case "iPad8,3": return "iPad Pro 11 inch 3rd Gen (WiFi+Cellular)"
            case "iPad8,4": return "iPad Pro 11 inch 3rd Gen (1TB, WiFi+Cellular)"
            case "iPad8,5": return "iPad Pro 12.9 inch 3rd Gen (WiFi)"
            case "iPad8,6": return "iPad Pro 12.9 inch 3rd Gen (1TB, WiFi)"
            case "iPad8,7": return "iPad Pro 12.9 inch 3rd Gen (WiFi+Cellular)"
            case "iPad8,8": return "iPad Pro 12.9 inch 3rd Gen (1TB, WiFi+Cellular)"
            case "iPad8,9": return "iPad Pro 11 inch 4th Gen (WiFi)"
            case "iPad8,10": return "iPad Pro 11 inch 4th Gen (WiFi+Cellular)"
            case "iPad8,11": return "iPad Pro 12.9 inch 4th Gen (WiFi)"
            case "iPad8,12": return "iPad Pro 12.9 inch 4th Gen (WiFi+Cellular)"
            case "iPad11,1": return "iPad mini 5th Gen (WiFi)"
            case "iPad11,2": return "iPad mini 5th Gen"
            case "iPad11,3": return "iPad Air 3rd Gen (WiFi)"
            case "iPad11,4": return "iPad Air 3rd Gen"
            case "iPad11,6": return "iPad 8th Gen (WiFi)"
            case "iPad11,7": return "iPad 8th Gen (WiFi+Cellular)"
            case "iPad12,1": return "iPad 9th Gen (WiFi)"
            case "iPad12,2": return "iPad 9th Gen (WiFi+Cellular)"
            case "iPad14,1": return "iPad mini 6th Gen (WiFi)"
            case "iPad14,2": return "iPad mini 6th Gen (WiFi+Cellular)"
            case "iPad13,1": return "iPad Air 4th Gen (WiFi)"
            case "iPad13,2": return "iPad Air 4th Gen (WiFi+Cellular)"
            case "iPad13,4": return "iPad Pro 11 inch 5th Gen"
            case "iPad13,5": return "iPad Pro 11 inch 5th Gen"
            case "iPad13,6": return "iPad Pro 11 inch 5th Gen"
            case "iPad13,7": return "iPad Pro 11 inch 5th Gen"
            case "iPad13,8": return "iPad Pro 12.9 inch 5th Gen"
            case "iPad13,9": return "iPad Pro 12.9 inch 5th Gen"
            case "iPad13,10": return "iPad Pro 12.9 inch 5th Gen"
            case "iPad13,11": return "iPad Pro 12.9 inch 5th Gen"
            case "iPad13,16": return "iPad Air 5th Gen (WiFi)"
            case "iPad13,17": return "iPad Air 5th Gen (WiFi+Cellular)"
            case "iPad13,18": return "iPad 10th Gen"
            case "iPad13,19": return "iPad 10th Gen"
            case "iPad14,3": return "iPad Pro 11 inch 4th Gen"
            case "iPad14,4": return "iPad Pro 11 inch 4th Gen"
            case "iPad14,5": return "iPad Pro 12.9 inch 6th Gen"
            case "iPad14,6": return "iPad Pro 12.9 inch 6th Gen"
            
            // MARK: - Watch
            case "Watch1,1": return "Apple Watch 38mm case"
            case "Watch1,2": return "Apple Watch 42mm case"
            case "Watch2,6": return "Apple Watch Series 1 38mm case"
            case "Watch2,7": return "Apple Watch Series 1 42mm case"
            case "Watch2,3": return "Apple Watch Series 2 38mm case"
            case "Watch2,4": return "Apple Watch Series 2 42mm case"
            case "Watch3,1": return "Apple Watch Series 3 38mm case (GPS+Cellular)"
            case "Watch3,2": return "Apple Watch Series 3 42mm case (GPS+Cellular)"
            case "Watch3,3": return "Apple Watch Series 3 38mm case (GPS)"
            case "Watch3,4": return "Apple Watch Series 3 42mm case (GPS)"
            case "Watch4,1": return "Apple Watch Series 4 40mm case (GPS)"
            case "Watch4,2": return "Apple Watch Series 4 44mm case (GPS)"
            case "Watch4,3": return "Apple Watch Series 4 40mm case (GPS+Cellular)"
            case "Watch4,4": return "Apple Watch Series 4 44mm case (GPS+Cellular)"
            case "Watch5,1": return "Apple Watch Series 5 40mm case (GPS)"
            case "Watch5,2": return "Apple Watch Series 5 44mm case (GPS)"
            case "Watch5,3": return "Apple Watch Series 5 40mm case (GPS+Cellular)"
            case "Watch5,4": return "Apple Watch Series 5 44mm case (GPS+Cellular)"
            case "Watch5,9": return "Apple Watch SE 40mm case (GPS)"
            case "Watch5,10": return "Apple Watch SE 44mm case (GPS)"
            case "Watch5,11": return "Apple Watch SE 40mm case (GPS+Cellular)"
            case "Watch5,12": return "Apple Watch SE 44mm case (GPS+Cellular)"
            case "Watch6,1": return "Apple Watch Series 6 40mm case (GPS)"
            case "Watch6,2": return "Apple Watch Series 6 44mm case (GPS)"
            case "Watch6,3": return "Apple Watch Series 6 40mm case (GPS+Cellular)"
            case "Watch6,4": return "Apple Watch Series 6 44mm case (GPS+Cellular)"
            case "Watch6,6": return "Apple Watch Series 7 41mm case (GPS)"
            case "Watch6,7": return "Apple Watch Series 7 45mm case (GPS)"
            case "Watch6,8": return "Apple Watch Series 7 41mm case (GPS+Cellular)"
            case "Watch6,9": return "Apple Watch Series 7 45mm case (GPS+Cellular)"
            case "Watch6,10": return "Apple Watch SE 40mm case (GPS)"
            case "Watch6,11": return "Apple Watch SE 44mm case (GPS)"
            case "Watch6,12": return "Apple Watch SE 40mm case (GPS+Cellular)"
            case "Watch6,13": return "Apple Watch SE 44mm case (GPS+Cellular)"
            case "Watch6,14": return "Apple Watch Series 8 41mm case (GPS)"
            case "Watch6,15": return "Apple Watch Series 8 45mm case (GPS)"
            case "Watch6,16": return "Apple Watch Series 8 41mm case (GPS+Cellular)"
            case "Watch6,17": return "Apple Watch Series 8 45mm case (GPS+Cellular)"
            case "Watch6,18": return "Apple Watch Ultra"
            
            // MARK: - Apple TV
            case "AppleTV5,3": return "Apple TV"
            case "AppleTV6,2": return "Apple TV 4K"
            
            // MARK: - HomePod
            case "AudioAccessory1,1": return "HomePod"
            case "AudioAccessory5,1": return "HomePod mini"
            
            // MARK: - Unrecognized
            default: return identifier
        }
    }
}

使用方法:

UIDevice.modelName

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接