2007年 03月 25日

RubyCocoa はホントに素晴しいからマカーな人はみんな使ってみるといいと思う。

たぶん Python とか Perl とかでもできるんだろうけど、言語はそんな関係ない気がする (Ruby 好きだから Ruby で書いてるけど)。

BUS Error でると悲しいけど、そんなに出まくるわけじゃないし、簡単に GUI も作れちゃうし (偉大なる Interface Builder 様のおかげ)、Cocoa でできることはなんでもできるし、Cocoa でできない Carbon なのも obj-c で拡張ライブラリ書いて (Ruby の拡張ライブラリは驚くほど簡単に書ける。「ちょっとめんどうくさい C syntax な Ruby」だ) 組みこめるし、そうなると (C 書いてるからあたりまえだけど) なんでもできる。


あと、拙作の newcocoa を使うとちょっと楽になる (バグってるかも。0.0.1 はおかしくて手元ではなおしてたのだけど、リリースしてなかった。さっき 0.0.2 をリリースした)

# sudo gem install newcocoa
newcocoa Sample
cd Sample
rake

これで Sample アプリが起動する。rake でコンパイルして実行までする (test がデフォルトターゲットではない)

open English.lproj/Main.nib

すると Interface Builder が起動するので、ウィンドウとか作って、必要なクラスとか作って、繋げて、保存して、で作ったクラスのヘッダファイルを作ってどーん。

例えば MainController っていうクラスを NSObject を継承して作って instantiate して、それにアクションとアウトレットを定義して、Ctrl 押しながらデザインしたフォームのアイテムと関連付けて、インターフェイスのテストして、あとは MainController を Create Files... で .h にしたら

newcocoa -c MainController.h

とかやると MainController.rb ができてインスタンス変数 (Outlet) やメソッド (Action) が定義されるので、あとはそれを書くだけ。Cocoa のドキュメントは http://developer.apple.com/cgi-bin/search.pl?q=%s を適当なキーワードで Fx にブクマしておけばぜんぶひっかかる。

気がむいたらスクリーン{ショット,キャスト}付きでまとめたい。てか Mac のスクリーンキャストでいまだに最適解を見つけられてない。VNC を録画ぐらい (でもめんどくてやらない) そういえば VNC で録画して変換したやつをさらん flv にするのはためしてない。

obj-c

obj-c でめんどいのは、Pathname がないのと、文字列処理

RubyCocoa ns_import

http://rubycocoa.sourceforge.net/doc/changes.ja.html を読むむ
フレームワークロード後の ns_import はいらないみたいだ。ステキ

pass-by-reference のルールがよくわからない。

あと使ってみると withString:length: みたいなときに第二引数はいらないと警告がでるけど、これもどういうルールになってるんだろ。

どんどん使いやすくなってるなぁ。

RubyCocoa ML

読もう

trunk をチェックアウトしてみた。branch を最初にチェックアウトしたらアレだった。

