提问人:The Mach System 提问时间:9/25/2014 最后编辑:General GrievanceThe Mach System 更新时间:9/27/2023 访问量:400496
如何确定当前的iPhone/设备型号?
How to determine the current iPhone/device model?
问:
有没有办法在 Swift 中获取设备型号名称(iPhone 4S、iPhone 5、iPhone 5S 等)?
我知道有一个属性命名,但它只返回设备类型(iPod touch、iPhone、iPad、iPhone 模拟器等)。UIDevice.currentDevice().model
我也知道使用这种方法可以在 Objective-C 中轻松完成:
#import <sys/utsname.h>
struct utsname systemInfo;
uname(&systemInfo);
NSString* deviceModel = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
但是我正在用 Swift 开发我的 iPhone 应用程序,所以有人可以帮我用 Swift 中的等效方法解决这个问题吗?
答:
在 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()
评论
x86_64
utsname
machine
x86_64
.machine
.nodename
My-iMac.local
我在 UIDevice
上做了这个“纯 Swift”扩展。
如果你正在寻找一个更优雅的解决方案,你可以使用我在 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 "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 英寸)(第 5 代)”,对于模拟器,它返回例如“模拟器 iPad Pro(12.9 英寸)(第 5 代)”
下面是模型参考:
评论
swiftlint:disable:this
此 Swift 3.0 示例将当前设备模型作为常量返回(以避免与字符串文字直接比较)。枚举的原始值是包含人类可读的 iOS 设备名称。由于它是 Swift,因此识别的设备列表仅包括足够近的型号,以支持包含 Swift 的 iOS 版本。以下用法示例利用了本答案末尾的实现:enum
String
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");
}
你的 App 应针对新设备版本以及 Apple 为同一设备系列添加新型号时保持最新状态。例如,iPhone3,1 iPhone3,2 iPhone3,4都是“iPhone 4”。避免编写不考虑新模型的代码,这样您的算法就不会意外地无法配置或响应新设备。您可以参考此维护的 iOS 设备型号 # 列表,以在关键时刻更新您的应用程序。
iOS 包含独立于设备的界面,用于检测硬件功能和参数,例如屏幕尺寸。Apple 提供的通用接口通常是最安全、最受支持的机制,可以动态地使应用的行为适应不同的硬件。不过,以下代码可用于原型设计、调试、测试或任何需要针对特定设备系列的代码。此技术还可用于通过其通用/公开识别的名称来描述当前设备。
斯威夫特 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
}
}
评论
modelMap
Duplicate literals in keys
if let model = modelMap[String.fromCString(modelCode!)!]
modelMap
if let model = modelMap[String.init(validatingUTF8: deviceModelCode()!)!] { return model }
另一个/简单的替代方案(模型标识符参考见 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"
}
评论
下面是获取硬件字符串的代码,但您需要比较这些硬件字符串才能知道它是哪个设备。我为它创建了一个包含几乎所有设备字符串的类(我们正在使字符串与新设备保持同步)。它易于使用,请检查
斯威夫特:GitHub/DeviceGuru
Objective-C:GitHub/DeviceUtil
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
评论
如果您不想在每次 Apple 向设备系列添加新型号时都不断更新代码,请使用以下方法仅返回型号代码。
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答案以使用枚举:
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];
评论
这里有一个没有强制解包和 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 数组相同。即:连续且无填充。
评论
withUnsafePointer
return String(cString: &sysinfo.machine.0)
deviceName()
return String(cString: &sysinfo.machine.0)
SWIFT 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 和 C/Swift 的所有复杂性都更清晰一些。 ):
返回诸如“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
}
}
}
评论
Swift 5.x,设备和模拟器都带有ENUMS(以检查您喜欢的任何组或模型)
- 更新至2023年9月 -
(始终检查和更新!
最后:iPad 第 10 代、iPhone 15 所有版本、iPhone SE 第 3 代 2022、iPad Air 第 5 代、iPhone 13(所有型号)、iPad 第 9 代 2021、iPad mini 第 6 代 2021、Apple Watch Series 7、iPad Pro(11 英寸)(第 3 代)、iPad Pro(12.9 英寸)(第 5 代)和 Apple TV 4K(第 2 代) , (所有 iPod 也更新, Apple Watch 和 Apple TV)
此方法检测正确的模型,即使它是模拟器。(模拟器中运行的模拟器设备模型的确切名称)
有了这个答案,借助枚举,您可以在几行中检查多个设备
例:
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
}
对于 Apple 设备型号,请访问: https://www.theiphonewiki.com/wiki/Models
附言:我在这里做了一个小的异步实验(与THEIPHONEWIKI网站直接连接,源代码中没有长长的静态设备列表。
评论
UIDevice().type.rawvalue
iPhone12,8
'init(validatingUTF8:)' is deprecated: Use a copy of the String argument
我在 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
}
}
}
我的简单解决方案按设备分组,并支持新设备,并在:iPhone 8
iPhone X
Swift 3
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:]
// 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;
}
我是如何获得密钥“营销名称”的?
在模拟器上运行,包含一个名为“SIMULATOR_CAPABILITIES”的键,其值是一个 plist 文件。然后你打开 plist 文件,你会得到模型名称的键“marketing-name”。NSProcessInfo.processInfo.environment
评论
有一个帮助程序库。
斯威夫特 5
pod 'DeviceKit', '~> 2.0'
斯威夫特 4.0 - 斯威夫特 4.2
pod '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)
维基设备
从iPhoneWiki中为您提供答案的异步库
对于像我这样的自动化爱好者来说,这是一个疯狂的小实验。我制作了这个算法,读取设备的识别码,物理的或模拟的,并加载 iphonewiki 页面以根据识别码推断型号名称(例如 iPhone11,2 -> iPhone XS)。该算法使用内部 Wiki API 沙盒工具与 WIKI 页面交互,该工具允许您获得 JSON 响应,但是内容无法在 JSON 中获取(只是需要的部分,即 wikitables),因此我解析了 HTML 内容以获取设备名称,而无需使用第三方 HTML 解析库。
优点: 始终更新,无需添加新设备
缺点: 使用网络上的 wiki 页面进行异步回答
P.S. 随意改进我的代码以获得更精确的结果和更优雅的语法 P.S.S. 如果您需要更直接的答案,请使用我之前在此页面中的答案
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:
如果你需要测试这个库,你可以从这里下载测试项目
评论
这是一个用于检测苹果设备的新库
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))
"""
对我有用
var sysinfo = utsname()
uname(&sysinfo)
let data = Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN))
let model = String(cString: [UInt8](data) //iPhone13,1
我最近致力于开发这个 swift 包:
https://github.com/EmilioOjeda/Device
我认为,它的主要优点是它是代码生成的。因此,每当发布新的 Xcode 版本时,我所要做的就是运行脚本并更新 swift 包。
代码生成是如何工作的?
它从 Xcode 的数据库(每个平台)读取和解析设备数据,以识别正在运行的设备,并为其提供信息。
它的用法......
import Device
// or => 'import iPhoneOSDevice' <= iPhoneOS-only device data
// or => 'import tvOSDevice' <= tvOS-only device data
// A representation of the running device - it could be either actual or simulated.
let device = Device.current
// It is 'true' when running on a physical device.
_ = device.isDevice
// It is 'true' when running on a simulator instance.
_ = device.isSimulator
// It is 'true' when the device does not match either simulators or physical devices.
_ = device.isUnknown
// The identifier for the device.
// i.e.: 'iPhone15,3'
let id = device.id
// The known/commercial name of the device.
// i.e.: 'iPhone 14 Pro Max'
let model = device.model
以下是 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
评论