Swift 2 Answer
This answer augments Jarret Hardie's 2011 answer. It's a Swift 2 String extension. I've added inline comments to explain what I did and why, since navigating whether or not an object needs to be released can be tricky here.
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) ?? ""
}
}
Alternatively, the function could return String?
and the last line could not return an empty string. That might make it easier to recognize the extreme situations where the serial number could not be retrieved (such as the repaired-Mac-motherboard scenario harrisg mentioned in his comment to Jerret's answer).
I also verified proper memory management with Instruments.
I hope someone finds it useful!