有没有办法在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中解决这个问题吗?


当前回答

在swift中处理c结构体是很痛苦的。尤其是当里面有c数组的时候。以下是我的解决方案:继续使用objective-c。只需创建一个包装器objective-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()

其他回答

这是一个用于检测apple设备的新库

import DeviceDetector

let detector = DeviceDetector.shared
let deviceName = detector.currentDeviceName
let deviceSet = detector.currentDevice
        
let information = """
Model: \(deviceName)
iPhone?: \(detector.isiPhone)
iPad?: \(detector.isiPad)
Notch?: \(detector.hasSafeArea)
        
4inch?: \(DeviceSet.iPhone4inchSet.contains(deviceSet))
4.7inch?: \(DeviceSet.iPhone4_7inchSet.contains(deviceSet))
iPhoneSE?: \(DeviceSet.iPhoneSESet.contains(deviceSet))
iPhonePlus?: \(DeviceSet.iPhonePlusSet.contains(deviceSet))
iPadPro?: \(DeviceSet.iPadProSet.contains(deviceSet))
"""

结果

斯威夫特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"

在Swift 3中是这样的

 UIDevice.current.model

还有另一个简单的替代方案(模型标识符参考可在https://www.theiphonewiki.com/wiki/Models):找到)

Swift 3/4/5的更新答案,包括字符串修剪和模拟器支持:

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)
}
extension UIDevice {

    public static let hardwareModel: String = {
        var path = [CTL_HW, HW_MACHINE]
        var n = 0
        sysctl(&path, 2, nil, &n, nil, 0)
        var a: [UInt8] = .init(repeating: 0, count: n)
        sysctl(&path, 2, &a, &n, nil, 0)
        return .init(cString: a)
    }()
}

UIDevice.hardwareModel // → iPhone9,3