Beginning Sketch Plugins Development in Xcode

Go Beyond CocoaScript, Unleash The Power Of Native Code

James Tang
MagicSketch Blog
5 min readJan 27, 2017

--

If you’re reading this, you probably already know Sketch plugins are suggested to be written in CocoaScript, which is basically JavaScript.

There’re many which we just CAN’T do using CocoaScript.

  1. Communicating with Sketch Classes using Block.
  2. Asynchronous Methods and Background Operations.
  3. Using marcos, and compilation time features like #define, typedef
  4. Writing runtime code in Objective-C.
  5. Code completion.
  6. Debugging and Inspecting runtime objects.
  7. Performance! Since every instructions are going through a Javascript Bridge with CocoaScript, you really can’t expect much.
  8. Interface Builder.

The list goes on. It’s far from ideal development environment, and we don’t wanted to be limited.

In this article, we’ll cover the minimal setup, so that you can get started to build your Sketch plugins in Xcode.

  1. Building a dynamic framework in Xcode.
  2. Loading the framework into Sketch using Mocha.
  3. Reading Logs

Building A Dynamic Framework in Xcode

p.s.: You need to have Xcode installed.

  1. Create a new Xcode project, pick the Cocoa Framework template, I named it HelloSketch.

2. Create a macOS Cocoa Class. I named it HSMain, language Objective-C.

Edit our HSMain.m with the following code:

#import "HSMain.h"
@import AppKit;
#define HSLog(fmt, ...) NSLog((@"HelloSketch (Sketch Plugin) %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);@implementation HSMain- (NSString *)helloText {
HSLog(@"Reading helloText");
return @"Hey there, sending signal from HSMain, over.";
}
@end

This class will be our main starting point. HS of the “HSMain” is our class prefix, it’s important because you don’t want to conflict with any other classes in Sketch. Avoid using the following prefix:

  • MS — Sketch classes.
  • NS — AppKit and Foundation classes, originated from NeXTStep heritage.
  • CA, CF — Core Animation, Core Foundation.
  • AF, BC, CD, CH, EC, FB, SVG, ZK— Popular opensource libraries.

It’s also a good practice to use a three letter class prefix.

3.0 Add a javascript helper file, I name it HelloSketch.js

3. Edit and paste following code to our HelloSketch.js.

var HelloSketch_FrameworkPath = HelloSketch_FrameworkPath || COScript.currentCOScript().env().scriptURL.path().stringByDeletingLastPathComponent();var HelloSketch_Log = HelloSketch_Log || log;(function() {
var mocha = Mocha.sharedRuntime();
var frameworkName = "HelloSketch";
var directory = HelloSketch_FrameworkPath;
if (mocha.valueForKey(frameworkName)) {
HelloSketch_Log("😎 loadFramework: `" + frameworkName + "` already loaded.");
return true;
} else if ([mocha loadFrameworkWithName:frameworkName inDirectory:directory]) {
HelloSketch_Log("✅ loadFramework: `" + frameworkName + "` success!");
mocha.setValue_forKey_(true, frameworkName);
return true;
} else {
HelloSketch_Log("❌ loadFramework: `" + frameworkName + "` failed!: " + directory + ". Please define HelloSketch_FrameworkPath if you're trying to @import in a custom plugin");
return false;
}
})();

4. Add a new Copy Files Phase in the HelloSketch > Build Phases panel. Make sure you’re selecting the HelloSketch framework target.

5. In the Copy Files phase, select Wrapper as the Destination, add HelloSketch.js

6. Remove HelloSketch.js from Copy Bundle Resources.

Loading the framework into Sketch using Mocha

Thanks to Mocha, what CocoaScript based on, the library provides a method to load a framework in Javascript.

If you wanted to know more about how dynamic code loading works behind the scene, read Apple’s documentation, Loading Code at Runtime.

  1. Create your Plugin Bundle (if you haven’t).

2. Locate your .sketchplugin

3. Build your framework, then copy it to your plugin’s Contents > Sketch folder.

4. Edit script.cocoascript, I used Atom.

@import 'HelloSketch.framework/HelloSketch.js'var onRun = function(context) {
log("Hello")
var main = HSMain.alloc().init();
context.document.showMessage(main.helloText());
log("Hello Finish")
};

5. Save your file, try it out! Ta-da.

Reading Logs

If anything, it’d be pretty useful to see logs in Xcode as well as your custom plugin.

  1. Find the console app using Spotlight

2. In All Messages, filter with “Sketch Plugin”.

Download the project

https://github.com/MagicSketch/HelloSketch

Things to consider

Once a dynamic framework was loaded, it can’t be unloaded. Therefore, every time you’ve changes in your Objective-C code, don’t forget to re-copy the framework into your .sketchplugin bundle, and then restart Sketch.

You can certainly use some Xcode Run Script to make the process automate, this leaves to another article.

There’re more Sketch plugins development articles in our blog:

Part 2 — Sketch Plugin Xcode Template

Thanks for reading! Please hit Recommend ❤ to let more people know!

--

--

James Tang
MagicSketch Blog

Sketch Plugins and iOS UX Engineer. Opensource projects contributor, share on Twitter. @jamztang