Comment configurer le routage WKWebView pour prendre en charge les Universal Links iOS

opoinstall
2026-10-07
5 min read

Comment activer les Universal Links au sein d'une WKWebView iOS ? Les Universal Links peuvent déjà être résolus à partir de liens éligibles au sein d'une WKWebView. L'implémentation de WKNavigationDelegate permet à l'application hôte de personnaliser les politiques de routage — en interceptant les destinations appartenant à l'application, en contrôlant les handoffs externes via decidePolicyForNavigationAction et en appliquant une sécurité au niveau des frames.

Dans l'architecture d'application iOS, l'interception de navigation WKWebView permet à l'application hôte de personnaliser les politiques de routage entre les Universal Links, les schémas d'URL personnalisés et les destinations web. En évaluant les métadonnées de requête de navigation au sein d'un WKNavigationDelegate, l'application peut router en interne les destinations qu'elle possède, déléguer les cibles externes aux gestionnaires système et appliquer des politiques de sécurité au niveau des frames.

Terme Définition Entité associée Rôle de l'intention de recherche
WebView Composant de vue intégré basé sur WebKit qui affiche du contenu web interactif au sein des applications iOS. SDK iOS Informationnel / Commercial
Universal Links Mécanisme HTTPS standard liant des domaines web vérifiés à des vues d'applications iOS natives. Routage Deep Link Technique / Informationnel
Custom URL Scheme Schéma d'URI défini par l'application, utilisé pour router les URL vers une application native. Deep Linking Mobile Informationnel

Interaction entre WKWebView et le routage Universal Link sur iOS

WKNavigationDelegate décide si WebKit charge, route en interne, délègue ou annule.

Cycles de vie de navigation WebKit et politiques de routage propriétaires

Apple implémente les Universal Links comme un mécanisme de routage au niveau du système, pris en charge dans les environnements Safari et WKWebView. Lorsqu'un utilisateur appuie sur un lien éligible au sein d'une WKWebView intégrée, la plateforme peut résoudre les associations de domaine et router l'exécution selon les politiques du système d'exploitation.

Bien que les Universal Links reconnus par le système puissent déléguer l'exécution à des gestionnaires natifs, les environnements de navigation intégrés nécessitent fréquemment une logique de routage spécifique à l'application. Par exemple, lorsqu'un lien cible le propre domaine de l'application hôte, les développeurs préfèrent souvent naviguer directement via des contrôleurs de vue natifs sans déclencher de relancement externe complet de l'application. L'implémentation de WKNavigationDelegate offre à l'application hôte un contrôle granulaire sur l'évaluation des liens, permettant aux équipes d'appliquer des listes d'autorisation personnalisées et de router les destinations internes de manière prévisible.

L'obstacle à l'expérience utilisateur : quand la navigation web intégrée piège les utilisateurs

