Как определить текущую модель 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 это было бы

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

Вы можете использовать платформу 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"

Другие вопросы по тегам