有没有办法在Swift中获得设备型号名称(iPhone 4S, iPhone 5, iPhone 5S等)?

我知道有一个名为UIDevice.currentDevice()的属性。模型,但它只返回设备类型(iPod touch, iPhone, iPad, iPhone模拟器等)。

我也知道在Objective-C中使用以下方法可以轻松完成:

#import <sys/utsname.h>

struct utsname systemInfo;
uname(&systemInfo);

NSString* deviceModel = [NSString stringWithCString:systemInfo.machine
                          encoding:NSUTF8StringEncoding];

但是我正在Swift中开发我的iPhone应用程序,所以有人可以帮助我用等效的方法在Swift中解决这个问题吗?


当前回答

struct DeviceType {
        static let IS_IPHONE_4_OR_LESS = UIDevice.current.userInterfaceIdiom == .phone && Constants.SCREEN_MAX_LENGTH < 568
        static let IS_IPHONE_5 = UIDevice.current.userInterfaceIdiom == .phone && Constants.SCREEN_MAX_LENGTH == 568
        static let IS_IPHONE_6 = UIDevice.current.userInterfaceIdiom == .phone && Constants.SCREEN_MAX_LENGTH == 667
        static let IS_IPHONE_6P = UIDevice.current.userInterfaceIdiom == .phone && Constants.SCREEN_MAX_LENGTH == 736
        static let IS_IPAD = UIDevice.current.userInterfaceIdiom == .pad && Constants.SCREEN_MAX_LENGTH == 1024
    }

其他回答

如果你不想每次苹果向设备家族添加新型号时都更新你的代码,可以使用下面的方法只返回型号代码。

func platform() -> String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let modelCode = withUnsafeMutablePointer(&systemInfo.machine) {
            ptr in String.fromCString(UnsafePointer<CChar>(ptr))
        }

        return String.fromCString(modelCode!)!
}

对我有用

