web-dev-qa-db-ja.com

デフォルトのURLスキームで処理する方法

アプリでURI(またはURLスキーム)サポートを構築したい。

LSSetDefaultHandlerForURLScheme()+ (void)initializeを実行し、info.plistでも特定のURLスキームを設定しました。だから私はApple ScriptまたはApple EventsのないURLスキームを持っています。

お気に入りのブラウザでmyScheme:を呼び出すと、システムがアプリをアクティブにします。

問題は、呼び出されたときにスキームをどのように処理するかです。または、より適切に言うと、myScheme:が呼び出されたときに、アプリが何をすべきかをどのように定義できますか。

実装しなければならない特別なメソッドはありますか、それともどこかに登録する必要がありますか?

25
papr

AppleScriptについておっしゃっていますが、Mac OSXで作業していると思います。

カスタムURLスキームを登録して使用する簡単な方法は、.plistでスキームを定義することです。

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>URLHandlerTestApp</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>urlHandlerTestApp</string>
        </array>
    </dict>
</array>

スキームを登録するには、これをAppDelegateの初期化に入れます。

[[NSAppleEventManager sharedAppleEventManager]
    setEventHandler:self
        andSelector:@selector(handleURLEvent:withReplyEvent:)
      forEventClass:kInternetEventClass
         andEventID:kAEGetURL];

アプリケーションがURLスキームを介してアクティブ化されるたびに、定義されたセレクターが呼び出されます。

URL文字列を取得する方法を示すイベント処理メソッドのスタブ:

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

Appleのドキュメント: Get URLハンドラーのインストール

UpdateapplicationDidFinishLaunching:にイベントハンドラーをインストールするサンドボックス化されたアプリの問題に気づきました。サンドボックスを有効にすると、カスタムスキームを使用するURLをクリックしてアプリを起動したときに、ハンドラーメソッドが呼び出されません。少し前にハンドラーをapplicationWillFinishLaunching:にインストールすると、メソッドは期待どおりに呼び出されます。

- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
    [[NSAppleEventManager sharedAppleEventManager]
        setEventHandler:self
            andSelector:@selector(handleURLEvent:withReplyEvent:)
          forEventClass:kInternetEventClass
             andEventID:kAEGetURL];
}

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

IPhoneで、URLスキームのアクティブ化を処理する最も簡単な方法は、UIApplicationDelegateのapplication:handleOpenURL: -- Documentation を実装することです。

72

すべてのクレジットはweichselおよびkchに移動する必要があります

私はあなたの便宜のためにSwift(2.2/3.0)コードを追加しています

func applicationWillFinishLaunching(_ notification: Notification) {
    NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleGetURL(event:reply:)), forEventClass: UInt32(kInternetEventClass), andEventID: UInt32(kAEGetURL) )
}

func handleGetURL(event: NSAppleEventDescriptor, reply:NSAppleEventDescriptor) {
    if let urlString = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue {
        print("got urlString \(urlString)")
    }
}
9
Laimis

問題は、呼び出されたときにスキームをどのように処理するかです。

そこで、Appleイベントが発生します。LaunchServicesがアプリにURLを開くように要求すると、アプリにkInternetEventClass/kAEGetURLイベントが送信されます。

Cocoaスクリプティングガイド 使用 イベントハンドラーのインストールの例としてのこのタスク

6
Peter Hosey

スクリプト用語SDEFで「getURL」コマンドを定義し、対応するメソッドを実装できます。たとえば、ターミナルのSDEFには、URLを処理するための次のコマンド定義が含まれています

<command name="get URL" code="GURLGURL" description="Open a command an ssh, telnet, or x-man-page URL." hidden="yes">
    <direct-parameter type="text" description="The URL to open." />
</command>

そして、アプリケーションがそれに応答することを宣言します。

<class name="application" code="capp" description="The application's top-level scripting object.">
    <cocoa class="TTApplication"/>
    <responds-to command="get URL">
        <cocoa method="handleGetURLScriptCommand:" />
    </responds-to>
</class>

TTApplicationクラス(NSApplicationのサブクラス)は、メソッドを定義します。

- (void)handleGetURLScriptCommand:(NSScriptCommand *)command { … }
0
Chris Page

わずかに異なるSwift 4/5バージョンのコードを追加しています:

func applicationWillFinishLaunching(_ notification: Notification) {
    NSAppleEventManager
        .shared()
        .setEventHandler(
            self,
            andSelector: #selector(handleURL(event:reply:)),
            forEventClass: AEEventClass(kInternetEventClass),
            andEventID: AEEventID(kAEGetURL)
        )

}

@objc func handleURL(event: NSAppleEventDescriptor, reply: NSAppleEventDescriptor) {
    if let path = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue?.removingPercentEncoding {
        NSLog("Opened URL: \(path)")
    }
}
0
Martin Pilch