How does System Profiler retrieve the full Mac hardware identifier?

Questions : How does System Profiler retrieve the full Mac hardware identifier?

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?

MacBookPro5,3 MacBookPro13,2

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?

Total Answers: 4 Answers 4


Popular Answers:

  1. 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) 
  2. 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) 
    1. Press Ctrl + Shift + R

    2. Replace the old package with the new one.

    3. Right click on the package name.

    4. Refactor > Rename and rename to the new one

  3. ctrl + Shift + R has always worked for me. Simply replace all and choose All Files.

  4. Please try the following steps:

    1. Click on the setting gear icon and deselect Compact Empty Middle Package
    2. Now we can see each package folder is broken into parts
    3. Now right click on the first package folder >>> refactor >>> rename
    4. Now a warning will be displayed but you go ahead and click Rename Package
    5. After that enter your domain name for the package name
    6. Click on ‘Do Refactor’
    7. Now it has changed the package domain name of the App. Now Change the domain extension and App folder name according to your requirement
    8. Now open build.gradle (Module: app) in Gradle Scripts. Here change the application id and click Sync Now.

    *******Finally it’s done ******

  5. enter image description here

    3 Methods to change package name in Android Studio

    I think this is a new one. I tried it and it’s working. If the above doesn’t work for you. Try this. On the site I mentioned above, there are 2 other methods too with image tutorials. I also checked.

    First I am going to talk about changing the Package name. In this example, We will change the package name “com.androidride.myapplication” to “info.xyz.yourapplication”.

    1. Right click on the package name you want to change and select Refactor – > Move.
    2. A new dialog appears, Choose Move package “com.androidride.myapplication” to another package and click on Ok.
    3. A warning dialog appears, click on yes.
    4. Enter new package name in the new dialog. But only “info.xyz” leave yourapplication.
    5. Now you will see a warning dialog says Package info.xyz does not exist. Do you want to create it? click on yes.
    6. Click on “Do Refactor”. Now your package name changed to info.xyz.myapplication.
    7. Right click on info.xyz.myapplication and Refactor -> Rename.
    8. Click on Rename package.
    9. Rename dialog: change myapplication to yourapplication.
    10. Click on Do refactor.
    11. Delete old package name directories and change application id in build.gradle, change it into info.xyz.yourapplication.
    12. That’s all.
  6. Right Click on the Package name -> Refractor ->Rename -> enter the name of the package ->Click “Refractor”. Do not edit any of the build files except “build.gradle” under the “app” folder.

    From Renaming android studio project – Vishnu Sivan

    • Go to project path > where you located Java files and package
    • Create new folders, for example com → super_package → activities
    • Android Studio will refresh project structure
    • Move all Java files to new folders
    • Remove old folders
    • Menu EditFind → Replace in path:
    • Change old package name to new
    • Change also in manifest and build gradle

    Done!

  7. The question asked:

    Is there an automatic refactoring included?

    I want to make bulk refactoring, but I don’t know how. I worked two years with Eclipse and in Eclipse it’s a one-click operation.

    Well, almost one-click with automatic refactoring, but just one small step first, i.e., just the small step to create the new package. Here is the full solution below.

    You can rename a package by creating a new package (including the required folder path) and then drag-and-drop over from the old package (and let Android Studio take care of the refactoring of the various references from the old package to the new), as follows:

    1. Right click on java under app. Right click on java under app
    2. Select New and Package enter image description here
    3. Select the location for the new package as ../app/src/main/java enter image description here
    4. Enter the full name of the new package enter image description here
    5. The new package will be created. Now, drag-and-drop over from the old package to the new. Preview the refactoring if you’d like to check that Android Studio is doing it properly. If it all looks good, proceed with the refactoring.

    NB: since application ID and package name are decoupled these days, note that the above is only for renaming the package name. For changing the application ID, you can do that in your build.gradle.

  8. Go to AndroidManifest.xml There you will find the package as the attribute of the manifest tag. Just select the part you want to change, right-click-> refactor -> rename

    Maybe earlier it was hard, but as of today, it is not anymore.

    You might also want to change the app id in

    defaultConfig { applicationId } 

    Short & Sweet

  9. That works very well for me, even for changing the occurrences, in all the modules concerned, for the folders names I want to modify in the package but, for me, it works fine only if I follow exactly the following steps :

    • A – If you want to change the name of the root folder (in other words the folder’s name who is normaly used in the package to contain the principal activity), you can do it before or after the following steps (B to C) by exiting from “Android Studio” and rename manually this root folder. Click after on “Import project…” and then on the new name of your project (this import process will automatically readjust the ‘Gradle’ files with the project files.)
    • B – before the following C step, don’t forget to modify manually the folder’s names you want to change in the package by changing them in the 3 following files: ‘AndroidManifest.xml’, ‘MainActivity.java’ (or the name you eventually choose for your first activity) and the ‘build.gradle (Module: app)’ file.
    • C – Follow the steps 1 to 6 described above (“In your Project pane, click on the little gear icon…”) -> https://stackoverflow.com/a/29092698/2001610
    • D – Only if you want to change the name of the root folder now, you can follow the ‘A’ process, as described above.
  10. After you follow one of these techniques to get your package renamed, you might start seeing errors.

    If / when your R.java is not getting generated properly, you’ll get a lot of errors in your project saying error: cannot find symbol class R and also error: package R does not exist.

    Remember to check your Application manifest xml. The manifest package name must match the actual package name. It seems the R.java is generated from the Application Manifest and can cause these errors if there’s a mismatch.

    Remember to check the package attribute matches in your <manifest package="com.yourcompany.coolapp">

  11. I needed to run File->Invalidate Caches/Restart… to remove remnants of the original package

  12. To rename the package name in Android studio, Click on the setting icon in the project section and untick the Compact empty Middle Packages, after that the package will split into multiple folder names, then right-click on the folder you need to change the name, click on refactor-> Rename-> Type the name you want to change in -> Refactor -> Refactor Directory, then import R.java file in the whole project. Working for me.

    • First, you need to go to the settings icon which is Appear in left. Click on that dropdown and uncheck Compact Empty Middle Packages

    Go to Your AndroidManifest.xml

    1. Select All of your Package and then Right click there
    2. Refactor and then rename that how you want.
    3. and then go to your build.gradle and then change Applicationid with packagename that what you have in Android Manifest.

    It is worked For Me

  13. for example if you want change package from com.example.a to com.example.b

    1)change project style folder from android to package (in project side)

    2)right click top of folder and click replace in path

    3)select in project button

    4)in first input write com.example.a

    5)in second input write com.example.b

    6)when you see warning select replace all to replace value

    after finish replace you can see your package name is com.example.b

  14. There is also a good keyboard shortcut key just click n select the Class / Package which you want to rename and press ALT + two times R or Shift+ F6

    which reflect :-> Refactor menu and Rename function in Android Studio. After rename the existing package it shows in bottom side where the effect of this reflection / rename if you click on Refector button it will change the Class name / Package name where is used in whole Project.

  15. """ Notes: 1 - This script it for python3 2 - Create a backup first 3 - Place on the root folder of the android project you want to change 4 - run `python change_android_studio_pkg_name.py` 5 - Type the old package name 6 - Type the new package name 7 - Clean and Rebuild on Android Studio 8 - SRC folder names won't be changed but app will work """ import os, glob, traceback from pathlib import Path def rwf(fp, mode="r", data="" ): if mode == "r": with open(fp, "r", encoding='utf8') as f: return(f.read()) elif mode == "w": with open(fp, "w", encoding='utf8') as f: f.write(data) old_pkg = input("Old PKGn").strip() new_pkg = input("New PKGn").strip() if not old_pkg or not new_pkg: exit("Args Missing") dirname, filename = os.path.split(os.path.abspath(__file__)) file_types = ['xml', 'txt', 'json', 'gradle', 'java'] _fs = glob.iglob(f"{dirname}/**", recursive=True) for file_path in _fs: ext = Path(file_path).suffix.replace(".", "").lower() if os.path.isfile(file_path) and ext in file_types: try: content = rwf(file_path) new_content = content.replace(old_pkg, new_pkg) rwf(file_path, "w", new_content) except: print(traceback.format_exc()) pass

Tasg: macos, cocoa