如何确定当前的iPhone /设备型号?
有什么办法可以在Swift中获取设备型号名称(iPhone 4S,iPhone 5,iPhone 5S等)?
我知道有一个名为UIDevice.currentDevice().model
的属性,但它只返回设备types(iPod touch,iPhone,iPad,iPhone模拟器等)。
我也知道这个方法可以在Objective-C中轻松完成:
#import <sys/utsname.h> struct utsname systemInfo; uname(&systemInfo); NSString* deviceModel = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
但是我正在Swift开发我的iPhone应用程序,所以有人可以帮助我用Swift解决这个问题。
我在UIDevice
上做了这个“纯Swift”扩展。
这个版本需要Swift 2.0如果你使用早期版本,请使用我的答案的旧版本 。
如果您正在寻找更优雅的解决scheme,您可以使用我在GitHub上发布的μ-framework DeviceKit
(也可以通过CocoaPods获得) 。
代码如下:
import UIKit 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 "iPod5,1": return "iPod Touch 5" case "iPod7,1": return "iPod Touch 6" case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4" case "iPhone4,1": return "iPhone 4s" case "iPhone5,1", "iPhone5,2": return "iPhone 5" case "iPhone5,3", "iPhone5,4": return "iPhone 5c" case "iPhone6,1", "iPhone6,2": return "iPhone 5s" case "iPhone7,2": return "iPhone 6" case "iPhone7,1": return "iPhone 6 Plus" case "iPhone8,1": return "iPhone 6s" case "iPhone8,2": return "iPhone 6s Plus" case "iPhone9,1", "iPhone9,3": return "iPhone 7" case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus" case "iPhone8,4": return "iPhone SE" case "iPhone10,1", "iPhone10,4": return "iPhone 8" case "iPhone10,2", "iPhone10,5": return "iPhone 8 Plus" case "iPhone10,3", "iPhone10,6": return "iPhone X" case "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 "AppleTV6,2": return "Apple TV 4K" case "AudioAccessory1,1": return "HomePod" case "i386", "x86_64": return "Simulator" default: return identifier } } }
你这样称呼它:
// Swift 2 let modelName = UIDevice.currentDevice().modelName // Swift 3 let modelName = UIDevice.current.modelName
这个Swift 3.0示例返回当前的设备模型作为一个enum
常量(以避免直接比较string文字)。 枚举的原始值是一个包含可读的iOS设备名称的string。 由于是Swift,所以已识别设备的列表中只包含了足够支持iOS版本(包括Swift)的模型。 以下使用示例在此答案的末尾使用了实现:
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”。 避免编写不考虑新模型的代码,因此您的algorithm不会意外地无法configuration或响应新设备。 您可以参考这个维护的iOS设备模型列表,在战略时间更新您的应用程序。
iOS包含与设备无关的接口,用于检测硬件function和参数(如屏幕尺寸)。 Apple提供的通用接口通常是dynamic调整应用程序行为以适应不同硬件的最安全,最好的支持机制。 不过,以下代码对于原型devise,debugging,testing或任何时间代码需要针对特定设备系列都是有用的。 这种技术也可以用其公共/公认的名称来描述当前设备。
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", 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 ] if let model = modelMap[String.init(validatingUTF8: modelCode!)!] { return model } return Model.unrecognized } }
又一个/简单的select:
更新Swift 3/4的答案,包括string修整和模拟器支持:
func modelIdentifier() -> String { if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] { return simulatorModelIdentifier } var sysinfo = utsname() uname(&sysinfo) // ignore return value return String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters) }
Swift 2的原始答案:
func modelIdentifier() -> String { var sysinfo = utsname() uname(&sysinfo) // ignore return value return NSString(bytes: &sysinfo.machine, length: Int(_SYS_NAMELEN), encoding: NSASCIIStringEncoding)! as String }
对于设备以及模拟器,创build一个名为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") }
处理结构是很痛苦的。 特别是如果他们有某种c数组。 这是我的解决scheme:继续使用Objective-C。 只要创build一个包装目标的类,做这个工作,然后在swift中使用该类。 这里是一个示例类,完全是这样的:
@interface DeviceInfo : NSObject + (NSString *)model; @end #import "DeviceInfo.h" #import <sys/utsname.h> @implementation DeviceInfo + (NSString *)model { struct utsname systemInfo; uname(&systemInfo); return [NSString stringWithCString: systemInfo.machine encoding: NSUTF8StringEncoding]; } @end
在快捷方面:
let deviceModel = DeviceInfo.model()
在Swift 3.0中,我已经想出了这个解决scheme来获取设备模态名称。
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 "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" case "i386", "x86_64": return "Simulator" default: return identifier } }
}
使用这个扩展你需要写这个来获取设备模态名称在swift 3.0。
//Getting Device modal name let modelName = UIDevice.current.modelName print(modelName)
愿这能帮助你。 谢谢。
我已经实现了一个超轻量级库来检测使用的设备基于一些给定的答案: 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") }
我发现很多这些答案都使用string。 我决定改变@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 } } }
当您使用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 } } }
var platform: String? { var systemInfo = utsname() uname(&systemInfo) return withUnsafeMutablePointer(&systemInfo.machine) { ptr in String.fromCString(UnsafePointer<CChar>(ptr)) } }
Swift 4和新的iPhone 8和iPhone X:
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", 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", 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, "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" : .iPhone8, "iPhone10,4" : .iPhone8plus, "iPhone10,5" : .iPhoneX, "iPhone10,6" : .iPhoneX ] if let model = modelMap[String.init(validatingUTF8: modelCode!)!] { return model } return Model.unrecognized } }
用法 :
print("\(UIDevice().type)")
输出:
iPhone X
在Swift 3中会是这样的
UIDevice.current.model
这里没有强制解压和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元组的内存alignment方式与Int8大数组相同。 即:连续和不填充。
下面是获取硬件string的代码,但是您需要比较这些硬件string以知道它是哪个设备。 我已经创build了一个包含几乎所有设备string的类(我们正在使用新设备保持string最新)。 这很容易使用,请检查
Swift : 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 }
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的所有错综复杂的东西还是比较清楚的。 ):
返回值如“x86_64”
If you do not want to keep updating your code everytime Apple adds a new model to a device family, use the method below returning you the model code only.
func platform() -> String { var systemInfo = utsname() uname(&systemInfo) let modelCode = withUnsafeMutablePointer(&systemInfo.machine) { ptr in String.fromCString(UnsafePointer<CChar>(ptr)) } return String.fromCString(modelCode!)! }
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 or higher
import UIKit class ViewController: UIViewController { let device = UIDevice.current override func viewDidLoad() { super.viewDidLoad() let model = device.model print(model) // eg "iPhone" let modelName = device.modelName print(modelName) // eg "iPhone 6" /* see the extension */ let deviceName = device.name print(deviceName) // eg "My iPhone" let systemName = device.systemName print(systemName) // eg "iOS" let systemVersion = device.systemVersion print(systemVersion) // eg "10.3.2" if let identifierForVendor = device.identifierForVendor { print(identifierForVendor) // eg "E1X2XX34-5X6X-7890-123X-XXX456C78901" } } }
and add the following extension
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 } } }
Using a Swift 'switch-case':
func platformString() -> String { var devSpec: String switch platform() { case "iPhone1,2": devSpec = "iPhone 3G" case "iPhone2,1": devSpec = "iPhone 3GS" case "iPhone3,1": devSpec = "iPhone 4" case "iPhone3,3": devSpec = "Verizon iPhone 4" case "iPhone4,1": devSpec = "iPhone 4S" case "iPhone5,1": devSpec = "iPhone 5 (GSM)" case "iPhone5,2": devSpec = "iPhone 5 (GSM+CDMA)" case "iPhone5,3": devSpec = "iPhone 5c (GSM)" case "iPhone5,4": devSpec = "iPhone 5c (GSM+CDMA)" case "iPhone6,1": devSpec = "iPhone 5s (GSM)" case "iPhone6,2": devSpec = "iPhone 5s (GSM+CDMA)" case "iPhone7,1": devSpec = "iPhone 6 Plus" case "iPhone7,2": devSpec = "iPhone 6" case "iPod1,1": devSpec = "iPod Touch 1G" case "iPod2,1": devSpec = "iPod Touch 2G" case "iPod3,1": devSpec = "iPod Touch 3G" case "iPod4,1": devSpec = "iPod Touch 4G" case "iPod5,1": devSpec = "iPod Touch 5G" case "iPad1,1": devSpec = "iPad" case "iPad2,1": devSpec = "iPad 2 (WiFi)" case "iPad2,2": devSpec = "iPad 2 (GSM)" case "iPad2,3": devSpec = "iPad 2 (CDMA)" case "iPad2,4": devSpec = "iPad 2 (WiFi)" case "iPad2,5": devSpec = "iPad Mini (WiFi)" case "iPad2,6": devSpec = "iPad Mini (GSM)" case "iPad2,7": devSpec = "iPad Mini (GSM+CDMA)" case "iPad3,1": devSpec = "iPad 3 (WiFi)" case "iPad3,2": devSpec = "iPad 3 (GSM+CDMA)" case "iPad3,3": devSpec = "iPad 3 (GSM)" case "iPad3,4": devSpec = "iPad 4 (WiFi)" case "iPad3,5": devSpec = "iPad 4 (GSM)" case "iPad3,6": devSpec = "iPad 4 (GSM+CDMA)" case "iPad4,1": devSpec = "iPad Air (WiFi)" case "iPad4,2": devSpec = "iPad Air (Cellular)" case "iPad4,4": devSpec = "iPad mini 2G (WiFi)" case "iPad4,5": devSpec = "iPad mini 2G (Cellular)" case "iPad4,7": devSpec = "iPad mini 3 (WiFi)" case "iPad4,8": devSpec = "iPad mini 3 (Cellular)" case "iPad4,9": devSpec = "iPad mini 3 (China Model)" case "iPad5,3": devSpec = "iPad Air 2 (WiFi)" case "iPad5,4": devSpec = "iPad Air 2 (Cellular)" case "i386": devSpec = "Simulator" case "x86_64": devSpec = "Simulator" default: devSpec = "Unknown" } return devSpec }
struct utsname systemInfo; uname(&systemInfo); NSString* deviceModel = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
I've made another sample extension on UIDevice to include simulator model identifier base on @HAS's answer :
public extension UIDevice { /// pares the deveice name as the standard name var modelName: String { #if (arch(i386) || arch(x86_64)) && os(iOS) let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"]! #else var systemInfo = utsname() uname(&systemInfo) let machineMirror = Mirror(reflecting: systemInfo.machine) let identifier = machineMirror.children.reduce("") { identifier, element in guard let value = element.value as? Int8 , value != 0 else { return identifier } return identifier + String(UnicodeScalar(UInt8(value))) } #endif switch identifier { case "iPod5,1": return "iPod Touch 5" case "iPod7,1": return "iPod Touch 6" case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4" case "iPhone4,1": return "iPhone 4s" case "iPhone5,1", "iPhone5,2": return "iPhone 5" case "iPhone5,3", "iPhone5,4": return "iPhone 5c" case "iPhone6,1", "iPhone6,2": return "iPhone 5s" case "iPhone7,2": return "iPhone 6" case "iPhone7,1": return "iPhone 6 Plus" case "iPhone8,1": return "iPhone 6s" case "iPhone8,2": return "iPhone 6s Plus" case "iPhone9,1", "iPhone9,3": return "iPhone 7" case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus" case "iPhone8,4": return "iPhone SE" case "iPhone10,1", "iPhone10,4": return "iPhone 8" case "iPhone10,2", "iPhone10,5": return "iPhone 8 Plus" case "iPhone10,3", "iPhone10,6": return "iPhone X" case "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 "AppleTV6,2": return "Apple TV 4K" case "AudioAccessory1,1": return "HomePod" default: return identifier } } }
It's working fine with Swift3.2:
let modelName = UIDevice.current.modelName
My simple solution grouped by device and support new devices iPhone 8
and iPhone X
in 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 } } }
And use:
switch UIDevice.current.modelName { case "iPhone 4": case "iPhone 5": case "iPhone 6,7,8": case "iPhone Plus": case "iPhone X": case "Simulator": default: }
if(UIScreen.mainScreen().bounds.size.height == 1366 || UIScreen.mainScreen().bounds.size.width == 1366){ print("iPad Pro") } else{ print("ipad") }