在运行时在Mac应用程序中以编程方式检测苹果芯片与英特尔CPU



在Mac应用程序中,我如何以编程方式检测(在运行时)应用程序当前是否运行在带有英特尔或苹果硅处理器的Mac上?

在Objective-C中,可以使用systemuname函数。这相当于来自壳层的uname -m

#include <sys/utsname.h>
NSString *GetMachineHardwareName(void) {
struct utsname sysinfo;
int retVal = uname(&sysinfo);
if (EXIT_SUCCESS != retVal) return nil;

return [NSString stringWithUTF8String:sysinfo.machine];
}

或Swift

func GetMachineHardwareName() -> String? {
var sysInfo = utsname()
let retVal = uname(&sysInfo)
guard retVal == EXIT_SUCCESS else { return nil }
return String(cString: &sysInfo.machine.0, encoding: .utf8)
}

对于最新型号的Intel mac,返回x86_64。对于Apple Silicon,它返回arm64

解决方案兼容Xcode 14及更新版本

我们检索utsname.machine并将其与"arm64":

进行比较
extension utsname {
static var sMachine: String {
var utsname = utsname()
uname(&utsname)
return withUnsafePointer(to: &utsname.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: Int(_SYS_NAMELEN)) {
String(cString: $0)
}
}
}
static var isAppleSilicon: Bool {
sMachine == "arm64"
}
}
  • "arm64"for Apple Silicon
  • "x86_64"或";i386"对于英特尔

MacOS 12+更新

Todd的答案会崩溃当一个应用程序链接到macOS 12.5 SDK,因为sysInfo.machine字段不是一个以空结束的字符串,这显然现在由String(cString:encoding:)强制执行。

这是一个可以工作的更新版本:

///
///  Determines the architecture of the Mac on which we're running. Returns `arm64` for Apple Silicon
///  and `x86_64` for Intel-based Macs or `nil` if the system call fails.
///
func getMachineHardwareName() -> String?
{
var sysInfo = utsname()
let retVal = uname(&sysInfo)
var finalString: String? = nil

if retVal == EXIT_SUCCESS
{
let bytes = Data(bytes: &sysInfo.machine, count: Int(_SYS_NAMELEN))
finalString = String(data: bytes, encoding: .utf8)
}

// _SYS_NAMELEN will include a billion null-terminators. Clear those out so string comparisons work as you expect.
return finalString?.trimmingCharacters(in: CharacterSet(charactersIn: ""))
}

最新更新