Les WebViews intégrées sont souvent déployées pour héberger des microsites promotionnels, des centres d'aide, des catalogues de partenaires et des pages de destination marketing au sein des applications iOS. Lorsqu'une page web intégrée inclut des liens destinés à diriger les utilisateurs vers d'autres sections de l'application hôte (par exemple, les boutons « Voir dans l'application ») ou vers des applications partenaires, la navigation par défaut peut entraîner un rendu redondant :

  • Rendu web redondant : Au lieu d'afficher des contrôleurs de vue natifs, l'utilisateur peut se voir présenter des versions web responsives de pages intégrées, nécessitant des authentifications répétées et dégradant la cohérence visuelle.
  • Piégeage web : Les utilisateurs peuvent se retrouver piégés dans des piles de navigation web complexes sans moyen intuitif de revenir aux interfaces natives principales.
  • Échecs de transitions entre applications : Le fait de cliquer sur des liens pointant vers des services tiers (tels que des applications de navigation, des boîtes de dialogue de partage social ou des passerelles de paiement) nécessite une délégation explicite si ces services reposent sur des schémas d'URL personnalisés.

Comparaison entre WKWebView et SFSafariViewController pour le passage Web-to-App

Lors de la conception de la navigation web intégrée sur iOS, les équipes d'ingénierie doivent choisir entre WKWebView et SFSafariViewController :

  • SFSafariViewController : Fournit une interface de navigation Safari gérée par le système et autonome, avec des fonctionnalités telles que l'auto-remplissage et le blocage de contenu. L'application hôte ne peut pas inspecter l'activité de navigation ou les données du site web, et la personnalisation de l'interface utilisateur se limite aux couleurs de teinte.
  • WKWebView : Un composant de vue intégré hébergé dans le processus UI de l'application tout en exécutant le contenu web dans des processus WebKit distincts. Il permet une personnalisation approfondie de l'interface utilisateur, des ponts JavaScript et une intégration de mise en page personnalisée, nécessitant l'implémentation explicite de WKNavigationDelegate pour personnaliser les politiques de routage et gérer les schémas personnalisés définis par l'application.

Comment decidePolicyForNavigationAction intercepte le routage WebKit

Le pipeline de politique de navigation : comprendre WKNavigationAction, request et decisionHandler

Pour contrôler le flux de navigation à l'intérieur d'une WKWebView, les développeurs attribuent un délégué personnalisé conforme aux conseils d'Apple pour les développeurs sur WKNavigationDelegate. Le point d'interception principal est la méthode de délégué :

func webView(
    _ webView: WKWebView,
    decidePolicyFor navigationAction: WKNavigationAction,
    decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
)

Les actions de navigation déclenchées par des interactions utilisateur, des redirections programmatiques ou des soumissions de formulaires passent par cette méthode. L'objet WKNavigationAction fournit des métadonnées clés :

  • navigationAction.request.url : L'URL cible demandée.
  • navigationAction.navigationType : Le type de déclencheur (.linkActivated, .other, .formSubmitted).
  • navigationAction.sourceFrame : Informations concernant la frame initiant la requête de navigation.
  • navigationAction.targetFrame : Informations concernant la frame de destination où le contenu doit être chargé.

Le decisionHandler est une closure de complétion qui informe WebKit s'il doit autoriser ou annuler la navigation demandée.

Quand retourner .allow vs .cancel : contrôler le cycle de vie du chargement des ressources WebKit

La WKNavigationActionPolicy transmise au decisionHandler contrôle si WebKit poursuit la navigation :

  • .allow : Informe WebKit de poursuivre la navigation demandée au sein de la vue web.
  • .cancel : Demande à WebKit d'annuler la navigation. Cette politique est exécutée chaque fois que l'application hôte intercepte un schéma personnalisé, route un Universal Link interne ou délègue une cible externe à UIApplication.shared.open().

Le decisionHandler doit être invoqué exactement une fois par action de navigation pour garantir que la résolution de la politique se déroule sans blocage.

Évaluation des types de navigation : distinguer les clics utilisateur (.linkActivated) des redirections automatisées

WKNavigationAction.navigationType permet aux développeurs de distinguer les interactions explicites de l'utilisateur des scripts automatisés :

  • .linkActivated : L'utilisateur a physiquement cliqué sur une balise d'ancrage HTML (<a href="...">).
  • .other : Représente les navigations programmatiques, telles que les mises à jour de window.location.href, les meta-refresh ou les appels webView.load() initiaux.
  • .formSubmitted / .formResubmitted : Représente les soumissions de formulaires POST ou GET.

L'évaluation du navigationType permet aux applications d'appliquer une politique de lien explicite et conservatrice au niveau de l'application. Pour les invocations de schémas personnalisés externes ou les transitions vers des applications tierces, exiger .linkActivated comme porte de politique aide à empêcher les scripts d'arrière-plan non sollicités de déclencher des lancements automatiques d'applications externes.

Gestion des politiques de décision asynchrones sans cycles de rétention

Lorsque la validation du routage ou les vérifications d'autorisation nécessitent d'interroger des caches locaux ou des validateurs de sécurité avant de renvoyer une décision :

  1. Assurez-vous que le decisionHandler est exécuté sur tous les chemins d'exécution, y compris les conditions d'erreur et de garde.
  2. Utilisez des références faibles ([weak self]) au sein des closures pour éviter les cycles de rétention entre la WKWebView, son délégué et le UIViewController parent.

Différencier les domaines associés de l'application des Universal Links externes

Les Universal Links appartenant à l'application doivent valider et router en interne depuis la WKWebView.

Gestion des destinations propriétaires vs délégation de lien au niveau système

Pour les routes appartenant à l'application, évitez de tenter de rentrer dans la même application via une recherche d'Universal Link redondante. Gérez les destinations propriétaires directement via le routeur interne de l'application hôte, et utilisez l'ouverture système principalement pour les destinations qui doivent quitter l'application actuelle ou être résolues par des services externes.

Cette séparation architecturale garantit une navigation fluide :

  • Domaines associés à l'application hôte : Si l'hôte de l'URL correspond au domaine associé de l'application hôte (app.example.com), annulez la navigation de la vue web (decisionHandler(.cancel)), validez le chemin de la route et transmettez les paramètres analysés directement au routeur de navigation interne de l'application.
  • Applications externes : Si l'URL pointe vers une destination partenaire externe ou un schéma personnalisé autorisé, appliquez un verrou de lien explicite au niveau de l'application (navigationType == .linkActivated), annulez la navigation de la vue web et transmettez la requête à UIApplication.shared.open(url) pour permettre au système d'exploitation de lancer l'application externe.

Conception de la validation de routage interne : extraction des chemins et paramètres via AppRouteValidator

Lorsqu'une URL entrante correspond au domaine associé de l'application hôte, la chaîne d'URL doit passer par un validateur de routage strict avant de déclencher des transitions de contrôleur de vue.

Le modèle AppRouteValidator :

  • Valide le chemin de l'URL par rapport à une liste d'autorisation de routes internes prises en charge (par exemple, /open/, /product/, /promo/, /checkout/).
  • Extrait les paramètres de requête (par exemple, id, promo, utm_source).
  • Applique des restrictions sur le jeu de caractères, les limites de longueur et le rejet des clés en double, renvoyant une structure de données ValidatedAppRoute propre.

Gestion des Universal Links tiers externes via la délégation UIApplication système

Les Universal Links externes peuvent tenter un handoff natif et retomber sur le web.

Lorsqu'une page web à l'intérieur d'une WKWebView renvoie vers des services externes (tels que des applications partenaires, des plateformes sociales ou des utilitaires externes), l'application hôte peut déléguer le routage au système iOS :

let options: [UIApplication.OpenExternalURLOptionsKey: Any] = [
    .universalLinksOnly: true
]
UIApplication.shared.open(url, options: options) { success in
    if !success {
        // Fallback de politique d'application : charger la destination web si aucune application native ne gère l'Universal Link
    }
}

L'utilisation de .universalLinksOnly comme politique d'application garantit que l'utilisateur n'est transféré hors de l'application actuelle que si une application native vérifiée est installée pour gérer l'Universal Link.

Gestion des fallbacks de schémas d'URL personnalisés (myapp://) avec les Universal Links HTTPS

Bien que les Universal Links HTTPS représentent le deep linking standard sur iOS, les schémas personnalisés définis par l'application (myapp:// ou partnerapp://) restent courants dans les campagnes promotionnelles et les intégrations de partenaires.

Dans une implémentation WKNavigationDelegate unifiée :

  • Les schémas non-HTTP/HTTPS sont inspectés en premier. Si le schéma correspond à un protocole personnalisé autorisé et satisfait la politique de lien explicite (navigationType == .linkActivated), le délégué vérifie l'hôte, le chemin et les paramètres avant de transmettre à UIApplication.shared.open().
  • Les schémas non reconnus ou les invocations de schémas en arrière-plan non sollicitées sont immédiatement annulés, empêchant les erreurs de navigation non gérées ou l'inondation d'intentions pilotée par script.
[L'utilisateur interagit avec un lien dans une WKWebView iOS]
                       │
                       ▼
[WKNavigationDelegate: decidePolicyForNavigationAction]
                       │
         ┌─────────────┴─────────────┐
         ▼                           ▼
[!action.sourceFrame.isMainFrame] [action.sourceFrame.isMainFrame]
         │                           │
         ▼                           ▼
[Sécurité sous-frame]          [Inspecter schéma & hôte destination]
├─ HTTP(S) -> .allow                 │
└─ Non-Web -> .cancel    ┌───────────┼───────────┐
   (Supprimer frame)     ▼           ▼           ▼
                   [Domaine hôte] [Web externe] [Schéma perso]
                         │           │           │
                         ▼           ▼           ▼
                   [AppRoute]    [Vérifier lien] [Vérifier lien]
                   ├─ Valide ->  ├─ Partenaire->  ├─ Valide & Clic->
                   │  Interne    │  Ouvrir app   │  Ouvrir app
                   └─ Invalide-> └─ Web ->       └─ Invalide/Auto->
                      .cancel       .allow          .cancel

Comment appliquer la sécurité de la frame principale et prévenir le détournement d'iframe

L'origine de la frame WKNavigationAction et le contexte cible déterminent la politique de navigation sécurisée.

Traiter la navigation web intégrée comme une entrée non fiable : normes de sécurité OWASP pour les deep links

Conformément au guide OWASP sur les deep links non sécurisés, toutes les URL et charges utiles de paramètres traitées par les gestionnaires de navigation mobiles doivent être traitées comme des entrées externes non fiables.

Les pages web affichées dans une WKWebView peuvent charger des scripts tiers, des bannières publicitaires ou du contenu généré par les utilisateurs. Si un délégué de navigation transmet des URL arbitraires à des contrôleurs de vue natifs ou à UIApplication.shared.open() sans validation, des paramètres inattendus pourraient cibler des routes d'application internes sensibles.

Isoler les navigations de frame principale des iframes intégrés et des cibles de nouvelle fenêtre

Conformément à la documentation développeur Apple sur WKNavigationAction, l'évaluation de la sécurité des frames nécessite de vérifier la frame initiatrice :

  • sourceFrame.isMainFrame == true : La navigation a été initiée directement par la frame principale du document de premier niveau.
  • sourceFrame.isMainFrame == false : La navigation a été initiée par une sous-frame ou un iframe intégré.
  • targetFrame == nil : La navigation demande une cible de nouvelle fenêtre (comme une ancre avec target="_blank").

Pour éviter le détournement d'iframe — où un iframe intégré tente de lancer des applications externes ou de déclencher des transitions de vue natives en arrière-plan — le délégué doit évaluer sourceFrame.isMainFrame. Si la frame initiatrice est un iframe (sourceFrame.isMainFrame == false), autorisez la navigation standard HTTP/HTTPS des sous-frames (.allow), mais bloquez tous les schémas personnalisés non-web ou les handoffs de routage natif (.cancel).

Prévenir les invocations de protocoles malveillants dans les sous-frames et l'inondation de schémas en arrière-plan

L'application de vérifications sur la frame initiatrice empêche les sous-frames de déclencher des invocations de schémas externes non sollicitées :

if !navigationAction.sourceFrame.isMainFrame {
    let scheme = url.scheme?.lowercased() ?? ""
    if scheme == "http" || scheme == "https" {
        decisionHandler(.allow) // Autoriser la navigation standard HTTP(S) des sous-frames
    } else {
        decisionHandler(.cancel) // Supprimer les schémas non-web des sous-frames
    }
    return
}

Appliquer des listes d'autorisation strictes pour les chemins et paramètres dans le routage client

Les URL de domaine associé internes et les schémas personnalisés externes doivent passer par des modèles de validation stricts avant exécution :

  • Liste d'autorisation des préfixes de chemin : Appliquez des préfixes de route approuvés (par exemple, /open/, /product/, /promo/, /checkout/), rejetant les chemins arbitraires ou malformés.
  • Filtrage des clés de requête : Écartez les clés de requête inattendues et rejetez les clés de paramètres en double pour empêcher la pollution des paramètres.
  • Contraintes de type de données et de longueur : Restreignez les valeurs des paramètres aux jeux de caractères alphanumériques et imposez des limites de longueur maximale (≤64\le 64 caractères).

Implémentation de WKNavigationDelegate en production avec Swift

Structurer l'architecture CustomWebViewController et le délégué en Swift

Un contrôleur WKWebView de production coordonne la configuration web, l'évaluation de la politique de navigation, le routage interne et la délégation externe. L'implémentation encapsule les règles de validation dans des classes de validation dédiées (AppRouteValidator et CustomSchemeValidator) pour garder les callbacks de délégué propres, testables et sécurisés.

Implémentation des modèles AppRouteValidator et CustomSchemeValidator

Les modèles de validation appliquent une sécurité stricte « fail-closed » :

  • AppRouteValidator valide les domaines associés internes, vérifiant les préfixes de chemin et assainissant les paramètres de requête en un objet ValidatedAppRoute structuré.
  • CustomSchemeValidator vérifie les schémas personnalisés autorisés (myapp), valide les hôtes autorisés (open, product, event) et assainit les valeurs de requête.

OpoInstall peut être intégré parallèlement à une couche de routage appartenant à l'application pour l'attribution et la récupération différée des paramètres. Consultez la documentation d'intégration du SDK pour des guides complets.

L'implémentation technique ci-dessous démontre comment configurer un WKNavigationDelegate sécurisé en Swift :

// iOS : CustomWebViewController avec routage WKNavigationDelegate strict et sécurité des frames
// Exemple d'intégration de référence. Vérifiez les signatures de méthodes et les mappages de domaine par rapport à votre architecture déployée.
import UIKit
import WebKit

struct ValidatedAppRoute {
    let path: String
    let queryParams: [String: String]
}

// 1. Validateur pour le domaine associé de l'application hôte (routes internes)
class AppRouteValidator {
    private static let allowedPrefixes = ["/open/", "/product/", "/promo/", "/checkout/"]
    private static let allowedQueryKeys = Set(["target", "id", "promo", "utm_source"])

    static func validate(url: URL) -> ValidatedAppRoute? {
        let path = url.path
        // Appliquer la liste d'autorisation des préfixes de chemin approuvés
        guard allowedPrefixes.contains(where: { path.hasPrefix($0) }) else {
            return nil
        }

        var sanitizedParams: [String: String] = [:]
        var seenKeys = Set<String>()

        if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
           let queryItems = components.queryItems {
            let validChars = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-")
            
            for item in queryItems {
                // Validation fail-closed : rejeter l'URL si des clés non autorisées ou des clés en double existent
                guard allowedQueryKeys.contains(item.name), !seenKeys.contains(item.name) else { return nil }
                seenKeys.insert(item.name)

                let value = item.value ?? ""
                if value.count <= 64 && value.rangeOfCharacter(from: validChars.inverted) == nil {
                    sanitizedParams[item.name] = value
                } else {
                    return nil
                }
            }
        }

        return ValidatedAppRoute(path: path, queryParams: sanitizedParams)
    }
}

// 2. Validateur pour les schémas personnalisés externes (myapp://)
class CustomSchemeValidator {
    private static let allowedSchemes = Set(["myapp"])
    private static let allowedHosts = Set(["open", "product", "event"])
    private static let allowedPathPrefixes = ["/detail/", "/view/", "/main/"]
    private static let allowedQueryKeys = Set(["target", "id", "promo", "utm_source"])

    static func validate(url: URL) -> URL? {
        guard let scheme = url.scheme?.lowercased(), allowedSchemes.contains(scheme) else {
            return nil
        }
        guard let host = url.host?.lowercased(), allowedHosts.contains(host) else {
            return nil
        }

        let path = url.path
        if !path.isEmpty && !allowedPathPrefixes.contains(where: { path.hasPrefix($0) }) {
            return nil
        }

        var seenKeys = Set<String>()
        if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
           let queryItems = components.queryItems {
            let validChars = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-")
            for item in queryItems {
                guard allowedQueryKeys.contains(item.name), !seenKeys.contains(item.name) else { return nil }
                seenKeys.insert(item.name)

                let value = item.value ?? ""
                if value.count > 64 || value.rangeOfCharacter(from: validChars.inverted) != nil {
                    return nil
                }
            }
        }

        return url
    }
}

// 3. UIViewController hébergeant WKWebView avec interception sécurisée de la politique de navigation
class CustomWebViewController: UIViewController, WKNavigationDelegate {

    var webView: WKWebView!
    private let hostAssociatedDomain = "app.example.com"
    private let allowedExternalPartnerHosts = Set(["partner.example.com"])

    override func viewDidLoad() {
        super.viewDidLoad()

        let configuration = WKWebViewConfiguration()
        webView = WKWebView(frame: view.bounds, configuration: configuration)
        webView.navigationDelegate = self
        view.addSubview(webView)
    }

    func webView(
        _ webView: WKWebView,
        decidePolicyFor navigationAction: WKNavigationAction,
        decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
    ) {
        guard let url = navigationAction.request.url else {
            decisionHandler(.allow)
            return
        }

        // Sécurité 1 : Appliquer la limite de frame initiatrice (sourceFrame) pour éviter le détournement d'iframe
        if !navigationAction.sourceFrame.isMainFrame {
            let scheme = url.scheme?.lowercased() ?? ""
            if scheme == "http" || scheme == "https" {
                decisionHandler(.allow) // Autoriser la navigation standard HTTP(S) des sous-frames
            } else {
                decisionHandler(.cancel) // Supprimer les schémas non-web des sous-frames/iframes
            }
            return
        }

        let scheme = url.scheme?.lowercased() ?? ""
        let isExplicitLinkActivation = (navigationAction.navigationType == .linkActivated)

        // Sécurité 2 : Gérer le domaine associé de l'application hôte
        // Router en interne au lieu d'appeler UIApplication.shared.open
        if scheme == "https", let host = url.host?.lowercased(), host == hostAssociatedDomain {
            if let validatedRoute = AppRouteValidator.validate(url: url) {
                AppInternalRouter.shared.navigate(to: validatedRoute)
            }
            decisionHandler(.cancel) // Annuler le chargement dans la webview pour router en interne
            return
        }

        // Sécurité 3 : Gérer les schémas personnalisés autorisés (myapp://) avec la politique d'activation de lien
        if scheme != "http" && scheme != "https" && scheme != "about" {
            // Exiger que les lancements d'applications externes via schéma personnalisé nécessitent une activation de lien explicite
            if isExplicitLinkActivation, let validatedURL = CustomSchemeValidator.validate(url: url) {
                UIApplication.shared.open(validatedURL, options: [:], completionHandler: nil)
            }
            decisionHandler(.cancel) // Annuler le chargement dans la webview pour éviter les erreurs de schéma non gérées
            return
        }

        // Sécurité 4 : Gérer les destinations externes et les requêtes de nouvelle fenêtre (target="_blank")
        if scheme == "http" || scheme == "https" {
            let host = url.host?.lowercased() ?? ""
            
            // Déléguer les Universal Links partenaires vérifiés vers l'application externe avec politique de lien explicite
            if allowedExternalPartnerHosts.contains(host) && isExplicitLinkActivation {
                let options: [UIApplication.OpenExternalURLOptionsKey: Any] = [
                    .universalLinksOnly: true
                ]
                UIApplication.shared.open(url, options: options) { [weak self] success in
                    if !success {
                        // Fallback : charger la destination partenaire externe dans la webview si aucune application native ne la gère
                        guard let self = self else { return }
                        self.webView.load(navigationAction.request)
                    }
                }
                decisionHandler(.cancel)
                return
            }

            // Si targetFrame est nil (requête de nouvelle fenêtre), charger en toute sécurité dans la webView actuelle
            if navigationAction.targetFrame == nil {
                webView.load(navigationAction.request)
                decisionHandler(.cancel)
                return
            }

            // Le contenu web standard continue de se charger dans WKWebView
            decisionHandler(.allow)
            return
        }

        decisionHandler(.allow)
    }
}

// Placeholder de routeur interne spécifique à l'application (ce n'est pas une API SDK OpoInstall)
class AppInternalRouter {
    static let shared = AppInternalRouter()

    func navigate(to route: ValidatedAppRoute) {
        // Exécuter la transition du contrôleur de vue interne basée sur le chemin et les paramètres
    }
}

Exécution thread-safe : assurer que les transitions UI s'exécutent sur l'acteur principal

Dans les modèles de concurrence Swift actuels, les callbacks de WKNavigationDelegate sont isolés sur l'acteur principal (main-actor). Le routage de l'application et les transitions de contrôleur de vue s'exécutent sur l'acteur principal, maintenant la sécurité des threads à travers les flux de navigation natifs.

Erreurs de navigation Deep Link dans WKWebView et matrice de diagnostic

Guide complet de dépannage du deep linking dans WKWebView iOS

La matrice ci-dessous décrit les modes de défaillance courants rencontrés lors de la gestion des deep links et des schémas personnalisés dans une WKWebView iOS, ainsi que leurs causes profondes et les remédiations d'ingénierie recommandées :

Signature d'erreur / Symptôme Cause profonde principale Versions iOS applicables Point de diagnostic Remédiation recommandée
L'Universal Link se charge dans le Web Domaine propriétaire non intercepté iOS 9+ decidePolicyForNavigationAction non géré Intercepter le domaine hôte, analyser le chemin, router en interne, .cancel
Le lien vers le domaine propre ne route pas Appel de UIApplication.open sur son propre domaine iOS 9+ UIApplication.shared.open appelé sur son propre hôte Éviter l'ouverture externe sur soi-même ; router directement vers le routeur interne
Le schéma personnalisé échoue silencieusement Protocole non-HTTP non reconnu par WebKit iOS 9+ Schéma non délégué à UIApplication Intercepter le schéma dans le délégué, valider la liste d'autorisation, ouvrir via UIApplication
Détournement de protocole Iframe Sous-frame déclenchant un schéma externe iOS 9+ sourceFrame.isMainFrame non vérifié Sécuriser avec if !sourceFrame.isMainFrame et supprimer les schémas non-web
Avertissement ou problème de transition UI Transitions UI exécutées hors thread principal iOS 9+ Dispatch manquant vers l'acteur principal Assurer l'exécution sur l'acteur principal pour le routeur interne et les transitions de vue

Foire aux questions (FAQ)

Comment les développeurs peuvent-ils intercepter les Universal Links dans une WKWebView ?
Les développeurs implémentent `WKNavigationDelegate` et inspectent les URL entrantes dans `decidePolicyForNavigationAction`. Si l'URL correspond à une destination appartenant à l'application, le délégué annule la navigation dans la webview avec `.cancel` et transmet les paramètres validés directement au routeur interne de l'application.
Puis-je utiliser UIApplication.shared.open pour lancer ma propre application depuis une WKWebView ?
La documentation Apple précise qu'appeler `UIApplication.shared.open()` sur un Universal Link pointant vers le domaine associé de l'application hôte n'ouvrira pas le lien dans l'application en tant qu'Universal Link. Pour les liens du domaine propre, l'application doit annuler la navigation de la webview et appeler directement son routeur de navigation interne.
Comment puis-je empêcher les iframes intégrés dans une WKWebView de déclencher des lancements d'applications externes ?
Pour prévenir le détournement d'iframe, vérifiez `navigationAction.sourceFrame.isMainFrame` dans `decidePolicyForNavigationAction`. Si `isMainFrame` est `false`, autorisez la navigation standard HTTP(S) des sous-frames avec `.allow`, mais annulez les schémas personnalisés non-web avec `.cancel` pour empêcher les iframes tiers d'exécuter des lancements externes non sollicités.

Résumé et cadre de décision

La gestion des Universal Links et des schémas personnalisés dans une WKWebView iOS nécessite de faire le pont entre le conteneur de rendu web de WebKit et les cycles de vie de navigation UIKit natifs. Se reposer sur les politiques de navigation par défaut peut empêcher une expérience fluide lorsque la logique de routage appartenant à l'application est requise.

En implémentant un WKNavigationDelegate robuste qui vérifie les limites de frame, applique des politiques d'activation de lien conservatrices sur les handoffs externes, analyse les domaines associés internes via des validateurs de route stricts et délègue les cibles externes en toute sécurité à UIApplication.shared.open, les équipes d'ingénierie maintiennent une navigation contrôlée tout en se protégeant contre le détournement de protocole iframe.

Pour explorer les architectures de routage de paramètres et de deep linking iOS natif, consultez la documentation d'intégration du SDK.

Matériaux associés

Share this article