WKWebViewは自分でWKUIDelegate
を指定してコードを書かない限り以下のような画面は表示されず、JavaScriptからの要求を無視します。
左から、JavaScriptのalert
,confirm
,prompt
が実行された時の画面です。
以下WKUIDelegateのみを使うことを目的としたコードを記します。
iOS8であればXcodeで新規作成時にSingle View Application
テンプレートを作成し、ViewController.m
にコピペするだけで動きますのでお試しください。
//
// ViewController.m
// MyWKWebView
//
// Created by FukuyamaShingo on 9/22/14.
// Copyright (c) 2014 Shingo Fukuyama. All rights reserved.
//
#import "ViewController.h"
#import <WebKit/WebKit.h>
@interface ViewController ()
<WKUIDelegate>
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) UIToolbar *toolbar;
@property (nonatomic, strong) UIBarButtonItem *buttonForAlert;
@property (nonatomic, strong) UIBarButtonItem *buttonForConfirm;
@property (nonatomic, strong) UIBarButtonItem *buttonForPrompt;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
/*
* Setup WKWebView only for WKUIDelegate
*/
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
_webView.UIDelegate = self;
NSString *urlString = @"https://www.google.com";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView loadRequest:request];
/*
* Setup Toolbar
*/
_buttonForAlert = [[UIBarButtonItem alloc] initWithTitle:@"Alert"
style:UIBarButtonItemStylePlain
target:self
action:@selector(showAlert:)];
_buttonForConfirm = [[UIBarButtonItem alloc] initWithTitle:@"Confirm"
style:UIBarButtonItemStylePlain
target:self
action:@selector(showConfirm:)];
_buttonForPrompt = [[UIBarButtonItem alloc] initWithTitle:@"Prompt"
style:UIBarButtonItemStylePlain
target:self
action:@selector(showPrompt:)];
_buttonForAlert.width = 80.0;
_buttonForConfirm.width = 80.0;
_buttonForPrompt.width = 80.0;
_toolbar = [[UIToolbar alloc] initWithFrame:CGRectZero];
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
_toolbar.items = @[_buttonForAlert, spacer, _buttonForConfirm, spacer, _buttonForPrompt];
[self.view addSubview:_webView];
[self.view addSubview:_toolbar];
[self setupConstraints];
}
- (void)showAlert:(UIBarButtonItem *)sender
{
NSString *promptCode = @"alert('Alertが押されました');";
[_webView evaluateJavaScript:promptCode completionHandler:^(id object, NSError *error) { }];
}
- (void)showConfirm:(UIBarButtonItem *)sender
{
NSString *promptCode = @"var confirmed = confirm('OK?');";
[_webView evaluateJavaScript:promptCode completionHandler:^(id object, NSError *error) { }];
}
- (void)showPrompt:(UIBarButtonItem *)sender
{
NSString *promptCode = @"var person = prompt('名前を入力してください', 'デフォルト');";
[_webView evaluateJavaScript:promptCode completionHandler:^(id object, NSError *error) { }];
}
#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler
{
NSString *hostString = webView.URL.host;
NSString *sender = [NSString stringWithFormat:@"%@からの表示", hostString];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:sender preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"閉じる" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler
{
NSString *hostString = webView.URL.host;
NSString *sender = [NSString stringWithFormat:@"%@からの表示", hostString];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:sender preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
//textField.placeholder = defaultText;
textField.text = defaultText;
}];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
NSString *input = ((UITextField *)alertController.textFields.firstObject).text;
completionHandler(input);
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"キャンセル" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler(nil);
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
{
NSString *hostString = webView.URL.host;
NSString *sender = [NSString stringWithFormat:@"%@からの表示", hostString];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:sender preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler(YES);
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"キャンセル" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler(NO);
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
#pragma mark - Constraints
- (void)setupConstraints
{
_webView.translatesAutoresizingMaskIntoConstraints = NO;
[_webView.superview addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-20.0-[view]-44.0-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:@{@"view":_webView}]];
[_webView.superview addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-0-[view]-0-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:@{@"view":_webView}]];
_toolbar.translatesAutoresizingMaskIntoConstraints = NO;
[_toolbar.superview addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[view]-0-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:@{@"view":_toolbar}]];
[_toolbar.superview addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-0-[view]-0-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:@{@"view":_toolbar}]];
[_toolbar.superview addConstraint:[NSLayoutConstraint constraintWithItem:_toolbar
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1.0
constant:44.0]];
}
@end
Alert地獄のサイトを回避するために"このページではこれ以上表示しない"などの対策も必要かと思います。
PR: iOS8向けのブラウザアプリを2つほど公開しますので、よろしくお願い致します。
ブログ: http://fukuyama.co/two-app-before-application