Reputation: 971
There are several terminal commands to retrieve the numerical / abbreviated Model Identifier for Mac hardware.
sysctl hw.model
system_profiler SPHardwareDataType
These dump a string with the hardware name and x,y versioning. Currently we have to maintain a table to convert these identifiers into the full english machine description.
Is there an API, or better a command line tool that can produce the more human friendly names that match Apple's documentation MacBook Pro 15-inch, Mid 2009 or MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports) instead of the more abbreviated MacBookPro5,3 or MacBookPro13,2 Model Identifier?
To summarize, how does System Profiler get the full localized names of Macintosh hardware in a way I can generate to consume that information systematically via script or program?
Upvotes: 24
Views: 12396
Reputation: 3702
No need for web requests to get this info.
The current model, as it appears in About This Mac, can be gathered from:
~/Library/Preferences/com.apple.SystemProfiler.plist
The plist contains names localized in the current users added languages:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>GTF1-sv-SE_SE</key>
<string>MacBook Pro (15 tum, 2016)</string>
<key>GTF1-en-SE_SE</key>
<string>MacBook Pro (15-inch, 2016)</string>
</dict>
</plist>
Where the keys are simply the last 4 letters of the serial number (GTF1) followed by locale.
If you want to, you can even edit this plist to customise your About This Mac window, a common practice amongst Hackintosh users.
EDIT:
Full implementation in Swift 5:
public enum SystemInfo {
public static var serialNumber: String? {
let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
return IORegistryEntryCreateCFProperty(service, "IOPlatformSerialNumber" as CFString, kCFAllocatorDefault, 0).takeUnretainedValue() as? String
}
public static var modelName: String? {
guard let serial = serialNumber,
let plist = try? PropertyList.load(from: .init(fileURLWithPath: "\(NSHomeDirectory())/Library/Preferences/com.apple.SystemProfiler.plist")),
let regionCode = Locale.current.regionCode,
let names = plist["CPU Names"] as? [String: String],
!names.isEmpty else {
return nil
}
for language in Locale.preferredLanguages {
let key = "\(serial.suffix(4))-\(language)_\(regionCode)"
if let entry = names[key] {
return entry
}
}
return nil
}
}
Where I'm also using this helper enum:
public enum PropertyList {
public static func load(from url: URL) throws -> [String: Any]? {
guard let plist = FileManager.default.contents(atPath: url.path) else { return nil }
var format = PropertyListSerialization.PropertyListFormat.xml
return try PropertyListSerialization.propertyList(from: plist, options: .mutableContainersAndLeaves, format: &format) as? [String: Any]
}
public static func save(_ plist: [String: Any], to url: URL) throws {
let data = try PropertyListSerialization.data(fromPropertyList: plist, format: .xml, options: 0)
try data.write(to: url, options: .atomic)
}
}
Usage:
print(SystemInfo.modelName)
Returns (Swedish):
MacBook Pro (15 tum, 2016)
Upvotes: 7
Reputation: 22717
You could use system_profiler -xml SPHardwareDataType
and look for the machine_name
key.
EDIT: Granted, this doesn't answer the question in the title of how the System Profiler does it, but it provides a way to do it in your own code.
Upvotes: 5
Reputation: 780
Did check the network traffic. System Information is connecting to
A full query looks like:
http://support-sp.apple.com/sp/product?cc=DJWR&lang=de_DE
Where 'DJWR' are the last four characters of the serial number
More info here: http://blog.coriolis.ch/get-your-apple-device-model-name-in-a-readable-format/
Upvotes: 16
Reputation: 517
ServerKit.framework
has a property list within its resources that can help you with model identifier <-> model name string translation:
/System/Library/PrivateFrameworks/ServerKit.framework/Versions/A/Resources/English.lproj/XSMachineAttributes.plist
Upvotes: 14