GoでOSXのアプリを書く #golang
February 19, 2015
この記事はQiitaの記事をエクスポートしたものです。内容が古くなっている可能性があります。
はじめに
タイトルは釣りです。すいません。 YosemiteからAppleScriptの代わりにJavaScriptが使えるようになったらしいです。
- http://qiita.com/zakuroishikuro/items/1b02378bf9e940602d87
- http://qiita.com/ymmtmdk/items/5cf7665eeddf34adf63e
JavaScriptで動かせるようになったということは、GopherJSの出番ですね!
GopherJS + Nashorn + JavaFXをやったときみたいに、簡単なサンプルを動かしてみました。
Windowを出す
ひとまず、Windowを出してみます。
上記のQiitaのJXAの記事を参考にしながら、JavaScriptのコードを無心でGo言語に変えていきます。
本気でやるなら(やる人はいないだろうけど)型を作った方がいいとは思うけど、とりあえずinterface{}
を使っておきます。
$
変数名に使えないので、__
を代用しました。
相変わらず、Goのソースの中にjs
やobjC
という他の言語の名前が出てくる気持ち悪い感じになっています。
registerSubclass
のあたりなんか、ゾクゾクしますね。
windowWillClose:
をwindowWillClose
って書いててしばらくハマりました。
win.center
と書くとウィンドウが真ん中によるという謎仕様にもハマりました。
関数を呼び出す訳でも、フィールドに値を入れるわけでもなく、単にフィールドにアクセスするだけなのは不思議です。
win.center()
とかの方がわかりやすい気がします。
package main
import (
"github.com/gopherjs/gopherjs/js"
)
func main() {
objC := js.Global.Get("ObjC")
__ := js.Global.Get("$")
objC.Call("import", "Cocoa")
var app js.Object
objC.Call("registerSubclass", map[string]interface{}{
"name": "WinDelegate",
"superclass": "NSObject",
"protocols": []string{"NSWindowDelegate"},
"methods": map[string]interface{}{
"windowWillClose:": map[string]interface{}{
"types": []interface{}{"void", []interface{}{"id"}},
"implementation": func(notification js.Object) js.Object {
return app.Call("terminate", 0)
},
},
},
})
styleMask := __.Get("NSTitledWindowMask").Int() |
__.Get("NSClosableWindowMask").Int() |
__.Get("NSMiniaturizableWindowMask").Int()
win := __.Get("NSWindow").Get("alloc").Call("initWithContentRectStyleMaskBackingDefer",
__.Call("NSMakeRect", 0, 0, 400, 400),
styleMask,
__.Get("NSBackingStoreBuffered"),
false,
)
win.Get("center")
win.Set("title", "Hello Cocoa")
win.Call("makeKeyAndOrderFront", win)
win.Set("delegate", __.Get("WinDelegate").Get("alloc").Get("init"))
app = __.Get("NSApplication").Get("sharedApplication")
app.Call("setActivationPolicy", __.Get("NSApplicationActivationPolicyRegular"))
app.Call("activateIgnoringOtherApps", true)
app.Call("run")
}
動かしてみます。
$ gopherjs build sample.go && osascript -l JavaScript sample.js
Nashornをやった頃より、エラーメッセージがわかりやすくなったので、go build
をかませる必要はないかなと思います。
感想
Nashornの時に、グローバルオブジェクトの対応をしたおかげで、gopehrjsには手を入れずに済みました。 Gopher君の3Dオブジェクトをグリグリやれるところぐらいまでやらないといけなかった気がします。 きっと誰も必要としない記事なんだろうと思います。 ありがとうございました。