アプリで WKWebView を使用してウェブ コンテンツを表示する場合は、次の理由からクリック動作の最適化を検討することをおすすめします。
- WKWebView はタブ ブラウジングをサポートしていません。デフォルトでは、新しいタブを開こうとする広告のクリックは何も行いません。
同じタブで開く広告をクリックすると、ページが再読み込みされます。たとえば、H5 ゲームをホストしていて、各ゲームの状態を維持したい場合は、広告のクリックを
WKWebView
の外部で開くように強制できます。自動入力は、
WKWebView
のクレジット カード情報をサポートしていません。これにより、広告主様の e コマース コンバージョンが減少し、ウェブ コンテンツの収益化に悪影響が及ぶ可能性があります。
WKWebView
では Google ログインはサポートされていません。
このガイドでは、ウェブビューのコンテンツを維持しながら、モバイル ウェブビューでのクリック動作を最適化するためのおすすめの手順について説明します。
前提条件
- ウェブビューの設定ガイドの手順を完了します。
実装
広告リンクの href
ターゲット属性は、_blank
、_top
、_self
、_parent
のいずれかに設定できます。アド マネージャーでは、広告を新しいタブまたはウィンドウで開くように設定することで、ターゲット属性を _blank
または _top
に制御できます。広告リンクには、window.open(url, "_blank")
などの JavaScript 関数を含めることもできます。
次の表に、ウェブビューでの各リンクの動作を示します。
href ターゲット属性 |
WKWebView のデフォルトのクリック動作 |
---|---|
target="_blank" |
ウェブビューで処理されないリンク。 |
target="_top" |
既存のウェブビューでリンクを再読み込みします。 |
target="_self" |
既存のウェブビューでリンクを再読み込みします。 |
target="_parent" |
既存のウェブビューでリンクを再読み込みします。 |
JavaScript 関数 | WKWebView のデフォルトのクリック動作 |
window.open(url, "_blank") |
ウェブビューで処理されないリンク。 |
WKWebView
インスタンスのクリック動作を最適化する手順は次のとおりです。
WKWebView
インスタンスでWKUIDelegate
を設定します。WKWebView
インスタンスでWKNavigationDelegate
を設定します。クリック URL の動作を最適化するかどうかを決定します。
WKNavigationAction
オブジェクトのnavigationType
プロパティが、最適化するクリックタイプであるかどうかを確認します。コード例では、.linkActivated
をチェックしています。これは、href
属性を持つリンクのクリックにのみ適用されます。WKNavigationAction
オブジェクトのtargetFrame
プロパティを確認します。nil
が返された場合は、ナビゲーションのターゲットが新しいウィンドウであることを意味します。WKWebView
はそのクリックを処理できないため、これらのクリックは手動で処理する必要があります。
URL を外部ブラウザ(
SFSafariViewController
)で開くか、既存のウェブビューで開くかを決定します。このコード スニペットは、SFSafariViewController
を表示してサイトから移動する URL を開く方法を示しています。
サンプルコード
次のコード スニペットは、ウェブビューのクリック動作を最適化する方法を示しています。たとえば、現在のドメインがターゲット ドメインと異なるかどうかを確認します。これは 1 つのアプローチにすぎません。使用する条件は異なる場合があります。
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
ウェブビューに渡すことができます。さまざまなリンクタイプをクリックして、アプリでの動作を確認します。
その際は、次の点をよくご確認ください。
- 各リンクは、意図した URL を開きます。
- アプリに戻ると、テストページのカウンタがゼロにリセットされず、ページの状態が保持されたことを確認できます。