SketchプラグインHello World

# はじめに

とある目的でSketchをいじっていたら、macOSのシステムフォントを扱えない状況をなんとかできないかと試行錯誤することになり、結果としてSketchプラグインを作るに至りました。
その時のプラグイン開発の知見を簡単に残しておくことにします。

その時に作ったプラグインは以下で公開しているので、どうぞご利用ください。おそらくは、日本のアプリ系UIデザイナーが皆悩んでいた問題を解決し得るものだと思います。


> **I want Apple System Font**
> https://github.com/usagimaru/Sketch-AppleSystemFont-Plugin
> Sketchで選択したテキストレイヤーに、Appleの「システムフォント」を適用します。
> 
> <img width="718" src="https://qiita-image-store.s3.amazonaws.com/0/3603/82cd3a30-4771-6c07-0087-190ccfcfe789.png">



# プラグイン開発の第一歩

## Run Script

プラグインを作らなくとも、スクリプトを即実行できる。
Pluginsメニューからシートを開ける。

<img width="472" src="https://qiita-image-store.s3.amazonaws.com/0/3603/e7d5851c-a572-2c36-424d-a9473ffff0ee.png">

## プラグイン新規作成

Run Scriptで記述した内容を「Save…」ボタンで保存すると自動でプラグインパッケージに変換してくれる。
とりあえず初回表示した時点で諸々テンプレ化されているので、何もせずに一旦保存しておくと良い。

以降は `.cocoascript` ファイルを好みのテキストエディタで編集する具合になる。

あるいは、このページに書かれているやり方でもプラグインパッケージを新規作成することができる。
http://developer.sketchapp.com/guides/first-plugin/

# プラグインの仕組み

.sketchpluginは、スクリプトファイルとmanifest.jsonファイル、リソースファイルで構成されているパッケージ。Finderで「パッケージの内容を表示」すれば中身を展開できる。

![](https://qiita-image-store.s3.amazonaws.com/0/3603/4308a052-28cc-f643-0f7a-dc8b3cab87e9.png)

```
myplugin.sketchplugin
  Contents/
    Sketch/
      manifest.json
      shared.js
      script.cocoascript
    Resources/
      icon.png
```


プラグインの名称、署名、メニューアクションの定義はmanifest.jsonで行う。

manifest.jsonの解説：
http://developer.sketchapp.com/guides/plugin-bundles/#manifest


## スクリプト

いずれかのスクリプトで記述できる。

- CocoaScript
- JavaScript

触ってみるとわかるが、CocoaScriptはJSとObjective-Cを混在させることができる変態言語らしい。Cocoaの知識があれば何をやれば良いのかは大体わかってくる。

### CocoaScriptの記述例

この記事によくまとまっている。

[Interacting with Objective-C Classes in CocoaScript](https://blog.magicsketch.io/interacting-with-objective-c-classes-in-cocoascript-68be7f39616f)

## 開発環境

小さなプログラムであればRun Scriptのシートダイアログでやってしまった方が良いかもしれない。コンソールもあるのですぐに結果を見ることができる。

Sketch DevTools プラグインを導入しておくと、プラグインの実行結果をコンソールウインドウに出力することができる。

![32320758-1dc414d8-bfbf-11e7-9282-1d57fc53874d.png](https://qiita-image-store.s3.amazonaws.com/0/3603/8d40dd6b-6cf0-a385-2650-7f382a0bdd6d.png)
https://github.com/skpm/sketch-dev-tools

## プラグインのリロード設定を変更する

cocoascriptファイルやmanifestファイルを変更したらすぐにプラグインに反映してほしい。
Terminalで次の設定を有効にしておくとプラグインのリロードが行われるようになる。

```
$ defaults write ~/Library/Preferences/com.bohemiancoding.sketch3.plist AlwaysReloadScript -bool YES
```

http://developer.sketchapp.com/guides/preferences/

## メニューアクションからメソッドを呼び出す

Pluginsメニューのメニュアクションから特定のメソッドを呼び出すには、次のように書くと良い。

```json:manifest.json
{
  "author" : "usagimaru",
  "commands" : [
    {
      "script" : "script.cocoascript",
      "name" : "Menu Title",
      "handlers" : {
        "run" : "onRun"
      },
      "identifier" : "com.hoge.fuga.onrun"
    }
  ],
  "menu" : {
    "isRoot" : false,
    "title" : "My Actions",
    "items" : [
      "com.hoge.fuga.onrun"
    ]
  },
  "identifier" : "com.hoge.fuga.myplugin",
  "version" : "1.0",
  "description" : "初めてのSketchプラグインです。",
  "authorEmail" : "mail@address.com",
  "name" : "My plugin's name"
}
```

handlers の中に "run" というキー名でメソッド名を記述。これで「Menu Title」という名前のメニューを選択すると `onRun` メソッドが呼び出されるようになる。

```script.cocoascript
var onRun = function(context) {
    // ここに処理を記述
};
```

contextという引数をひとつ持ち、ここからドキュメントの情報や現在の状態（選択中のレイヤー一覧など）が得られる。


# 次のステップへの手がかり

## SketchのObjective-Cヘッダーを探る

プラグインで凝ったことをやろうとするとSketch.app自体のハックが必要になってくる。
Sketchをclass-dumpにかけるか、このリポジトリーに上がっているObjective-Cヘッダーを眺めると各クラスが持つメソッド一覧を得られる。

https://github.com/abynim/Sketch-Headers

## 公式のAPIリファレンスを探る（JavaScriptの場合）

CocoaScriptだとそんなメソッドはundefinedやでと怒られるので注意。

http://developer.sketchapp.com/reference/api/
https://github.com/BohemianCoding/SketchAPI

## 他のプラグインやコードを探る

ここのGistには参考になりそうなコードがまとまっている。
https://gist.github.com/bomberstudios

## Cocoaバンドルを組み込んでより本格的な機能を実現するには？

XcodeでCocoaバンドル（.bundleパッケージに含まれる実行ファイル）をビルドして、それをSketchプラグインに組み込むことができるようです。
おそらくは独自のUIなりを実装するのに必要なのだと思いますが、その仕組みまではまだ探れていません。