如果您的应用使用 WKWebView 显示 Web 内容,您可能需要考虑优化点击行为,原因如下:
- WKWebView 不支持标签页浏览。默认情况下,尝试打开新标签页的广告点击不会执行任何操作。
如果广告点击会在同一标签页中打开,系统会重新加载该页面。您可能希望强制广告点击在
WKWebView
之外打开,例如,如果您托管 H5 游戏并希望维护每款游戏的状态。自动填充功能不支持
WKWebView
中的信用卡信息。这可能会导致广告客户的电子商务转化次数减少,进而对网络内容的创收产生负面影响。
WKWebView
不支持 Google 登录。
本指南提供了建议步骤,以便在保留网页视图内容的同时优化移动网页视图中的点击行为。
前提条件
- 完成设置网页视图指南。
实现
广告链接的 href
目标属性可以设置为 _blank
、_top
、_self
或 _parent
。
借助 Ad Manager,您可以通过将广告设置为在新标签页或新窗口中打开,将目标属性控制为 _blank
或 _top
。
广告链接还可以包含 JavaScript 函数,例如 window.open(url, "_blank")
。
下表介绍了这些链接在网页视图中的行为方式。
href target 属性 |
默认的 WKWebView 点击行为 |
---|---|
target="_blank" |
网页视图未处理链接。 |
target="_top" |
在现有网页视图中重新加载链接。 |
target="_self" |
在现有网页视图中重新加载链接。 |
target="_parent" |
在现有网页视图中重新加载链接。 |
JavaScript 函数 | 默认的 WKWebView 点击行为 |
window.open(url, "_blank") |
网页视图未处理链接。 |
请按照以下步骤优化 WKWebView
实例中的点击行为:
在
WKWebView
实例上设置WKUIDelegate
。在
WKWebView
实例上设置WKNavigationDelegate
。确定是否优化点击后到达网址的行为。
检查
WKNavigationAction
对象上的navigationType
属性是否为您要优化的点击类型。代码示例会检查.linkActivated
,该事件仅适用于包含href
属性的链接的点击。检查
WKNavigationAction
对象上的targetFrame
属性。如果它返回nil
,则表示导航的目标是新窗口。由于WKWebView
无法处理此点击,因此必须手动处理这些点击。
确定是在外部浏览器、
SFSafariViewController
还是现有网页视图中打开网址。该代码段展示了如何通过呈现SFSafariViewController
来打开从网站导航出去的网址。
代码示例
以下代码段展示了如何优化网页视图点击行为。例如,它会检查当前网域是否与目标网域不同。这只是一种方法,因为您使用的条件可能会有所不同。
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? {
guard let url = navigationAction.request.url,
let currentDomain = webView.url?.host,
let targetDomain = url.host else { return nil }
// 3. Determine whether to optimize the behavior of the click URL.
if didHandleClickBehavior(
url: url,
currentDomain: currentDomain,
targetDomain: targetDomain,
navigationAction: navigationAction) {
print("URL opened in SFSafariViewController.")
}
return nil
}
// Implement the WKNavigationDelegate method.
func webView(
_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
{
guard let url = navigationAction.request.url,
let currentDomain = webView.url?.host,
let targetDomain = url.host else { return decisionHandler(.cancel) }
// 3. Determine whether to optimize the behavior of the click URL.
if didHandleClickBehavior(
url: url,
currentDomain: currentDomain,
targetDomain: targetDomain,
navigationAction: navigationAction) {
return decisionHandler(.cancel)
}
decisionHandler(.allow)
}
// Implement a helper method to handle click behavior.
func didHandleClickBehavior(
url: URL,
currentDomain: String,
targetDomain: String,
navigationAction: WKNavigationAction) -> Bool {
// Check if the navigationType is a link with an href attribute or
// if the target of the navigation is a new window.
guard 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 else { return false }
// 4. Open the URL in a SFSafariViewController.
let safariViewController = SFSafariViewController(url: url)
present(safariViewController, animated: true)
return true
}
}
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 {
NSURL *url = navigationAction.request.URL;
NSString *currentDomain = webView.URL.host;
NSString *targetDomain = navigationAction.request.URL.host;
// 3. Determine whether to optimize the behavior of the click URL.
if ([self didHandleClickBehaviorForURL: url
currentDomain: currentDomain
targetDomain: targetDomain
navigationAction: navigationAction]) {
NSLog(@"URL opened in SFSafariViewController.");
}
return nil;
}
// Implement the WKNavigationDelegate method.
- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:
(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL *url = navigationAction.request.URL;
NSString *currentDomain = webView.URL.host;
NSString *targetDomain = navigationAction.request.URL.host;
// 3. Determine whether to optimize the behavior of the click URL.
if ([self didHandleClickBehaviorForURL: url
currentDomain: currentDomain
targetDomain: targetDomain
navigationAction: navigationAction]) {
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
// Implement a helper method to handle click behavior.
- (BOOL)didHandleClickBehaviorForURL:(NSURL *)url
currentDomain:(NSString *)currentDomain
targetDomain:(NSString *)targetDomain
navigationAction:(WKNavigationAction *)navigationAction {
if (!url || !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:url];
[self presentViewController:safariViewController animated:YES
completion:nil];
return YES;
}
return NO;
}
测试页面导航
如需测试网页导航更改,请加载
https://webview-api-for-ads-test.glitch.me#click-behavior-tests
到您的网页视图中。点击每种不同类型的链接,查看它们在应用中的行为方式。
请检查以下各项:
- 每个链接都会打开预期的网址。
- 返回应用时,测试页面的计数器不会重置为零,以验证页面状态是否已保留。