How To Create an Xcode Plugin: Part 1/3

Get started with exploring app internals as you learn about developing Xcode plugins and some LLDB tips in this first of a three-part tutorial series. By Derek Selander.

2 (1) · 1 Review

Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Toggling and Persisting the Rayroll

You’re designing this plugin to be annoying; no doubt you’d like to toggle it on and off as you work on it, while having your selection persist across the various instances of Xcode using NSUserDefaults.

Navigate to Rayrolling.h and add the following property to the header file:

+ (BOOL)isEnabled;

Now go to Rayrolling.m and add the following methods:

+ (BOOL)isEnabled {
  return [[NSUserDefaults standardUserDefaults] boolForKey:@"com.raywenderlich.Rayrolling.shouldbeEnable"];
}

+ (void)setIsEnabled:(BOOL)shouldBeEnabled {
  [[NSUserDefaults standardUserDefaults] setBool:shouldBeEnabled forKey:@"com.raywenderlich.Rayrolling.shouldbeEnable"];
}

You have the logic to persist your selection; now you need to enable a toggle in the GUI.

Back in Rayrolling.m, modify -(void)doMenuAction to look like the following:

- (void)doMenuAction:(NSMenuItem *)menuItem {
  [Rayrolling setIsEnabled:![Rayrolling isEnabled]];
  menuItem.title = [Rayrolling isEnabled] ? @"Disable Rayrolling" : @"Enable Rayrolling"; 
}

This will simply toggle the boolean to either enable or disable Rayrolling.

Finally, change the menu setup code in didApplicationFinishLaunchingNotification: to look like the following:

NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:@"Edit"];
if (menuItem) {
  [[menuItem submenu] addItem:[NSMenuItem separatorItem]];
  NSString *title = [Rayrolling isEnabled] ? @"Disable Rayrolling" : @"Enable Rayrolling";
  NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:title action:@selector(doMenuAction:) keyEquivalent:@""];
  [actionMenuItem setTarget:self];
  [[menuItem submenu] addItem:actionMenuItem];
}

You now have an NSMenuItem which will persist across Xcode launches and retain the setting to to enable or disable the logic.

Navigate back to NSObject+Rayrolling_DVTBezelAlertPanel.m, and add the following import:

#import "Rayrolling.h"

Finally, open Rayrolling_initWithIcon:message:parentWindow:duration: and replace this line:

if (arg1) {

…with:

if ([Rayrolling isEnabled] && arg1) {

Build and run the program so the changes propagate to the plugin.

Boom! You now have a plugin which modifies the Xcode alert and can be toggled on and off. Pretty nice for a day’s work, eh?

Where to Go From Here?

You can download the completed Rayrolling project from this part of the tutorial.

You’ve made a ton of progress — but there’s still a lot more to do! In part 2, you’ll learn the basics of Dtrace and explore some advanced LLDB features to look into running processes such as Xcode.

If you want to get ahead, there’s some homework to do before you get to part 3, where you’ll see a lot of assembly code. Make sure you start learning now and have a decent understanding of x86_64 assembly by checking out Part I and Part II of Mike Ash’s series on disassembling assembly. These two articles will greatly aid in what’s to come.

Good luck and have fun exploring! If you had any comments or questions from this tutorial, feel free to join the forum discussion below!