タイトルAppleScript Working》4 _ AppleScriptからJavaを呼び出す(1)カテゴリーAppleScript, AppleScript Working
作成日2002/2/7 17:17:59作成者新居雅行
   この記事のPDFファイル(650KB)は以下のアドレスにあります。
   ダウンロードには、MDOnlineのアカウントが必要です。
   pdfs/MDOnline020008.pdf
 ‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
AppleScript Studioで作成するアプリケーションは、クラスやあるいはオブジェクトのメソッドを呼び出すという機能が利用できる。AppleScriptに対するインタフェースを特別に定義したわけではないようなクラスを直接呼び出せるのだ。AppleScript Stduioのチュートリアルにも、Objective-Cでの事例が掲載されており、Cocoaのクラスにあるメソッド等を呼び出す方法が書いてある。CocoaだからObjective-Cだけかという雰囲気もあるが、実は、Javaで作ったクラスもAppleScriptから直接呼び出すことができる。これらは、機能拡張の手法に大きな柔軟性を与えるものだ。

――――AppleScriptからのメソッド呼び出し
AppleScript StudioのApplication Suiteには、call methodというコマンドがある。アプリケーションの中なら、そのまま使えるわけだが、用語辞典を日本語におおまかになおすと次のようなものだ。

call method メソッド名
[of class クラス名]
[of object オブジェクト]
[with parameter 引数]
[with parameters 引数のリスト]

つまり、いきなりcall methodコマンドを使えるのだが、クラスないしはオブジェクトの一方を指定し、呼び出すメソッドがあれば、引数あるいは引数リストのいずれか一方を指定することになる。このメソッドを使って、Objective-Cのクラスを呼び出す方法が、以下の文書に掲載されている。

◇More on AppleScript Studio
 http://developer.apple.com/techpubs/macosx/CoreTechnologies/AppleScriptStudio/applescriptstudio/chapter3/More_on_App_ript_Studio.html

Objective-Cの場合はクラスメソッドであれば、クラス名とメソッドを与えればいいが、ウインドウ上のボタンへの参照をオブジェクトとして指定してもかまわないのである。また、自分でソースプログラムを供給したクラスを指定し、そこに定義されているメソッドを呼び出すこともできる。この場合、一般にはクラスメソッドを定義して、そこでさまざまな処理を組み込むことになるだろう。Objective-Cで作成するのが基本となっているが、クラス定義部分はもちろん、Objective-Cでの文法に従う必要があるが、メソッド内の処理ではCの記述も可能であるため、その意味ではToolboxのAPIをそのまま呼び出したり、あるいはCocoaのクラスを利用するということは可能である。
しかしながら、後で説明するように、Objective-Cだけでなく、Javaでも同様にプログラミングはできる。それぞれ長所や短所はあるが、両方できるという点は選択肢の上でも広くなり好ましいことだと言えるだろう。なお、CarbonのAPIを使うにはC言語のAPIであるため、Objective-Cで作る方が何かと楽だろう。一方、JavaだとPure Javaのさまざまなライブラリが使えるという点が大きい。Javaだと実行速度の上では若干不利であるのだが、AppleScript自体の処理スピードのことを考慮すれば、Javaの処理能力低下はほとんど考慮外になることもあるだろう。

――――Objective-Cのクラスを定義して呼び出す
自分で作ったObjective-Cのクラスのメソッドを呼び出す方法をまずは説明しよう。Project Builderで、AppleScript Applicationを選択して作ったプロジェクトがあるとする。そのプロジェクトに、次のようにして、Objective-Cのソースファイルを追加する。まず、「ファイル」メニューから「新規ファイル」(Command+N)を選択する。ダイアログボックスが表示されるので、ここではCocoaのObjective-Cクラスを選択する。

◇新規ファイルでObjective-C Classを選択する
 

すると、クラス名やこのクラスを追加するターゲットを指定するダイアログボックスになる。ここでは、SoundPlay.mというファイルに加えて、ヘッダのファイルも作成し、最初からあるターゲットに追加するように指定した。

◇ファイル名とターゲットを指定する
 

これで、SoundPlay.mとSoundPlay.hという2つのファイルが追加された。ここで、プログラムを追加するが、文字通り、サウンドを鳴らすプログラムを追加したい。システム環境設定の「サウンド」で、警告音の一覧が出るが、これは/System/Library/Soundsおよび~/Library/SoundsにあるAIFFファイル(拡張子は.aiff)の一覧である。NSSoundの機能を使うと、これらのサウンドファイルを、ファイル名を指定するだけで鳴らすことができる。どんな名前でいいのかは、システム環境設定で見る方が確実だろう。
それそれのリストは次のようにした。まず、ヘッダファイルは次の通りだ。

// SoundPlay.h

#import

@interface SoundPlay : NSObject {}

+ (void)playSound;
+ (void)playSound:(NSString *)soundName;
+ (void)playSound:(NSString *)soundName async:(BOOL)isAsync;

@end

ヘッダでは、とりあえず、クラスメソッドのインタフェースを記述する。ここでは、3種類のplaySoundメソッドを定義するが、インポートするヘッダは、初期状態のFoundation.hからCocoa.hにしておくのが何かと便利だろう。
最初のplaySoundは、Templeという名前のサウンドを無条件に鳴らす。2つ目は1つの引数を指定し、その引数にサウンド名を指定して、そのサウンドを鳴らす。3つ目のものは、2つの引数を取り、サウンド名と非同期で鳴らすかどうかを論理値でそれぞれ指定する。2つ目の引数は同期で鳴らすなら、trueを指定する。なお、最初の2つのメソッドはサウンドを非同期で鳴らすため、サウンドを慣らしている最終に次の処理に移動する。
そして、インプリメントを記述するSoundPlay.hは次のようにした。

// SoundPlay.m

#import "SoundPlay.h"


@implementation SoundPlay

+ (void)playSound;
{
NSSound * theSound = [NSSound soundNamed:@"Temple"];
[theSound play];
}
+ (void)playSound:(NSString *)soundName;
{
NSSound * theSound = [NSSound soundNamed:soundName];
[theSound play];
}
+ (void)playSound:(NSString *)soundName async:(BOOL)isAsync;
{
NSSound * theSound;
theSound = [NSSound soundNamed:soundName];
[theSound play];
if(isAsync)
while([theSound isPlaying])
sleep(1);
}

@end

いずれも、NSSoundというクラスにあるクラスメソッド、soundNamedで指定した名前のサウンドのインスタンスを得て、playメソッドで実際に音を鳴らしている。なお、同期で鳴らすために、isPlayingメソッドで鳴らしている途中かどうかを判断しながら、鳴らしている途中であれば、sleepで1秒待って鳴り終わるのを待つというわけだ。
これらのメソッドをAppleScriptで使うプログラムをまず見ていただきたい。

call method "playSound" of class "SoundPlay"
call method "playSound:" of class "SoundPlay" with parameter "Frog"
call method "playSound:async:" of class "SoundPlay" with parameters {"Temple", true}

(この項、続く)
関連リンク