LoginSignup
20
21

More than 5 years have passed since last update.

XcodeのメニューをカスタマイズするプラグインをSwiftで作る

Last updated at Posted at 2015-07-29

追記
サンプルプラグインをアップしました
https://github.com/iTerasaka/CustomMenuWithSwift


こんにちは! 寺坂です

セミも鳴き始めてすっかり夏です

暑い日は自宅にこもってモクモクと開発するのもいいですね


と、いうことで、

今回はXcodeのプラグイン開発の導入を書いていきたいと思います。

拙い部分も多いですが、どうか温かい目でよろしくお願いします!

プラグイン開発用のプロジェクト作成~ビルド成功まで

こちらを参考に、まずはプラグインのビルド+プラグイン読み込みまでを成功させましょう。

基本的には、Objective-cと同様の設定を行います。

Swiftビルド用のライブラリを有効にする点など、

異なる部分もあるので丁寧に設定していきましょう。

また、今回使用するXcodeのバージョンは、6.4になります。

最初に呼ばれるクラス作成

下記のクラスメソッドを定義しておくと、そのクラスが呼ばれます。

class func pluginDidLoad(bundle: NSBundle)

さっそくクラスを作成していきます。

MyPlugin.swift
import Foundation

class MyPlugin: NSObject {

    class func pluginDidLoad(bundle: NSBundle) {
        NSLog("Hello world :)")
    }
}

ここまでで、Xcode起動時に"Hello World"がログに出力されるようになります。

このクラスを編集して、

自作メニューを追加するところまで進めていきます。

AppKitのimport

メニューの編集は、AppKitに含まれているNSMenuなどを利用しますので

AppKitをインポートする必要があります。

MyPlugin.swift
import Foundation
import AppKit

class MyPlugin: NSObject {

    class func pluginDidLoad(bundle: NSBundle) {
        NSLog("Hello world :)")
    }

}

NSNotificationを設定

NSAppを利用してメニューをカスタマイズしていきますが、

pluginDidLoad(bundle: NSBundle) が呼ばれた時点では、NSAppはまだ空の状態です。

そこで、アプリケーション起動後に処理を実行するために、

NSNotificationで監視しましょう。

NSApplicationDidFinishLaunchingNotification はアプリケーション起動後のキーです。

このキーを使って登録することで、

アプリケーション起動後にsetMenu()が呼ばれるようになります。

MyPlugin.swift
import Foundation
import AppKit

class MyPlugin: NSObject {

    class func pluginDidLoad(bundle: NSBundle) {
        NSLog("Hello world :)")

        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: "setMenu",
            name: NSApplicationDidFinishLaunchingNotification,
            object: nil
        )
    }

    class func setMenu(){
        NSLog("called MyPlugin setMenu() :)")
    }

}

既存メニューへ項目を追加する

ためしに「Edit」メニューに項目を追加してみましょう。

追加部分だけを書くと、以下のようになります。

MyPlugin.swift

if let mainMenu = NSApp.mainMenu ?? nil {

    // 既存のメニューに項目を追加する

    let editMenu = mainMenu.itemWithTitle("Edit")
    let newItemInEdit = NSMenuItem(title: "Hello World", action: "printHelloWorld", keyEquivalent: "")

    newItemInEdit.target = self
    editMenu?.submenu?.addItem(newItemInEdit)
}

新しいメニューを自作する

自作メニューを追加する方法はこちらです。

MyPlugin.swift

if let mainMenu = NSApp.mainMenu ?? nil {

    // 新しいメニューを追加する

    let myMenu = NSMenu(title: "MyMenu")
    let myMenuItem1 = NSMenuItem(title: "Hello World1", action: "printHelloWorld", keyEquivalent: "")
    let myMenuItem2 = NSMenuItem(title: "Who am I", action: "printMe", keyEquivalent: "")

    myMenuItem1.target = self
    myMenuItem2.target = self
    myMenu.addItem(myMenuItem1)
    myMenu.addItem(myMenuItem2)

    let newMenuItem = NSMenuItem(title: "MyMenu", action: nil, keyEquivalent: "")
    newMenuItem.submenu = myMenu

    mainMenu.addItem(newMenuItem)
}

完成

全部くっつけたものが、下のコードです。

このクラスが実行されて、

新しいメニューが追加されていることが確認できれば成功です。

ありがとうございました!

MyPlugin.swift
import Foundation
import AppKit

class MyPlugin: NSObject {

    class func pluginDidLoad(bundle: NSBundle) {
        NSLog("Hello world :)")

        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: "setMenu",
            name: NSApplicationDidFinishLaunchingNotification,
            object: nil
        )
    }

    class func setMenu(){
        NSLog("called MyPlugin setMenu() :)")

        if let mainMenu = NSApp.mainMenu ?? nil {

            // 既存のメニューに項目を追加する

            let editMenu = mainMenu.itemWithTitle("Edit")
            let newItemInEdit = NSMenuItem(title: "Hello", action: "hello", keyEquivalent: "")

            newItemInEdit.target = self
            editMenu?.submenu?.addItem(newItemInEdit)

            // 新しいメニューを追加する

            let myMenu = NSMenu(title: "MyMenu")
            let myMenuItem1 = NSMenuItem(title: "Good Morning", action: "goodMorning", keyEquivalent: "")
            let myMenuItem2 = NSMenuItem(title: "Good Afternoon", action: "goodAfternoon", keyEquivalent: "")

            myMenuItem1.target = self
            myMenuItem2.target = self
            myMenu.addItem(myMenuItem1)
            myMenu.addItem(myMenuItem2)

            let newMenuItem = NSMenuItem(title: "MyMenu", action: nil, keyEquivalent: "")
            newMenuItem.submenu = myMenu

            mainMenu.addItem(newMenuItem)
        }
    }

    class func hello(){
        NSLog("Hello:)")
    }

    class func goodMorning(){
        NSLog("Good Morning:)")
    }

    class func goodAfternoon(){
        NSLog("Good Afternoon:)")
    }
}

参考サイト

初めてのXcode 5 プラグイン開発 -
http://dev.classmethod.jp/smartphone/xcode5-plugin-1/

Xcode 5 プラグイン 開発のテクニック -
http://dev.classmethod.jp/smartphone/xcode5-plugin-2/

いつかに備えてXcode Plugin作成コトハジメ
http://qiita.com/kgmyshin/items/c2e4e270a37882d3306a

20
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
21