web-dev-qa-db-ja.com

ユニバーサルリンクでSFSafariViewController、WKWebView、またはUIWebViewを使用できるのはいつですか?

iOSアプリ検索プログラミングガイドユニバーサルリンク セクションで、Appleは次のように述べています:

SFSafariViewController、WKWebView、またはUIWebViewオブジェクトをインスタンス化してユニバーサルリンクを処理する場合、iOSはアプリを開く代わりにSafariでWebサイトを開きます。ただし、ユーザーが埋め込みSFSafariViewController、WKWebView、またはUIWebViewオブジェクト内からユニバーサルリンクをタップすると、iOSはアプリを開きます。

「ユニバーサルリンクを処理する」とはどういう意味ですか?指定されたURLをSFSafariViewControllerWKWebView、またはUIWebViewで開くことはできませんか? -[UIApplicationDelegate application:continueUserActivity:restorationHandler:]の間にのみ適用されますか、それともタイムアウトが発生しますか?これは、URLをSFSafariViewControllerWKWebView、またはUIWebViewで開くことができないことを意味しますか?

21
Heath Borders

私はあなたの質問を完全に理解しているかどうかわかりません。

基本をカバーするために、Appleで説明することを許可します ユニバーサルリンクとは

ユニバーサルリンクを使用すると、ユーザーは、メール、メッセージ、その他のアプリで発生するようなopenURL:の呼び出しにつながるリンクに加えて、WKWebViewおよびUIWebViewビューとSafariページ内のWebサイトへのリンクをタップしたときにアプリを開くことができます。

つまり、基本的に、Twitterクライアントで作業していて、タイムラインを通過すると、次のYouTubeビデオリンクを含むツイートが表示されると想像してください。 https://youtu.be/ejQod8liXm

これをタップすると、HTTP URLであるため、Safariがリンクを開くことが期待されます。ただし、すべてのiOS開発者は、ネイティブアプリの方が優れているという事実にほぼ同意できると思います。したがって、サードパーティのクライアントからでも、ビデオを開くための公式YouTubeアプリ

これが「ユニバーサルリンク」で許可されていることです。 YouTubeアプリがiOS上でリンクの処理を担当するアプリとして登録されている場合 https://www.youtube.com (*)リンク、iOSエコシステムのすべての人にメリットがありますAPIルールに従っている場合。ウェブサイトを運営していて、ユーザーがインストールしている場合に公式iOSアプリを開くようにコンテンツのいずれかをトリガーする場合、またはより良いユーザーのためにインストールするかどうかをユーザーに確認する場合も、同じことが起こります。経験(そしてもちろんあなたのビジネスを助けるために)。

それで、これらすべてが邪魔にならないように、元のテキストに戻りましょう:

SFSafariViewController、WKWebView、またはUIWebViewオブジェクトをインスタンス化してユニバーサルリンクを処理する場合、iOSはアプリを開く代わりにSafariでWebサイトを開きます。ただし、ユーザーが埋め込みSFSafariViewController、WKWebView、またはUIWebViewオブジェクト内からユニバーサルリンクをタップすると、iOSはアプリを開きます。

これが意味するのは、アプリからユーザーがコンテンツへのユニバーサルリンクをタップした場合(例: http://www.your-company.com/foo )、ユーザーはタップしないということです。たとえば、正規表現を介してアプリのコードでこれを検出し、代わりにSFSafariViewControllerWKWebView、またはUIWebViewをインスタンス化して、-への通常のリンクであるかのように開きます。 The New York Times または何か、OSは、アプリでこれを開く代わりに、Safariにこれを処理させたいRemember:Universal Linksの全体的な目的は、ユーザーがURLをブラウザーではなく、ネイティブアプリで処理することでエクスペリエンスを向上させることです。 。

これは最初の文が言うことです。 2つ目は、潜在的なフォローアップの質問を明らかにします。ユーザーが、私のコンテンツではない別のアプリから、埋め込みブラウザーから私のコンテンツへのユニバーサルリンクをタップした場合はどうなりますか?次に、OSは正常に動作します。つまり、ユニバーサルリンクのルールに従ってアプリを開きます。

TL; DR:アプリからコンテンツへのユニバーサルリンクもコードで検出し、処理する必要があります。 iOSはこれを処理しません。代わりに、アプリから埋め込みブラウザでアプリのコンテンツへのユニバーサルリンクを開くようにOSに指示すると、指示どおりに機能します。

EDIT:SFSafariViewControllerまたは-openURL:options:completitionHandler: AP​​IにURLを開くように依頼するかどうかを決定するのに助けが必要な場合は、 このリンクはあなたを助けるはずです ; 最初に-openURL:options:completitionHandler:を使用し、成功しない場合はSFSafariViewControllerまたは同様のものを使用することをお勧めします。

これがお役に立てば幸いです。あなたの質問を正しく理解しました。

乾杯!そして、ハッピーiOS 11プログラミング! :)

7
dinesharjani

この問題は、以下のSwift 4クラスで解決しました。可能であれば、組み込みのSafariブラウザも使用します。あなたの場合も同様の方法に従うことができます。

import UIKit
import SafariServices

class OpenLink {
    static func inAnyNativeWay(url: URL, dontPreferEmbeddedBrowser: Bool = false) { // OPEN AS UNIVERSAL LINK IF EXISTS else : EMBEDDED or EXTERNAL
        if #available(iOS 10.0, *) {
            // Try to open with owner universal link app
            UIApplication.shared.open(url, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : true]) { (success) in
                if !success {
                    if dontPreferEmbeddedBrowser {
                        withRegularWay(url: url)
                    } else {
                        inAnyNativeBrowser(url: url)
                    }
                }
            }
        } else {
            if dontPreferEmbeddedBrowser {
                withRegularWay(url: url)
            } else {
                inAnyNativeBrowser(url: url)
            }
        }
    }
    private static func isItOkayToOpenUrlInSafariController(url: URL) -> Bool {
        return url.Host != nil && (url.scheme == "http" || url.scheme == "https") //url.Host!.contains("Twitter.com") == false
    }
    static func inAnyNativeBrowser(url: URL) { // EMBEDDED or EXTERNAL BROWSER
        if isItOkayToOpenUrlInSafariController(url: url) {
            inEmbeddedSafariController(url: url)
        } else {
            withRegularWay(url: url)
        }
    }
    static func inEmbeddedSafariController(url: URL) { // EMBEDDED BROWSER ONLY
        let vc = SFSafariViewController(url: url, entersReaderIfAvailable: false)
        if #available(iOS 11.0, *) {
            vc.dismissButtonStyle = SFSafariViewController.DismissButtonStyle.close
        }
        mainViewControllerReference.present(vc, animated: true)
    }
    static func withRegularWay(url: URL) { // EXTERNAL BROWSER ONLY
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [UIApplication.OpenExternalURLOptionsKey(rawValue: "no"):"options"]) { (good) in
                if !good {
                    Logger.log(text: "There is no application on your device to open this link.")
                }
            }
        } else {
            UIApplication.shared.openURL(url)
        }
    }
}
4
Salih