17

含まれているアプリを起動したい。

URL スキームを使用してみました。

URL スキームが他の場所からアプリを起動したため、問題はありません。

このオブジェクトは nil のようです:

   self.extensionContext

したがって、このメソッドを実行できません:

[self.extensionContext openURL:url completionHandler:nil];

アプリを起動できますか? URL スキームはカスタム キーボードで機能しますか?

ありがとう!

4

11 に答える 11

15

このコードを試してください

    UIResponder* responder = self;
    while ((responder = [responder nextResponder]) != nil)
    {
        NSLog(@"responder = %@", responder);
        if([responder respondsToSelector:@selector(openURL:)] == YES)
        {
            [responder performSelector:@selector(openURL:) withObject:[NSURL URLWithString:urlString]];
        }
    }
于 2015-04-10T06:22:15.247 に答える
10

私自身の質問に答えるには:

iOS8 カスタム キーボードでは、extensionContext オブジェクトが nil であるため、それを使用して含まれているアプリを起動することはできません。

私が思いついた回避策は次のとおりです。

  1. アプリの URL スキームを作成する
  2. UIWebView を inputView に追加します
  3. 含まれているアプリの URL スキームを webview に読み込みます

Apple がこれを許可するかどうかはわかりませんが、現在は機能しています。

于 2014-07-06T13:18:16.117 に答える
10

これは、キーボード拡張機能の実用的なソリューション (iOS 9.2 でテスト済み)です。このカテゴリは、隠しsharedApplicationオブジェクトにアクセスするための特別なメソッドを追加し、それを呼び出しますopenURL:。(もちろんopenURL:、アプリ スキームでメソッドを使用する必要があります。)

// Usage:
// UIInputViewController.openURL(NSURL(string: "your-app-scheme://")!)
extension UIInputViewController {

    func openURL(url: NSURL) -> Bool {
        do {
            let application = try self.sharedApplication()
            return application.performSelector("openURL:", withObject: url) != nil
        }
        catch {
            return false
        }
    }

    func sharedApplication() throws -> UIApplication {
        var responder: UIResponder? = self
        while responder != nil {
            if let application = responder as? UIApplication {
                return application
            }

            responder = responder?.nextResponder()
        }

        throw NSError(domain: "UIInputViewController+sharedApplication.swift", code: 1, userInfo: nil)
    }

}

最近、私は少し異なるアプローチを開発しました:

// Usage:
// UIApplication.sharedApplication().openURL(NSURL(string: "your-app-scheme://")!)

extension UIApplication {

    public static func sharedApplication() -> UIApplication {
        guard UIApplication.respondsToSelector("sharedApplication") else {
            fatalError("UIApplication.sharedKeyboardApplication(): `UIApplication` does not respond to selector `sharedApplication`.")
        }

        guard let unmanagedSharedApplication = UIApplication.performSelector("sharedApplication") else {
            fatalError("UIApplication.sharedKeyboardApplication(): `UIApplication.sharedApplication()` returned `nil`.")
        }

        guard let sharedApplication = unmanagedSharedApplication.takeUnretainedValue() as? UIApplication else {
            fatalError("UIApplication.sharedKeyboardApplication(): `UIApplication.sharedApplication()` returned not `UIApplication` instance.")
        }

        return sharedApplication
    }

    public func openURL(url: NSURL) -> Bool {
        return self.performSelector("openURL:", withObject: url) != nil
    }

}
于 2015-12-23T00:33:01.270 に答える
2

Apple のドキュメントhttps://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/index.htmlによると、次のように NSExtensionContext を使用する必要があります。

NSExtensionContext *ctx = [[NSExtensionContext alloc] init];
[ctx openURL:[NSURL URLWithString:@"myapp://"] completionHandler:^(BOOL success){return ;}];
于 2014-12-08T13:22:33.093 に答える
1

これは、上記の方法を使用して任意の URL を開くことがわかったものです。

UIWebView * webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
NSString *urlString = @"https://itunes.apple.com/us/app/watuu/id304697459";
NSString * content = [NSString stringWithFormat : @"<head><meta http-equiv='refresh' content='0; URL=%@'></head>", urlString];
[webView loadHTMLString:content baseURL:nil];
[self.view addSubview:webView];
[webView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:2.0];

この場合、UIInputViewController からこの呼び出しをインスタンス化していることに注意してください。

このメソッドは、含まれているアプリの URL スキームを使用しても機能するはずです

注: iOS 8.3 以降、Apple はこのメソッドを削除しました

于 2015-01-20T03:27:20.647 に答える
1

アプリの拡張機能 (例: カスタム キーボード) では、UIViewController.extensionContextiOS 8.1.2 で処理されますが、フィールドはnil次の Swift 呼び出しにあります。

self.extensionContext?.openURL(appURL, completionHandler: nil)
// Does nothing because extensionContext is nil (iOS 8.1)

実際には、 Apple のドキュメントApplication.sharedApplication.openURL(...)に記載されているように、App Extension で使用することもできません。

したがって、8.1.2 の時点での回避策は、次のようにダムUIWebViewを使用して含まれているアプリにリダイレクトすることです。

let webView = UIWebView(frame: CGRectMake(0, 0, 0, 0));
let url = "MyKeyboard://";
let content = "<head><meta http-equiv='refresh' content='0; URL=\(url)'></head>";
webView.loadHTMLString(content, baseURL: nil);
self.view.addSubview(webView);
let delayInSeconds = 2.0
let startTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delayInSeconds * Double(NSEC_PER_SEC)))
dispatch_after(startTime, dispatch_get_main_queue()) { () -> Void in
    webView.removeFromSuperview()
}

含まれているアプリの URL スキームとして、 WhereMyKeyboard://を適切に定義する必要があります。

これが Apple によって承認されているかどうかはまだわからないことに注意してください。カスタム キーボードからのアプリへの転送は、ユーザー エクスペリエンスにとって十分に悪い場合があります。

于 2015-01-25T20:41:02.477 に答える