iOS WKWebView拦截URL scheme时decisionHandler传.allow与.cancel的区别
WKWebView 中 decisionHandler 两种传值的区别
首先明确:decisionHandler 是 WKNavigationDelegate 导航策略回调的入参,作用是告知 WebKit 内核,当前触发的导航请求是否允许 WebView 本身执行后续的加载/跳转逻辑,和你主动调用的 UIApplication.shared.open 没有直接关联,二者是独立逻辑。
你代码中两种传值的差异如下:
- 当调用
decisionHandler(.allow)时
相当于允许 WKWebView 继续处理本次原始的导航请求。在你的 tel/sms/itms-services 分支中,你已经主动调用系统能力打开了对应链接,此时再传.allow,WebView 会按照默认逻辑再次尝试处理这类系统级 scheme,本质是冗余操作,虽然系统大概率会对重复的跳转请求做去重,用户无感知,但不符合规范,极端场景下可能出现重复弹窗的问题。 - 当调用
decisionHandler(.cancel)时
相当于告知 WKWebView 终止处理本次原始的导航请求。在你的自定义 mailto 分支中,你没有处理原始的 mailto 链接,而是跳转了自定义的内部协议ncsone://mail/write,此时传.cancel可以避免 WebView 按照默认逻辑唤起系统邮件App,和你的自定义跳转逻辑冲突,是正确的写法。
优化建议
你两个分支都已经主动处理了跳转逻辑,不需要 WebView 再做额外处理,因此第一个分支也建议改为传 decisionHandler(.cancel),避免冗余操作。
你当前的代码示例:
if scheme == "tel" || scheme == "sms" || scheme == "itms-services" { UIApplication.shared.open(destinationUrl) decisionHandler(.allow) // 这里建议改为.cancel return } else if scheme == "mailto" { UIApplication.shared.open(URL(string: "ncsone://mail/write")) decisionHandler(.cancel) return }
内容的提问来源于stack exchange,提问作者Pie Lee
相关产品推荐
相关产品推荐

