How to determine the current iPhone/device model?
Is there a way to get the device model name (iPhone 4S, iPhone 5, iPhone 5S, etc) in Swift?
I know there is a property named UIDevice.currentDevice().model
but it only returns device type (iPod touch, iPhone, iPad, iPhone Simulator, etc).
I also know it can be done easily in Objective-C with this method:
#import <sys/utsname.h>
struct utsname systemInfo;
uname(&systemInfo);
NSString* deviceModel = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
But I'm developing my iPhone app in Swift so could someone please help me with the equivalent way to solve this in Swift?
I made this "pure Swift" extension on UIDevice
.
This version works in Swift 2 or higher If you use an earlier version please use an older version of my answer.
If you are looking for a more elegant solution you can use my µ-framework DeviceKit
published on GitHub (also available via CocoaPods, Carthage and Swift Package Manager).
Here's the code:
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 "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 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
}
}
}
You call it like this:
// Swift 2
let modelName = UIDevice.currentDevice().modelName
// Swift 3
let modelName = UIDevice.current.modelName
This Swift 3.0 example returns the current device model as an enum
constant (to avoid direct comparisons to string literals). The enum's raw value is a String
containing the human-readable iOS device name. Since it is Swift, the list of recognized devices only includes models recent enough to support iOS releases that include Swift. The following usage example utilizes the implementation at the end of this answer:
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");
}
Your app should be kept up-to-date for new device releases and also when Apple adds new models for the same device family. For example, iPhone3,1 iPhone3,2 iPhone3,4 are all "iPhone 4". Avoid writing code that doesn't account for new models, so your algorithms don't unexpectedly fail to configure or respond to a new device. You can refer to this maintained list of iOS Device Model #'s to update your app at strategic times.
iOS includes device-independent interfaces to detect hardware capabilities and parameters such as screen size. The generalized interfaces Apple provides are usually the safest, best supported mechanisms to dynamically adapt an app's behavior to different hardware. Nevertheless, the following code can be useful for prototyping, debugging, testing, or any time code needs to target a specific device family. This technique can also be useful to describe the current device by its common/publicly recognized name.
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,
"iPhone10,6" : .iPhoneX
]
if let model = modelMap[String.init(validatingUTF8: modelCode!)!] {
return model
}
return Model.unrecognized
}
}
Yet another/simple alternative (model identifier reference found at https://www.theiphonewiki.com/wiki/Models):
Updated answer for Swift 3/4 including string trimming and simulator support:
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)
}
Original answer for 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
}
链接地址: http://www.djcxy.com/p/35126.html
上一篇: 如何将百分号添加到NSString
下一篇: 如何确定当前的iPhone /设备型号?