if let sn = Device.serialNumber() {
print("serial number: \(sn)")
}
if let model = Device.model() {
print("model name: \(model)")
}
- 获取产品型号全称(Full marketing name)
Task.init {
if let pn = await try? Device.marketingProductName() {
print("product name: \(pn)")
}
}
代码实现
struct Device {
static func sysctl(by name: String) -> String? {
var len: Int = 0
sysctlbyname(name, nil, &len, nil, 0)
let buf = UnsafeMutablePointer<CChar>.allocate(capacity: len)
buf.initialize(repeating: 0, count: len)
defer { buf.deinitialize(count: len); buf.deallocate() }
sysctlbyname(name, buf, &len, nil, 0)
return String(cString: buf, encoding: .utf8)
}
static func resolveName(from content: String) -> String? {
guard let start = content.range(of: "<configCode>"),
let end = content.range(of: "</configCode>") else { return nil}
return String(content[start.upperBound..<end.lowerBound])
}
/// 产品型号
static func model() -> String? {
sysctl(by: "hw.model")
}
/// 产品序列号
static func serialNumber() -> String? {
let platformExpert = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
defer { IOObjectRelease(platformExpert) }
let key = kIOPlatformSerialNumberKey as CFString
let serialNumberAsCFString =
IORegistryEntryCreateCFProperty(platformExpert,
key,
kCFAllocatorDefault, 0);
guard let serialNumber = serialNumberAsCFString?.takeUnretainedValue() else {
return nil
}
return serialNumber as? String
}
/// 获取产品型号全称
static func marketingProductName() async throws -> String? {
guard let sn = serialNumber() else { return nil}
let cc = sn.suffix(from: sn.index(sn.startIndex, offsetBy: 8))
let url = URL(string: "https://support-sp.apple.com/sp/product?cc=\(cc)")!
let (data, _) = try await URLSession.shared.data(from: url)
guard let content = String(data: data, encoding: .utf8) else { return nil }
return resolveName(from: content)
}
}
网友评论