tests に run ループに入ってやるテストはないみたいだなぁ。どう書くのがいいんだろ。
osxhotkey のときは Thread と SizedQueue 使って書いたけど ( http://lab.lowreal.net/trac/browser/site-ruby/osxhotkey/test/osxhotkey_test.rb )、うーん。わかりにくい

fork して終了コード見るとかやってみよう

2007年 03月 23日

RubyCocoa で AppleRemote リッスンして Safari のプレゼンツールうごかす

http://rubycocoa.com/appleremote/1 にあるとおりに framework をビルドして配置

require "osx/cocoa"
include OSX
OSX.require_framework "AppleRemote"
OSX.ns_import :AppleRemote

class AppleRemoteDelegate < NSObject

	addRubyMethod_withType('appleRemoteButton:pressedDown:', 'v@:ii')

	def appleRemoteButton_pressedDown(buttonIdentifier, pressedDown)
		puts "button #{buttonIdentifier}, pressed #{pressedDown}"
		return if pressedDown == 0
		case buttonIdentifier
		when 1 # down
			call_safari_js "$presentation.fold($presentation.page);$presentation.scrollTo($presentation.pages[$presentation.page]);"
		when 3, 4 # middle, right
			call_safari_js "$presentation.next();"
		when 5 # left
			call_safari_js "$presentation.prev();"
		end
	end
	
	def call_safari_js(script)
		errinfo = NSDictionary.alloc.init
		NSAppleScript.alloc.initWithSource(<<-EOS).executeAndReturnError(errinfo)
			tell application "Safari"
				do JavaScript "#{script.gsub(/¥n/, ";")}" in document 1
			end tell
		EOS
	end
end


a = AppleRemote.alloc.init
d = AppleRemoteDelegate.alloc.init
a.setDelegate d
a.startListening 0
trap (:INT) { exit }
NSApplication.sharedApplication.run

rbosa で JS 送ろうとおもったけど、in document の書きかたがわからなかったので NSAppleScript を読んでる。一応ストレスなしにうごくっぽい

2007年 03月 22日

RubyCocoa framework のロード

FAQ に書いてあるほうほう (NSBundle#load) 以外に

OSX.require_framework "IOBluetooth"

ってできたんだなぁ。

そういえば、なんも考えないで Ruby Cocoa の最新版入れなおしたけど、シンボルはさんで呼ぶ方法がつかえなくなるんだよなぁ。いままでつくたやつ全部動かない予感。めんどい……

svk push が失敗していた件

http://subtech.g.hatena.ne.jp/cho45/20070222/1172131008
Apache のログを見てみると XML parser error code: not well-formed (invalid token) とか出てた。invalid token がでそうっていうと入力したログメッセージのせいなんじゃないか、とか思って svk smerge -f (-I をつけない) でまとめてコミットしたらいけた。ながいたたかいだった。

2007年 03月 21日

Bluetooth on Cocoa, OS X

ケータイでとった写真を自動でかきあつめて日付別にディレクトリにつっこみたかったので Bluetooth をいぢってみた。

いつものとおり RubyCocoa さん

require "osx/cocoa"
include OSX
NSBundle.bundleWithPath("/System/Library/Frameworks/IOBluetooth.framework").load
OSX.ns_import :IOBluetoothObject
OSX.ns_import :IOBluetoothDevice
OSX.ns_import :IOBluetoothOBEXSession
OSX.ns_import :OBEXFileTransferServices


#NSBundle.bundleWithPath("/System/Library/Frameworks/IOBluetoothUI.framework").load
#OSX.ns_import :IOBluetoothDeviceSelectorController
#p OSX::IOBluetoothDeviceSelectorController.deviceSelector.runModal
#

def log(*args)
	OSX.NSLog(args.map {|o| o.inspect }.join("¥n")+"¥n")
end

class Main < NSObject
	def init
		self
	end

	def applicationDidFinishLaunching(aNotification)
		IOBluetoothDevice.pairedDevices.each do |d|
			log d.getAddressString.to_s
			log d.getName.to_s
			d.getServices.each do |s|
				log s.getServiceName.to_s
			end
		end

		target = "Nyece"
		@device = IOBluetoothDevice.pairedDevices.find {|d| d.getName.to_s == target }
		#@device.openConnection

		@session = IOBluetoothOBEXSession.withDevice_channelID(@device, 10)

		@ftp = OBEXFileTransferServices.alloc.initWithOBEXSession(@session)
		@ftp.setDelegate(self)
		log @ftp.delegate
		log @ftp
		log @ftp.isConnected?
		log @ftp.connectToFTPService
	end

	def fileTransferServicesConnectionComplete_error(service, error)
		log "FTP Connected"
		log @ftp.currentPath
		@ftp.retrieveFolderListing
	end

	def fileTransferServicesRetrieveFolderListingComplete_error_listing(service, error, listing)
		log "ls complete"
		log listing.to_a
		log @ftp.disconnect
		#@device.closeConnection
	end
end

app = OSX::NSApplication.sharedApplication
app.setDelegate(Main.alloc.init)
trap('SIGINT') { exit 0 }
app.run

が、BUS Error ( fileTransferServicesConnectionComplete_error の呼びだしで落ちてる ) うまくいかない。orz
obj-c で書いたほうがはやいだろうなぁ。でもなんかそれは負けた気がする。

わかったこと

  • ファイルのやりとりは OBEX っていう転送プロトコルがつかわれる (IrDA と同じらしい)
  • OBEXFileTransferServices は自分で openConnection しなくても勝手にひらいてくれる
  • ファイルのやりとりいがいはたぶん OBEXSession を直接つかって open & delegate するのかな。

プロトコル調べるのがめんどい。

アプリケーションバンドル化してみたけどやぱ BUS Error で落ちる。むりか。

2007年 03月 20日

同じずれかた

ふいた

gerry

いたい……