var sysinfo = utsname()
uname(&sysinfo)
let data = Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN))
let model = String(cString: [UInt8](data) //iPhone13,1

这个Swift 3.0示例将当前设备模型作为枚举常量返回(以避免与字符串字面值直接比较)。enum的原始值是一个包含人类可读的iOS设备名称的字符串。因为它是Swift,所以认可的设备列表只包括最新的机型,足以支持包含Swift的iOS版本。下面的使用示例利用了这个答案末尾的实现:

    switch UIDevice().type {
    case .iPhone5:
              print("No TouchID sensor")
    case .iPhone5S:
              fallthrough
    case .iPhone6:
              fallthrough
    case .iPhone6plus:
              fallthrough
    case .iPad_Pro9_7:
              fallthrough
    case .iPad_Pro12_9:
              fallthrough
    case .iPhone7:
              fallthrough
    case .iPhone7plus:
              print("Put your thumb on the " + 
                     UIDevice().type.rawValue + " TouchID sensor")
    case .unrecognized:
              print("Device model unrecognized");
    default:
              print(UIDevice().type.rawValue + " not supported by this app");
    }

你的应用应该保持最新的新设备发布,以及当苹果为同一设备家族添加新型号时。例如,iPhone3、1 iPhone3、2 iPhone3、4都是“iPhone 4”。避免编写不考虑新型号的代码,这样你的算法就不会意外地配置失败或对新设备做出响应。你可以参考这个维护列表的iOS设备型号#更新你的应用程序在战略时刻。

iOS includes device-independent interfaces to detect hardware capabilities and parameters such as screen size. The generalized interfaces Apple provides are usually the safest, best supported mechanisms to dynamically adapt an app's behavior to different hardware. Nevertheless, the following code can be useful for prototyping, debugging, testing, or any time code needs to target a specific device family. This technique can also be useful to describe the current device by its common/publicly recognized name.

斯威夫特3

// 1. Declare outside class definition (or in its own file).
// 2. UIKit must be included in file where this code is added.
// 3. Extends UIDevice class, thus is available anywhere in app.
//
// Usage example:
//
//    if UIDevice().type == .simulator {
//       print("You're running on the simulator... boring!")
//    } else {
//       print("Wow! Running on a \(UIDevice().type.rawValue)")
//    }
import UIKit

public enum Model : String {
    case simulator   = "simulator/sandbox",
    iPod1            = "iPod 1",
    iPod2            = "iPod 2",
    iPod3            = "iPod 3",
    iPod4            = "iPod 4",
    iPod5            = "iPod 5",
    iPad2            = "iPad 2",
    iPad3            = "iPad 3",
    iPad4            = "iPad 4",
    iPhone4          = "iPhone 4",
    iPhone4S         = "iPhone 4S",
    iPhone5          = "iPhone 5",
    iPhone5S         = "iPhone 5S",
    iPhone5C         = "iPhone 5C",
    iPadMini1        = "iPad Mini 1",
    iPadMini2        = "iPad Mini 2",
    iPadMini3        = "iPad Mini 3",
    iPadAir1         = "iPad Air 1",
    iPadAir2         = "iPad Air 2",
    iPadPro9_7       = "iPad Pro 9.7\"",
    iPadPro9_7_cell  = "iPad Pro 9.7\" cellular",
    iPadPro10_5      = "iPad Pro 10.5\"",
    iPadPro10_5_cell = "iPad Pro 10.5\" cellular",
    iPadPro12_9      = "iPad Pro 12.9\"",
    iPadPro12_9_cell = "iPad Pro 12.9\" cellular",
    iPhone6          = "iPhone 6",
    iPhone6plus      = "iPhone 6 Plus",
    iPhone6S         = "iPhone 6S",
    iPhone6Splus     = "iPhone 6S Plus",
    iPhoneSE         = "iPhone SE",
    iPhone7          = "iPhone 7",
    iPhone7plus      = "iPhone 7 Plus",
    iPhone8          = "iPhone 8",
    iPhone8plus      = "iPhone 8 Plus",
    iPhoneX          = "iPhone X",
    iPhoneXS         = "iPhone XS",
    iPhoneXSmax      = "iPhone XS Max",
    iPhoneXR         = "iPhone XR",
    iPhone11         = "iPhone 11",
    iPhone11Pro      = "iPhone 11 Pro",
    iPhone11ProMax   = "iPhone 11 Pro Max",
    unrecognized     = "?unrecognized?"
}

public extension UIDevice {
    public var type: Model {
        var systemInfo = utsname()
        uname(&systemInfo)
        let modelCode = withUnsafePointer(to: &systemInfo.machine) {
            $0.withMemoryRebound(to: CChar.self, capacity: 1) {
                ptr in String.init(validatingUTF8: ptr)

            }
        }
        var modelMap : [ String : Model ] = [
            "i386"       : .simulator,
            "x86_64"     : .simulator,
            "iPod1,1"    : .iPod1,
            "iPod2,1"    : .iPod2,
            "iPod3,1"    : .iPod3,
            "iPod4,1"    : .iPod4,
            "iPod5,1"    : .iPod5,
            "iPad2,1"    : .iPad2,
            "iPad2,2"    : .iPad2,
            "iPad2,3"    : .iPad2,
            "iPad2,4"    : .iPad2,
            "iPad2,5"    : .iPadMini1,
            "iPad2,6"    : .iPadMini1,
            "iPad2,7"    : .iPadMini1,
            "iPhone3,1"  : .iPhone4,
            "iPhone3,2"  : .iPhone4,
            "iPhone3,3"  : .iPhone4,
            "iPhone4,1"  : .iPhone4S,
            "iPhone5,1"  : .iPhone5,
            "iPhone5,2"  : .iPhone5,
            "iPhone5,3"  : .iPhone5C,
            "iPhone5,4"  : .iPhone5C,
            "iPad3,1"    : .iPad3,
            "iPad3,2"    : .iPad3,
            "iPad3,3"    : .iPad3,
            "iPad3,4"    : .iPad4,
            "iPad3,5"    : .iPad4,
            "iPad3,6"    : .iPad4,
            "iPhone6,1"  : .iPhone5S,
            "iPhone6,2"  : .iPhone5S,
            "iPad4,1"    : .iPadAir1,
            "iPad4,2"    : .iPadAir2,
            "iPad4,4"    : .iPadMini2,
            "iPad4,5"    : .iPadMini2,
            "iPad4,6"    : .iPadMini2,
            "iPad4,7"    : .iPadMini3,
            "iPad4,8"    : .iPadMini3,
            "iPad4,9"    : .iPadMini3,
            "iPad6,3"    : .iPadPro9_7,
            "iPad6,11"   : .iPadPro9_7,
            "iPad6,4"    : .iPadPro9_7_cell,
            "iPad6,12"   : .iPadPro9_7_cell,
            "iPad6,7"    : .iPadPro12_9,
            "iPad6,8"    : .iPadPro12_9_cell,
            "iPad7,3"    : .iPadPro10_5,
            "iPad7,4"    : .iPadPro10_5_cell,
            "iPhone7,1"  : .iPhone6plus,
            "iPhone7,2"  : .iPhone6,
            "iPhone8,1"  : .iPhone6S,
            "iPhone8,2"  : .iPhone6Splus,
            "iPhone8,4"  : .iPhoneSE,
            "iPhone9,1"  : .iPhone7,
            "iPhone9,2"  : .iPhone7plus,
            "iPhone9,3"  : .iPhone7,
            "iPhone9,4"  : .iPhone7plus,
            "iPhone10,1" : .iPhone8,
            "iPhone10,2" : .iPhone8plus,
            "iPhone10,3" : .iPhoneX,
            "iPhone10,6" : .iPhoneX,
            "iPhone11,2" : .iPhoneXS,
            "iPhone11,4" : .iPhoneXSmax,
            "iPhone11,6" : .iPhoneXSmax,
            "iPhone11,8" : .iPhoneXR,
            "iPhone12,1" : .iPhone11,
            "iPhone12,3" : .iPhone11Pro,
            "iPhone12,5" : .iPhone11ProMax
        ]

    if let model = modelMap[String.init(validatingUTF8: modelCode!)!] {
            return model
        }
        return Model.unrecognized
    }
}

我已经实现了一个超轻量级的库,可以根据给出的一些答案来检测使用的设备:https://github.com/schickling/Device.swift

它可以通过迦太基安装,并像这样使用:

import Device

let deviceType = UIDevice.currentDevice().deviceType

switch deviceType {
case .IPhone6: print("Do stuff for iPhone6")
case .IPadMini: print("Do stuff for iPad mini")
default: print("Check other available cases of DeviceType")
}

这里有一个辅助库。

斯威夫特5

吊舱“股息”,“~> 2.0”

Swift 4.0 - Swift 4.2

吊舱“股息”,“~> 1.3”

如果你只是想确定模型并做出相应的东西。

你可以这样用:

let isIphoneX = Device().isOneOf([.iPhoneX, .simulator(.iPhoneX)])

在函数中:

func isItIPhoneX() -> Bool {
    let device = Device()
    let check = device.isOneOf([.iPhoneX, .iPhoneXr , .iPhoneXs , .iPhoneXsMax ,
                                .simulator(.iPhoneX), .simulator(.iPhoneXr) , .simulator(.iPhoneXs) , .simulator(.iPhoneXsMax) ])
    return check
}