Как определить текущую модель iPhone/ устройства?
Есть ли способ получить название модели устройства (iPhone 4S, iPhone 5, iPhone 5S и т. Д.) В Swift?
Я знаю, что есть свойство по имени UIDevice.currentDevice().model
но он возвращает только тип устройства (iPod touch, iPhone, iPad, iPhone Simulator и т. д.).
Я также знаю, что это легко сделать в Objective-C с помощью этого метода:
#import <sys/utsname.h>
struct utsname systemInfo;
uname(&systemInfo);
NSString* deviceModel = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
Но я разрабатываю свое приложение для iPhone на Swift, так что кто-нибудь может помочь мне с аналогичным способом решить эту проблему в Swift?
38 ответов
Я сделал это "чистый Swift" расширение на UIDevice
,
Эта версия работает в Swift 2 или выше. Если вы используете более раннюю версию, пожалуйста, используйте более старую версию моего ответа.
Если вы ищете более элегантное решение, вы можете использовать мой µ-framework DeviceKit
опубликовано на GitHub (также доступно через 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 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 "iPhone11,2": return "iPhone XS"
case "iPhone11,4", "iPhone11,6": return "iPhone XS Max"
case "iPhone11,8": return "iPhone XR"
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 "AppleTV5,3": return "Apple TV"
case "AppleTV6,2": return "Apple TV 4K"
case "AudioAccessory1,1": return "HomePod"
case "i386", "x86_64": 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 9,7 дюйма", для симуляторов - "Симулятор" + идентификатор симулятора, например "Симулятор iPad Pro 9,7 дюйма".
Swift 4 оба устройства / симулятор
и новый iPhone XR, XS, XS Max
PS (Этот метод также определяет правильную модель, если используется симулятор и модель устройства симулятора..):
public enum Model : String {
case simulator = "simulator/sandbox",
//iPod
iPod1 = "iPod 1",
iPod2 = "iPod 2",
iPod3 = "iPod 3",
iPod4 = "iPod 4",
iPod5 = "iPod 5",
//iPad
iPad2 = "iPad 2",
iPad3 = "iPad 3",
iPad4 = "iPad 4",
iPadAir = "iPad Air ",
iPadAir2 = "iPad Air 2",
iPad5 = "iPad 5", //aka iPad 2017
iPad6 = "iPad 6", //aka iPad 2018
//iPad mini
iPadMini = "iPad Mini",
iPadMini2 = "iPad Mini 2",
iPadMini3 = "iPad Mini 3",
iPadMini4 = "iPad Mini 4",
//iPad pro
iPadPro9_7 = "iPad Pro 9.7\"",
iPadPro10_5 = "iPad Pro 10.5\"",
iPadPro12_9 = "iPad Pro 12.9\"",
iPadPro2_12_9 = "iPad Pro 2 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",
//Apple TV
AppleTV = "Apple TV",
AppleTV_4K = "Apple TV 4K",
unrecognized = "?unrecognized?"
}
// #-#-#-#-#-#-#-#-#-#-#-#-#-#-#
//MARK: UIDevice extensions
// #-#-#-#-#-#-#-#-#-#-#-#-#-#-#
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,
//iPod
"iPod1,1" : .iPod1,
"iPod2,1" : .iPod2,
"iPod3,1" : .iPod3,
"iPod4,1" : .iPod4,
"iPod5,1" : .iPod5,
//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,
"iPad4,1" : .iPadAir,
"iPad4,2" : .iPadAir,
"iPad4,3" : .iPadAir,
"iPad5,3" : .iPadAir2,
"iPad5,4" : .iPadAir2,
"iPad6,11" : .iPad5, //aka iPad 2017
"iPad6,12" : .iPad5,
"iPad7,5" : .iPad6, //aka iPad 2018
"iPad7,6" : .iPad6,
//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,
//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,
//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,
//AppleTV
"AppleTV5,3" : .AppleTV,
"AppleTV6,2" : .AppleTV_4K
]
if let model = modelMap[String.init(validatingUTF8: modelCode!)!] {
if model == .simulator {
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
if let simModel = modelMap[String.init(validatingUTF8: simModelCode)!] {
return simModel
}
}
}
return model
}
return Model.unrecognized
}
}
Использование: вы получаете свою модель просто с:
let deviceType = UIDevice().type
или выведите точную строку с помощью:
print("\(UIDevice().type.rawvalue)")
Выход:
iPhone X
Другой пример:
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
}
Для моделей устройств Apple посетите: https://www.theiphonewiki.com/wiki/Models
Этот пример Swift 3.0 возвращает текущую модель устройства в виде enum
константа (чтобы избежать прямого сравнения со строковыми литералами). Необработанное значение перечисления является String
содержит удобочитаемое имя устройства iOS. Поскольку это 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");
}
Ваше приложение должно постоянно обновляться для новых выпусков устройств, а также, когда Apple добавляет новые модели для того же семейства устройств. Например, iPhone3,1 iPhone3,2 iPhone3,4 - это все "iPhone 4". Избегайте написания кода, который не учитывает новые модели, чтобы ваши алгоритмы не могли неожиданно не настроить и не отреагировать на новое устройство. Вы можете обратиться к этому поддерживаемому списку iOS Device Model #, чтобы обновить свое приложение в стратегическое время.
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",
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
]
if let model = modelMap[String.init(validatingUTF8: modelCode!)!] {
return model
}
return Model.unrecognized
}
}
Еще одна / простая альтернатива (ссылка на идентификатор модели находится по адресу https://www.theiphonewiki.com/wiki/Models):
Обновленный ответ для Swift 3/4, включая обрезку строк и поддержку симулятора:
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
}
Я сделал еще один пример расширения для UIDevice, включив в него идентификатор идентификатора модели симулятора на основе ответа @HAS:
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 "iPhone11,2": return "iPhone XS"
case "iPhone11,4", "iPhone11,6": return "iPhone XS Max"
case "iPhone11,8": return "iPhone XR"
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 "AppleTV5,3": return "Apple TV"
case "AppleTV6,2": return "Apple TV 4K"
case "AudioAccessory1,1": return "HomePod"
default: return identifier
}
}
}
Версия Swift 4.x:
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 "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 "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 "AppleTV5,3": return "Apple TV"
case "AppleTV6,2": return "Apple TV 4K"
case "AudioAccessory1,1": return "HomePod"
default: return identifier
}
}
}
Работает нормально с Swift3.2 и выше:
let modelName = UIDevice.current.modelName
var platform: String? {
var systemInfo = utsname()
uname(&systemInfo)
return withUnsafeMutablePointer(&systemInfo.machine) { ptr in String.fromCString(UnsafePointer<CChar>(ptr)) }
}
Использование 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. то есть: смежный и не дополненный.
Для обоих устройств, а также для симуляторов, создайте новый файл swift с именем UIDevice.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
}
}
}
Тогда в вашем viewcontroller,
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")
}
Вот решение, обновленное на январь 2023 года. Оно включает самые последние модели 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"
// 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
Работа с c структурами болезненна быстро. Особенно, если в них есть какие-то массивы c. Вот мое решение: продолжать использовать цель-с. Просто создайте класс-объект-оболочку, который выполняет эту работу, а затем используйте этот класс в Swift. Вот пример класса, который делает именно это:
@interface DeviceInfo : NSObject
+ (NSString *)model;
@end
#import "DeviceInfo.h"
#import <sys/utsname.h>
@implementation DeviceInfo
+ (NSString *)model
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString: systemInfo.machine encoding: NSUTF8StringEncoding];
}
@end
В быстрой стороне:
let deviceModel = DeviceInfo.model()
В Swift 3.0 я разобрался с этим решением, чтобы получить модальное имя устройства.
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")
}
Я обнаружил, что во многих ответах используются строки. Я решил изменить ответ @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
}
}
}
WikiDevice
асинхронная библиотека, которая дает вам ответ от theiphonewiki
Небольшой безумный эксперимент для таких фанатов автоматизации, как я. Я создал этот алгоритм, который считывает идентификационный код устройства, физического или смоделированного, и загружает страницу theiphonewiki, чтобы экстраполировать название модели на основе идентификационного кода (например, iPhone11,2 -> iPhone XS). Алгоритм взаимодействует со страницей WIKI с помощью внутреннего инструмента песочницы Wiki API, который позволяет вам получить ответ JSON, однако содержимое не может быть получено в JSON (только та часть, которая была необходима, то есть wikitables), поэтому я проанализировал содержимое HTML. чтобы добраться до имени устройства, не используя сторонние библиотеки синтаксического анализа HTML.
ПЛЮСЫ : всегда в курсе, не нужно добавлять новые устройства
МИНУСЫ : асинхронный ответ с помощью вики - страницу из Интернета
PS Не стесняйтесь улучшать мой код, чтобы получить еще более точный результат и более элегантный синтаксис. PSS. Если вам нужен более быстрый ответ, используйте мой предыдущий ответ здесь, на этой странице
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:
Если вам нужно протестировать эту библиотеку, вы можете скачать тестовый проект отсюда.
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 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
}
}
}
There is a helper library for this.
Swift 5
pod 'DeviceKit', '~> 2.0'
Swift 4.0 - Swift 4.2
pod 'DeviceKit', '~> 1.3'
if you just want to determine the model and make something accordingly.
You can use like that:
let isIphoneX = Device().isOneOf([.iPhoneX, .simulator(.iPhoneX)])
In a function:
func isItIPhoneX() -> Bool {
let device = Device()
let check = device.isOneOf([.iPhoneX, .iPhoneXr , .iPhoneXs , .iPhoneXsMax ,
.simulator(.iPhoneX), .simulator(.iPhoneXr) , .simulator(.iPhoneXs) , .simulator(.iPhoneXsMax) ])
return check
}
Вот модификация без принудительной развёртки и 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
}
}
Вы можете использовать платформу BDLocalizedDevicesModels для анализа информации об устройстве и получения имени.
Тогда просто позвоните UIDevice.currentDevice.productName
в вашем коде.
Недавно я работал над разработкой этого быстрого пакета:
https://github.com/EmilioOjeda/Устройство
Я думаю, что главное его преимущество в том, что он генерируется кодом. Поэтому всякий раз, когда выпускается новая версия 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
Если вы не хотите обновлять свой код каждый раз, когда 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!)!
}
Мое простое решение сгруппировано по устройствам и поддерживает новые устройства 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:
}
Используя 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
}
Ниже приведен код для получения аппаратной строки, но вам нужно сравнить эту аппаратную строку, чтобы узнать, какое это устройство. Я создал класс, в котором содержатся практически все строки устройств (мы постоянно обновляем строку для новых устройств). Это легко использовать, пожалуйста, проверьте
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
}
Самый простой способ получить название модели (маркетинговое название)
Использовать частный API -[UIDevice _deviceInfoForKey:]
осторожно, Apple не откажет вам,
// works on both simulators and real devices, iOS 8 to iOS 12
NSString *deviceModelName(void) {
// For Simulator
NSString *modelName = NSProcessInfo.processInfo.environment[@"SIMULATOR_DEVICE_NAME"];
if (modelName.length > 0) {
return modelName;
}
// For real devices and simulators, except simulators running on iOS 8.x
UIDevice *device = [UIDevice currentDevice];
NSString *selName = [NSString stringWithFormat:@"_%@ForKey:", @"deviceInfo"];
SEL selector = NSSelectorFromString(selName);
if ([device respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
modelName = [device performSelector:selector withObject:@"marketing-name"];
#pragma clang diagnostic pop
}
return modelName;
}
Как я получил ключевое "маркетинговое имя"?
Бег на тренажере, NSProcessInfo.processInfo.environment
содержит ключ с именем "SIMULATOR_CAPABILITIES", значением которого является файл plist. Затем вы открываете файл plist, вы получаете ключ названия модели "marketing-name".
Простой способ получить имя устройства с одной строкой кода
let name = ProcessInfo.init().environment["SIMULATOR_DEVICE_NAME"] ?? "NoN"
print("My device name is: ", name)
Результат для симулятора iPhone X -> Имя моего устройства: iPhone X
Результат на детской площадке Xcode 9.3.1 -> Имя моего устройства: iPad Pro (9,7 дюйма)
Работает для меня
var sysinfo = utsname()
uname(&sysinfo)
let data = Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN))
let model = String(cString: [UInt8](data) //iPhone13,1
На основании этого ответа и этого ответа. Я создал публичную суть
Как это можно использовать
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://stackru.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://stackru.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
}
}
}
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"