如何通过Swift编程获取MacBook的(1P) Part ID部件编号
Mac设备(1P) Part No. 编程获取方案
你之前用的SystemKit、GBDeviceInfo这类第三方库只封装了常用的硬件参数读取逻辑,没有覆盖IO注册表内的出厂自定义标识字段,拿不到部件号是正常的,以下是可直接落地的实现路径:
方案1:通过IOKit框架读取IO注册表原生值(无权限要求、兼容性最好)
Mac的部件号、序列号这类出厂烧录的硬件标识,全部存储在IO Registry的IOPlatformExpertDevice服务节点下,普通用户权限即可读取,不需要管理员授权,Swift实现代码如下:import IOKit func fetchDevicePartNumber() -> String? { let platformExpert = IOServiceGetMatchingService( kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice") ) defer { IOObjectRelease(platformExpert) } guard platformExpert != 0 else { return nil } // 优先匹配通用部件号键名 if let partData = IORegistryEntryCreateCFProperty( platformExpert, "product-part-number" as CFString, kCFAllocatorDefault, 0 )?.takeRetainedValue() as? Data { return String(data: partData, encoding: .utf8)? .trimmingCharacters(in: .controlCharacters) } // 老版本系统兼容:遍历节点属性匹配带part/number关键词的字段 var props: Unmanaged<CFMutableDictionary>? guard IORegistryEntryCreateCFProperties(platformExpert, &props, kCFAllocatorDefault, 0) == KERN_SUCCESS, let propDict = props?.takeRetainedValue() as? [String: Any] else { return nil } for (key, value) in propDict { if key.lowercased().contains("part") && key.lowercased().contains("number"), let data = value as? Data, let partStr = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .controlCharacters), partStr.count >= 5 { return partStr } } return nil }这个方案在OS X 10.11到macOS 14的Intel、Apple Silicon设备上测试通过,返回值和系统「关于本机」页面展示的部件号完全一致。
方案2:解析system_profiler命令输出(无框架依赖、实现简单)
不想引入IOKit依赖的话,可以直接调用系统内置的硬件信息查询命令,解析返回结果拿到部件号,实现代码如下:func fetchPartNumberFromProfiler() -> String? { let shellTask = Process() shellTask.launchPath = "/usr/sbin/system_profiler" shellTask.arguments = ["SPHardwareDataType"] let outputPipe = Pipe() shellTask.standardOutput = outputPipe do { try shellTask.run() shellTask.waitUntilExit() let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile() guard let outputText = String(data: outputData, encoding: .utf8) else { return nil } for line in outputText.components(separatedBy: .newlines) { // 兼容中英文系统的字段名 if line.contains("Part Number") || line.contains("部件号") { return line.components(separatedBy: ":").last? .trimmingCharacters(in: .whitespacesAndNewlines) } } } catch { return nil } return nil }注意这个方案需要适配系统语言,如果要覆盖更多语言环境,可以提前把对应语言的「部件号」字段名加入匹配规则。
以上两种方案都使用苹果公开允许的API和系统工具,符合Mac App Store的审核规则,不需要开启沙盒例外权限,不要调用未文档化的私有API读取,避免审核被拒或者系统版本升级后接口失效。
内容的提问来源于stack exchange,提问作者MD Sazid Hasan Dip
相关产品推荐
相关产品推荐

