I recently spent a large amount of time trying to shoehorn in a project into sketch. Unfortunately an API broke and there was seemingly no way back. I thought it would be worth sharing my tips for working on Sketch plugins.
CocoaScript
The first thing to understand is the environment. They are using CocoaScript. Which allows you to write javascript with the cocoa frameworks.
You can write it using ObjC brackets or JS underscores. So for example, this:
NSRect frame = [[NSScreen mainScreen] frame]
is equivalent to:var frame = NSScreen.mainScreen().frame()
and this:
[[NSPanel alloc] initWithContentRect:frame styleMask:mask backing:NSBackingStoreBuffered defer:true];
is equivalent to:
NSPanel.alloc().initWithContentRect_styleMask_backing_defer(frame, mask, NSBackingStoreBuffered, true);
As the Cocascript library is available you can use all the features that it provides. You can play around with it using the examples from the project. For example showing a colour wheel:
var filter = [COSQuickCIFilter quickFilterWithKernel:"""
bool isOdd(int v) {
float dividend = float(v) / 2.0;
return dividend != floor(dividend);
}
vec4 hsvToRgb(vec4 hsv) {
float h = hsv.r;
float s = hsv.g;
float v = hsv.b;
int i = int(floor(h));
float f = isOdd(i) ? h - float(i) : 1.0 - (h - float(i));
float m = v * (1.0 - s);
float n = v * (1.0 - s * f);
vec4 result = (i == 0) ? vec4(v, n, m, hsv.a) : ((i == 1) ?
vec4(n, v, m, hsv.a) : ((i == 2) ? vec4(m, v, n, hsv.a) : ((i == 3) ?
vec4(m, n, v, hsv.a) : ((i == 4) ? vec4(n, m, v, hsv.a) : ((i == 5) ?
vec4(v, m, n, hsv.a) : vec4(v, n, m, hsv.a))))));
return (h == -1.0) ? vec4(v, v, v, hsv.a) : result;
}
kernel vec4 colorWheel(float radius) {
vec2 center = vec2(radius, radius);
vec2 v0 = destCoord();
vec2 v1 = vec2(v0.x, radius);
float a = distance(v0, v1);
float b = distance(v1, center);
float angle = atan(a,b);
float pi = 3.14159265;
angle = (v0.x>radius)?((v0.y>radius)?
(atan(b,a)+pi/2.0):atan(a,b)+pi):
(v0.y<radius)?(atan(b,a)+(pi*1.5)):atan(a,b);
vec4 theColor = vec4(1.0);
theColor.r = (angle * 3.0) / pi;
// make it a cirlce
float dist = length(destCoord() - center);
theColor.a = clamp(radius - dist, 0.0, 1.0);
return premultiply(hsvToRgb(theColor));
}"""];
[filter addKernelArgument:[NSNumber numberWithInt:100]];
[COSImageTools viewCIImage:[filter outputImage] inWindowNamed:"Color Wheel" extent:CGRectMake(0, 0, 200, 200)];
Logging Objects
As the documentation is far from complete it is difficult to determine what methods and properties objects have. Using this helper function gives you the names and parameters which can be useful.
function dump_obj(obj){
log("#####################################################################################")
log("## Dumping object " + obj )
log("## obj class is: " + [obj className])
log("#####################################################################################")
log("obj.properties:")
log("#####################################################################################")
log([obj class].mocha().properties())
log("obj.propertiesWithAncestors:")
log([obj class].mocha().propertiesWithAncestors())
log("#####################################################################################")
log("obj.classMethods:")
log("#####################################################################################")
log([obj class].mocha().classMethods())
log("obj.classMethodsWithAncestors:")
log([obj class].mocha().classMethodsWithAncestors())
log("#####################################################################################")
log("obj.instanceMethods:")
log("#####################################################################################")
log([obj class].mocha().instanceMethods())
log("obj.instanceMethodsWithAncestors:")
log([obj class].mocha().instanceMethodsWithAncestors())
log("#####################################################################################")
log("obj.protocols:")
log("#####################################################################################")
log([obj class].mocha().protocols())
log("obj.protocolsWithAncestors:")
log([obj class].mocha().protocolsWithAncestors())
log("#####################################################################################")
log("obj.treeAsDictionary():")
log("#####################################################################################")
log(obj.treeAsDictionary())
}
dump_obj(selection[0])
Exploring Undocumented APIs
Warning that these can easily break between versions. I would recommend using the CocoaLibraries if possible over these.
You can use class dump on the sketch application to list all of the classes.
I created a version here.
Mailing List
The sketch developer mailing list is a great resource and worth subscribing to.
Luckily it is all available online and most questions you have are already been asked.
So we can just use google to find them:
search://mail.sketchplugins.com/ ***