Blog headline image

Debugging a System Preference Pane With Xcode 6

August 31st, 2015 by ‐ No Comments

SystemPrefs iconThis may be an exotic topic for most, but sometimes you want to develop a preference pane for the System Preferences app. Of course NSLog() is your friend, but sometimes print debugging just won’t cut it. Especially when it comes to fixing crashes or timing problems. Well, debugging a preference pane from Xcode is no problem – if you know how to set it up.

When searching the Interwebs, one of the first things that caught my attention was Brian Dunagan‘s post on Debugging Preference Panes in Xcode. That kind of gave me an idea which route to take, but it’s from 2009. Now we’re an Xcode major release or two further down the road, and Brian’s instructions don’t work out of the box any more. But no worries, updated instructions await below.

Brian’s scheme involves a manual step: finding the freshly compiled pref pane and double-clicking it to get it installed. After a few iterations, this gets quite boring. So I decided to change my set up to fully automatic; i.e. launch a shell script to copy the pref pane to the installation directory, and have Xcode fire up System Preferences, and attach the debugger to it. All with a single button press “run” under the debug configuration. It all seemed to work fine, System Preferences opened up, showing my shiny new pref pane in the bottom row. But when I clicked it to open it:

system preferences must quit and reopen

Bummer! This wasn’t happening when the pref pane was installed by double-clicking it in the Finder and manually launching System Preferences.Also, the console bragged something about “Garbage Collection enabled” and “GC capability mismatch”. Enabling garbage collection is not an option, since Xcode 6 will refuse to compile non-ARC projects. Apple’s documentation is also not overly helpful, since it is dated 2012 and states that 64-bit preference panes for System Preferences must support garbage collection. technically you can’t because Xcode 6 won’t let you, and it’s no longer true for nowadays System preferences app as the eye-opening post Garbage Collection app loading ARC binary explains. Stack Overflow to the rescue! It turns out that ARC is backwards compatible, that System Preferences has the right switch (guess why?), and that it is invoked with a different environment from Xcode than otherwise (no surprise really).

So with all these findings, here is the step-by-step guide how to debug a pref pane in System preferences from within Xcode:

  1. Edit your build schemes, and select the “Run” scheme, and make sure you are editing “Debug” (A). In the environment variables section, click on “+” to add a new environment variable (B). Name the new variable OBJC_DISABLE_GC, and set its value to YES.adding the new environment variable to the run scheme
  2. Click the little disclosure triangle for the run scheme to reveal its detailed settings. Then select pre-actions.adding the shell script Click the “+” at the bottom to add a run script action. Enter /bin/sh as the shell, make sure that your target is selected to provide build settings, and type a shell command line to install the newly compiled pref pane in your personal Library folder:
    cp -Rf ${CONFIGURATION_BUILD_DIR}/MySettings.prefPane ~/Library/PreferencePanes
       
    

    Be sure to change “MySettings” to the name of your pref pane. Also be sure to keep the “~” to install into your home directory. If you remove the “~” the copy operation will silently fail, and you will be scratching your head why it’s not working.

  3. Select the run step, choose “other” from the executable drop-down menu, and select System Preferences in the Applications folder. Verify that debug executable, and launch automatically are both checked.setting system preferences as the executable to debug

 

That’s all! Now when you have the debug configuration selected, and click “run” in Xcode, your pref pane will be compiled (in case you made any changes), copied to the pref panes folder in your home directory, System preferences will be launched, and will come to the front. You should now see the icon for your pref pane somewhere. If you now go back to Xcode, you can set breakpoints, watchpoints, or whatever you wish to debug. When you click on your pref pane’s icon to open it, your code will be executed, it will stop at breakpoints, and you can debug it as you would debug any normal app, too. NSLog() messages will appear in Xcode’s debugger pane, so you don’t need to have the system console hanging around.

Happy debugging!