itok's Lab

昔の開発ネタを記録として残してます

デフォルトアプリに飛んできたイベントを受け取る

さて、デフォルトアプリとしての設定もでき、任意の scheme に従う URL を受け取ることができるようになったわけですが、ではどうやってそれを受け取ったらいいのか、という話。これには AppleEvent の枠組みを使います。Cocoa でいえば、NSAppleEventManager。(デフォルトアプリ云々というよりは AppleEvent の取り扱い方の話ですね)

// NSAppleEventManager
-(void) setEventHandler:(id)handler
    andSelector:(SEL)handleEventSelector
    forEventClass:(AEEventClass)eventClass
    andEventID:(AEEventID)eventID;

当然ながら handleEventSelector の形は決まっていまして↓こういう感じです。

-(void)handleAppleEvent:(NSAppleEventDescriptor*)event
    withReplyEvent:(NSAppleEventDescriptor*)replyEvent;

また、後半に AE* という見慣れない2つの引数がありますけれど、要はどういったイベントを受け取るのかっていうのを設定することになります。詳しくは後述の例にて。

細かいことはさておき、早速例を見てみましょう。ここでは受け取った URL を表示するだけにしています。

-(void) method
{
...
    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
        andSelector:@selector(handleAppleEvent:withReplyEvent:)
        forEventClass:'GURL'
        andEventID:'GURL'];
...
}

-(void) handleAppleEvent:(NSAppleEventDescriptor*)event
    withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
    NSString* url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
    NSLog(@"%@", url);
}

最後に、登録はどこで行うのがいいのかということについて。AppleEvent は起動していないアプリケーションにも飛んできます。飛んできたらそのアプリケーションは起動するんですが、もちろんのことながら受信メソッドが登録されていないとせっかく起動されても当該のイベントを受け取ることができません。この場合、AppleEvent はアプリケーションが起動したあとにその処理を要求してきますので、起動しきる前に受信メソッドを登録してしまえばいいようです。つまるところ、おなじみ applicationWillFinishLaunching: の中で登録作業を行えば、起動後にめでたく登録した受信メソッドが呼びだされます。もちろん、アプリケーションが動作している間は普通に受け取れます。