Mac的唯一标识符是什么?

31

在iPhone上,我可以使用

[[UIDevice currentDevice] uniqueIdentifier];

如何获取用于标识此设备的字符串?在 macOS 中有类似的方法吗?我找不到任何信息。我只是想识别启动应用程序的 Mac。你能帮我吗?


1
请查看此问题:https://dev59.com/YXNA5IYBdhLWcg3wgeId - Vladimir
给你一个点赞和一个更新到Swift 2的答案。;-) - Joshua Nozzi
3个回答

37

苹果提供了一篇技术文档,讲解如何唯一地识别Mac。下面是一个松散修改过的代码版本,基于该技术文档中苹果发布的代码......构建此代码前不要忘记链接你的项目到IOKit.framework

#import <IOKit/IOKitLib.h>

- (NSString *)serialNumber
{
    io_service_t    platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,

    IOServiceMatching("IOPlatformExpertDevice"));
    CFStringRef serialNumberAsCFString = NULL;

    if (platformExpert) {
        serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert,
                                                         CFSTR(kIOPlatformSerialNumberKey),
                                                             kCFAllocatorDefault, 0);
        IOObjectRelease(platformExpert);
    }

    NSString *serialNumberAsNSString = nil;
    if (serialNumberAsCFString) {
        serialNumberAsNSString = [NSString stringWithString:(NSString *)serialNumberAsCFString];
        CFRelease(serialNumberAsCFString);
    }

    return serialNumberAsNSString;
}

1
很遗憾,这个解决方案在64位模式下无法工作。也许你对这个问题有所了解? - xyz
1
请注意,如果机器已经被修理过(例如更换了主板),那么该机器将没有序列号。您可能需要考虑回退到网络接口的MAC地址。 - harrisg
这适用于应用商店吗? - tofutim
@Jarret 这是否会违反苹果目前的应用商店提交指南? - GoodSp33d
添加了一个 Swift 2 的答案。 - Joshua Nozzi
显示剩余3条评论

20

Swift 2答案

这个答案是基于Jarret Hardie在2011年的答案而来的。它是一个Swift 2字符串扩展程序。我增加了内联注释来解释我所做的操作和原因,因为在这里判断是否需要释放对象可能会很棘手。

extension String {

    static func macSerialNumber() -> String {

        // Get the platform expert
        let platformExpert: io_service_t = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));

        // Get the serial number as a CFString ( actually as Unmanaged<AnyObject>! )
        let serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert, kIOPlatformSerialNumberKey, kCFAllocatorDefault, 0);

        // Release the platform expert (we're responsible)
        IOObjectRelease(platformExpert);

        // Take the unretained value of the unmanaged-any-object 
        // (so we're not responsible for releasing it)
        // and pass it back as a String or, if it fails, an empty string
        return (serialNumberAsCFString.takeUnretainedValue() as? String) ?? ""

    }

}

或者,该函数可以返回String?,最后一行可能不会返回空字符串。这可能使识别无法检索序列号的极端情况更容易(例如修复Mac主板场景 harrisg 在他对 Jerret's 回答的评论中提到)。

我还使用工具验证了正确的内存管理。

我希望有人觉得它有用!


3
感谢您。修改后完美运行。
serialNumberAsNSString = [NSString stringWithString:(NSString *)serialNumberAsCFString];

TO

serialNumberAsNSString = [NSString stringWithString:(__bridge NSString *)serialNumberAsCFString];

__bridge是由Xcode自己推荐使用的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接