如果您的应用使用 WKWebView 显示 Web 内容,您可能需要考虑优化点击行为,原因如下:
- WKWebView 不支持标签页式浏览。默认情况下,尝试打开新标签页的广告点击不会执行任何操作。
在同一标签页中打开的广告点击会重新加载页面。您可能希望强制广告点击在
WKWebView
之外打开,例如,如果您托管 H5 游戏并希望保持每个游戏的状态,则可以这样做。自动填充功能不支持
WKWebView
中的信用卡信息。这可能会导致广告客户的电子商务转化次数减少,从而对网站内容的创收产生负面影响。
- Google 登录在
WKWebView
中不受支持。
本指南提供了建议的步骤,可在保留 WebView 内容的同时优化移动 WebView 中的点击行为。
前提条件
- 完成设置 WebView 指南中的操作。
实现
广告链接可以将 href
目标属性设置为 _blank
、_top
、_self
或 _parent
。
借助 Ad Manager,您可以将广告设置为在新标签页或窗口中打开,从而将 target 属性控制为 _blank
或 _top
。
广告链接还可以包含 JavaScript 函数,例如 window.open(url, "_blank")
。
下表介绍了这些链接在 WebView 中的行为。
href target 属性 |
默认 WKWebView 点击行为 |
---|---|
target="_blank" |
网页视图未处理链接。 |
target="_top" |
重新加载现有 WebView 中的链接。 |
target="_self" |
重新加载现有 WebView 中的链接。 |
target="_parent" |
重新加载现有 WebView 中的链接。 |
JavaScript 函数 | 默认 WKWebView 点击行为 |
window.open(url, "_blank") |
网页视图未处理链接。 |
请按照以下步骤优化 WKWebView
实例中的点击行为:
在
WKWebView
实例上设置WKUIDelegate
。在
WKWebView
实例上设置WKNavigationDelegate
。确定是否优化点击后到达网址的行为。
检查
WKNavigationAction
对象上的navigationType
属性是否为要优化的点击类型。此代码示例会检查.linkActivated
,该属性仅适用于点击带有href
属性的链接。检查
WKNavigationAction
对象上的targetFrame
属性。如果返回nil
,则表示导航的目标是新窗口。由于WKWebView
无法处理该点击,因此必须手动处理这些点击。
决定是在外部浏览器(
SFSafariViewController
)中打开网址,还是在现有的 WebView 中打开网址。此代码段展示了如何通过显示SFSafariViewController
来打开导航到网站以外的网址。
代码示例
以下代码段展示了如何优化 WebView 点击行为。例如,它会检查当前网域是否与目标网域不同。这只是一种方法,您使用的条件可能会有所不同。
Swift
import GoogleMobileAds
import SafariServices
import WebKit
class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// ... Register the WKWebView.
// 1. Set the WKUIDelegate on your WKWebView instance.
webView.uiDelegate = self;
// 2. Set the WKNavigationDelegate on your WKWebView instance.
webView.navigationDelegate = self
}
// Implement the WKUIDelegate method.
func webView(
_ webView: WKWebView,
createWebViewWith configuration: WKWebViewConfiguration,
for navigationAction: WKNavigationAction,
windowFeatures: WKWindowFeatures) -> WKWebView? {
// 3. Determine whether to optimize the behavior of the click URL.
if didHandleClickBehavior(
currentURL: webView.url,
navigationAction: navigationAction) {
print("URL opened in SFSafariViewController.")
}
return nil
}
// Implement the WKNavigationDelegate method.
func webView(
_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
{
// 3. Determine whether to optimize the behavior of the click URL.
if didHandleClickBehavior(
currentURL: webView.url,
navigationAction: navigationAction) {
return decisionHandler(.cancel)
}
decisionHandler(.allow)
}
// Implement a helper method to handle click behavior.
func didHandleClickBehavior(
currentURL: URL,
navigationAction: WKNavigationAction) -> Bool {
guard let targetURL = navigationAction.request.url else {
return false
}
// Handle custom URL schemes such as itms-apps:// by attempting to
// launch the corresponding application.
if navigationAction.navigationType == .linkActivated {
if let scheme = targetURL.scheme, !["http", "https"].contains(scheme) {
UIApplication.shared.open(targetURL, options: [:], completionHandler: nil)
return true
}
}
guard let currentDomain = currentURL.host,
let targetDomain = targetURL.host else {
return false
}
// Check if the navigationType is a link with an href attribute or
// if the target of the navigation is a new window.
if (navigationAction.navigationType == .linkActivated ||
navigationAction.targetFrame == nil) &&
// If the current domain does not equal the target domain,
// the assumption is the user is navigating away from the site.
currentDomain != targetDomain {
// 4. Open the URL in a SFSafariViewController.
let safariViewController = SFSafariViewController(url: targetURL)
present(safariViewController, animated: true)
return true
}
return false
}
}
Objective-C
@import GoogleMobileAds;
@import SafariServices;
@import WebKit;
@interface ViewController () <WKNavigationDelegate, WKUIDelegate>
@property(nonatomic, strong) WKWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// ... Register the WKWebView.
// 1. Set the WKUIDelegate on your WKWebView instance.
self.webView.uiDelegate = self;
// 2. Set the WKNavigationDelegate on your WKWebView instance.
self.webView.navigationDelegate = self;
}
// Implement the WKUIDelegate method.
- (WKWebView *)webView:(WKWebView *)webView
createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration
forNavigationAction:(WKNavigationAction *)navigationAction
windowFeatures:(WKWindowFeatures *)windowFeatures {
// 3. Determine whether to optimize the behavior of the click URL.
if ([self didHandleClickBehaviorForCurrentURL: webView.URL
navigationAction: navigationAction]) {
NSLog(@"URL opened in SFSafariViewController.");
}
return nil;
}
// Implement the WKNavigationDelegate method.
- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:
(void (^)(WKNavigationActionPolicy))decisionHandler {
// 3. Determine whether to optimize the behavior of the click URL.
if ([self didHandleClickBehaviorForCurrentURL: webView.URL
navigationAction: navigationAction]) {
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
// Implement a helper method to handle click behavior.
- (BOOL)didHandleClickBehaviorForCurrentURL:(NSURL *)currentURL
navigationAction:(WKNavigationAction *)navigationAction {
NSURL *targetURL = navigationAction.request.URL;
// Handle custom URL schemes such as itms-apps:// by attempting to
// launch the corresponding application.
if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
NSString *scheme = targetURL.scheme;
if (![scheme isEqualToString:@"http"] && ![scheme isEqualToString:@"https"]) {
[UIApplication.sharedApplication openURL:targetURL options:@{} completionHandler:nil];
return YES;
}
}
NSString *currentDomain = currentURL.host;
NSString *targetDomain = targetURL.host;
if (!currentDomain || !targetDomain) {
return NO;
}
// Check if the navigationType is a link with an href attribute or
// if the target of the navigation is a new window.
if ((navigationAction.navigationType == WKNavigationTypeLinkActivated
|| !navigationAction.targetFrame)
// If the current domain does not equal the target domain,
// the assumption is the user is navigating away from the site.
&& ![currentDomain isEqualToString: targetDomain]) {
// 4. Open the URL in a SFSafariViewController.
SFSafariViewController *safariViewController =
[[SFSafariViewController alloc] initWithURL:targetURL];
[self presentViewController:safariViewController animated:YES
completion:nil];
return YES;
}
return NO;
}
测试网页导航
如需测试网页导航更改,请加载
https://google.github.io/webview-ads/test/#click-behavior-tests
到您的 WebView 中。点击每种不同的链接类型,查看它们在应用中的行为。
请检查以下几个方面:
- 每个链接都会打开预期的网址。
- 返回应用时,测试页面的计数器不会重置为零,以验证页面状态是否已保留。