2

I want to Identify a Mac based on Hardware ID.I have seen this

https://developer.apple.com/library/content/technotes/tn1103/_index.html

It gives mainly 2 approaches

1 -Using S/N: But it seems this might not be supported in future Machines

2 -Using MAC ID: I don't know if this is reliable

Could you please suggest the best way and provide me some sample code in SWIFT to start with.Almost all examples are in Objective C. I'm new to SWIFT as well.

Community
  • 1
  • 1
techno
  • 6,100
  • 16
  • 86
  • 192
  • 1
    Swift code for obtaining the serial number is here https://stackoverflow.com/a/35486613/1187415, and Swift code for obtaining the MAC address of the (built-in) Ethernet interface is here https://stackoverflow.com/q/31835418/1187415. – Martin R Oct 10 '17 at 17:56
  • Macs have also a Hardware UUID – vadian Oct 10 '17 at 17:58
  • @vadian Is this approach reliable ... Can you point me in some direction or may be a sample code :) – techno Oct 10 '17 at 18:02
  • It's the same as getting the serial number but passing the key `IOPlatformUUID`. Consider that the tech note is from 2006 / 2011. The approach is reliable. – vadian Oct 10 '17 at 18:04
  • @vadian Which is the most reliable approach? Can you Please provide me some example.. – techno Oct 10 '17 at 18:05
  • @MartinR Thanks... Which is the most reliable approach? – techno Oct 10 '17 at 18:05
  • You can do this in Terminal if that helps... `system_profiler SPHardwareDataType` It gives you a serial number and a hardware UUID. – Mark Setchell Oct 10 '17 at 18:08
  • Once again it's the same code as getting the serial number but passing `kIOPlatformUUIDKey`rather than `kIOPlatformSerialNumberKey` – vadian Oct 10 '17 at 18:08
  • @techno You can use the serial number approach from this answer https://stackoverflow.com/a/35486613/2303865 – Leo Dabus Oct 10 '17 at 18:08
  • @LeoDabus Is this reliable and will this work on all versions of OSX? Please advice.. – techno Oct 10 '17 at 18:12
  • @techno I haven't tested it on different macOS versions but nothing stops you from doing so. It looks reliable considering that all you need is to import Foundation. – Leo Dabus Oct 10 '17 at 18:14
  • You can also make it non optional and a bit shorter using guard case let and returning an empty string in case of an unlikely failure `var serialNumber: String { guard case let platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice") ), platformExpert > 0, let serialNumber = IORegistryEntryCreateCFProperty(platformExpert, kIOPlatformSerialNumberKey as CFString, kCFAllocatorDefault, 0).takeUnretainedValue() as? String else { return "" } IOObjectRelease(platformExpert) return serialNumber }` – Leo Dabus Oct 10 '17 at 18:16
  • @LeoDabus: The purpose of optionals is that you *don't* have to return magic values (like empty strings) in the case of a failure :) – Martin R Oct 10 '17 at 18:28
  • @MartinR is it possible for a macOS machine to do not have a Serial Number? – Leo Dabus Oct 10 '17 at 18:29
  • 1
    @vadian: I wonder why TN 1103 does not mention the IOPlatformUUID, do you have an idea? – Martin R Oct 10 '17 at 18:30
  • @MartinR He can also just throw a fatalError() instead of returning an empty string in this case `var serialNumber: String { guard case let platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice") ), platformExpert > 0, let serialNumber = IORegistryEntryCreateCFProperty(platformExpert, kIOPlatformSerialNumberKey as CFString, kCFAllocatorDefault, 0).takeUnretainedValue() as? String else { fatalError("Serial Number not found") } IOObjectRelease(platformExpert) return serialNumber }` – Leo Dabus Oct 10 '17 at 18:35
  • @Leo I don't know if the calls can fail. But yes, either you *assume* that they succeed, or you return an optional and let the caller decide. – But even Apple's same code at https://developer.apple.com/library/content/technotes/tn1103/_index.html#//apple_ref/doc/uid/DTS10002943-CH1-TNTAG3 check the success of the calls and *might* return NULL. – Martin R Oct 10 '17 at 18:36
  • @MartinR My guess: The tech note is pretty old and talks about Panther (10.3) and Tiger (10.4). `kIOPlatformUUIDKey` has been introduced in Leopard (10.5) – vadian Oct 10 '17 at 18:37
  • @vadian: Good point! – And perfectly documented https://developer.apple.com/documentation/iokit/kioplatformuuidkey: "No overview available" :) – Martin R Oct 10 '17 at 18:42
  • @vadian You can't run Swift based apps on OSX earlier than 10.9 anyways – Leo Dabus Oct 10 '17 at 18:44
  • @LeoDabus * _g_ * Indeed. Another advantage for the hardware UUID. – vadian Oct 10 '17 at 18:53
  • Using kIOPlatformUUIDKey in above code gives the same result as calling `gethostuuid()`, and the man page of that function states: *"Be aware that the hardware identifiers that gethostuuid() uses to generate the UUID can themselves be modified."* – Martin R Oct 10 '17 at 19:04
  • @MartinR so also from the link you posted **It is possible for a system to lose its serial number so that it will no longer appear either in System Profiler or the I/O Registry. Repairing a system by swapping hardware components is one reason this can happen. Apple does not document the specific details of how a machine can lose its serial number. Once the serial number has been lost there is no means to restore it to the machine. Apple does not guarantee that all future systems will have a software-readable serial number.** – Leo Dabus Oct 10 '17 at 19:14
  • @MartinR Which one do you think it is the recommended approach ? – Leo Dabus Oct 10 '17 at 19:15
  • @LeoDabus: I don't know. None of the approaches listed in TN 1103 is guaranteed to be stable. – Martin R Oct 10 '17 at 19:21
  • @vadian never mind I did manage to create a method here – Leo Dabus Oct 10 '17 at 20:40
  • @LeoDabus You're welcome. – vadian Oct 10 '17 at 20:41
  • @LeoDabus Can you please share your solution? – Parag Bafna Oct 08 '20 at 05:37

0 Answers0