//
//  JSViewController.m
//  Library
//
//  Created by 朱逸 on 16/7/7.
//  Copyright © 2016年 朱逸. All rights reserved.
//

#import "JSViewController.h"
#import <WebKit/WebKit.h>

@interface JSViewController ()<WKScriptMessageHandler,WKUIDelegate,WKNavigationDelegate>{
}

@property (nonatomic, strong)WKWebView *wk;
@property (nonatomic, strong)UIProgressView *progressView;

@end

@implementation JSViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.automaticallyAdjustsScrollViewInsets = NO;

    self.view.backgroundColor = [UIColor grayColor];
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];

    /*
     * 用户配置
     */
    config.preferences = [[WKPreferences alloc] init];

    /*
     * 用户交互管理
     */
    config.userContentController = [[WKUserContentController alloc] init];

    /*
     * 申明代理和Native方法名
     */
    [config.userContentController addScriptMessageHandler:self name:@"AppModel"];

    // 设置偏好设置
    config.preferences = [[WKPreferences alloc] init];
    // 默认为0
    config.preferences.minimumFontSize = ;
    // 默认认为YES
    config.preferences.javaScriptEnabled = YES;
    // 在iOS上默认为NO,表示不能自动通过窗口打开
    config.preferences.javaScriptCanOpenWindowsAutomatically = NO;

    self.wk = [[WKWebView alloc] initWithFrame:CGRectMake(, , self.view.frame.size.width, self.view.frame.size.height - ) configuration:config];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];
    NSURL *url = [NSURL fileURLWithPath:path];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.wk loadRequest:request];
    /*
     * 申明导航代理
     */
    self.wk.navigationDelegate = self;
    /*
     * 申明UI代理
     */
    self.wk.UIDelegate = self;
    [self.view addSubview:self.wk];

    /*
     * 进度条
     */
    self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(, , self.view.frame.size.width, )];
    self.progressView.backgroundColor = [UIColor redColor];
    [self.view addSubview:self.progressView];

    /*
     * KVO
     */
    [self.wk addObserver:self
                   forKeyPath:@"loading"
                      options:NSKeyValueObservingOptionNew
                      context:nil];
    [self.wk addObserver:self
                   forKeyPath:@"title"
                      options:NSKeyValueObservingOptionNew
                      context:nil];
    [self.wk addObserver:self
                   forKeyPath:@"estimatedProgress"
                      options:NSKeyValueObservingOptionNew
                      context:nil];

    UIBarButtonItem *goback = [[UIBarButtonItem alloc] initWithTitle:@"后退" style:UIBarButtonItemStyleDone target:self action:@selector(goback)];
    UIBarButtonItem *gofarward = [[UIBarButtonItem alloc] initWithTitle:@"前进" style:UIBarButtonItemStyleDone target:self action:@selector(gofarward)];
    NSArray *array = @[gofarward,goback];
    self.navigationItem.rightBarButtonItems = array;
}

- (void)goback {
    if ([self.wk canGoBack]) {
        [self.wk goBack];
    }
}

- (void)gofarward {
    if ([self.wk canGoForward]) {
        [self.wk goForward];
    }
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    if ([message.name isEqualToString:@"AppModel"]) {
        NSLog(@"响应");
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"loading"]) {
        NSLog(@"loading");
    } else if ([keyPath isEqualToString:@"title"]) {
        self.title = self.wk.title;
    } else if ([keyPath isEqualToString:@"estimatedProgress"]) {
        self.progressView.progress = self.wk.estimatedProgress;
    }

    if (!self.wk.loading) {
        NSString *js = @"callJsAlert()";
        [self.wk evaluateJavaScript:js completionHandler:^(id _Nullable response, NSError * _Nullable error) {
            NSLog(@"response: %@ error: %@", response, error);
            NSLog(@"call js alert by native");
        }];

        [UIView animateWithDuration:0.5 animations:^{
            self.progressView.alpha = ;
        }];
    }
}

#pragma mark--WKNavigationDelegate
// 决定导航的动作,通常用于处理跨域的链接能否导航。WebKit对跨域进行了安全检查限制,不允许跨域,因此我们要对不能跨域的链接
// 单独处理。但是,对于Safari是允许跨域的,不用这么处理。
// 这个是决定是否Request
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    NSString *hostname = navigationAction.request.URL.host.lowercaseString;
    if (navigationAction.navigationType == WKNavigationTypeLinkActivated
        && ![hostname containsString:@".baidu.com"]) {
        // 对于跨域,需要手动跳转
        [[UIApplication sharedApplication] openURL:navigationAction.request.URL];

        // 不允许web内跳转
        decisionHandler(WKNavigationActionPolicyCancel);
    } else {
        self.progressView.alpha = 1.0;
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}
// 决定是否接收响应
// 这个是决定是否接收response
// 要获取response,通过WKNavigationResponse对象获取
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigation ResponsedecisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{

}
// 当main frame的导航开始请求时,会调用此方法
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation{

}

// 当main frame接收到服务重定向时,会回调此方法
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation{

}

// 当main frame开始加载数据失败时,会回调
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{

}

// 当main frame的web内容开始到达时,会回调
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation{

}

// 当main frame导航完成时,会回调
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{

}

// 当main frame最后下载数据失败时,会回调
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{

}

// 这与用于授权验证的API,与AFN、UIWebView的授权验证API是一样的
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler{
    completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}

// 当web content处理完成时,会回调
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{

}

#pragma mark - WKUIDelegate
- (void)webViewDidClose:(WKWebView *)webView {
    NSLog(@"%s", __FUNCTION__);
}

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    NSLog(@"%s", __FUNCTION__);
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:@"JS调用alert" preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }]];

    [self presentViewController:alert animated:YES completion:NULL];
    NSLog(@"%@", message);
}

- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
    NSLog(@"%s", __FUNCTION__);

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"confirm" message:@"JS调用confirm" preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }]];
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }]];
    [self presentViewController:alert animated:YES completion:NULL];

    NSLog(@"%@", message);
}

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
    NSLog(@"%s", __FUNCTION__);

    NSLog(@"%@", prompt);
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.textColor = [UIColor redColor];
    }];

    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler([[alert.textFields lastObject] text]);
    }]];

    [self presentViewController:alert animated:YES completion:NULL];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

webkit框架的使用的更多相关文章

  1. WebKit框架 浅析

    摘要 WebKit是iOS8之后引入的专门负责处理网页视图的框架,其比UIWebView更加强大,性能也更优. iOS中WebKit框架应用与解析 一.引言 在iOS8之前,在应用中嵌入网页通常需要使 ...

  2. iOS中WebKit框架应用与解析

    WebKit是iOS8之后引入的专门负责处理网页视图的框架,其比UIWebView更加强大,性能也更优. 引言 在iOS8之前,在应用中嵌入网页通常需要使用UIWebView这样一个类,这个类通过UR ...

  3. Firemonkey实现Mac OS程序中内嵌浏览器的功能(自己动手翻译,调用苹果提供的webkit框架)

    XE系列虽然可以跨平台,但是在跨平台的道路上只是走了一小半的路,很多平台下的接口都没实现彻底,所以为了某些功能,还必须自己去摸索. 想实现程序中可以内嵌浏览器的功能,但是Firemonkey还没有对应 ...

  4. iOS:WebKit内核框架的应用与解析

    原文:http://www.cnblogs.com/fengmin/p/5737355.html 一.摘要: WebKit是iOS8之后引入的专门负责处理网页视图的框架,其比UIWebView更加强大 ...

  5. iOS引入JavaScriptCore引擎框架(二)

    为何放弃第一种方案 UIWebView的JSContext获取     上篇中,我们通过简单的kvc获取UIWebVIew的JSContext,但是实际上,apple并未给开发者提供访问UIWebVi ...

  6. 网络天荒地老之UIWebView&WebKit

    UIWebView 是苹果提供的用来展示网页的UI控件,它也是最占内存的控件. iOS8.0之后出现了webkit框架,WKWebView相比UIWebView节省了1/4~1/3的内存,速度快,但是 ...

  7. iOS10通知框架UserNotification理解与应用

    iOS10通知框架UserNotification理解与应用 一.引言 关于通知,无论与远程Push还是本地通知,以往的iOS系统暴漏给开发者的接口都是十分有限的,开发者只能对标题和内容进行简单的定义 ...

  8. WebKit示例解读

    如果你曾经在你的App中使用UIWebView加载网页内容的话,你应该体会到了它的诸多不尽人意之处.UIWebView是基于移动版的Safari的,所以它的性能表现十分有限.特别是在对几乎每个Web应 ...

  9. 谈谈iOS9中的WebKit 与 Safari

    每个用过 UIWebView 的iOS开发者对其诸多的限制和有限的功能也深有感触.悻然,自iOS8推出 WebKit 框架后将改变这一窘境.在本文我将会深入WebKit来体验一下它给我们带来的好处,同 ...

随机推荐

  1. 配置restful webservice 框架restkit

    (配置restful webservice 框架restkit) RestKit 是一个开源的 objective-c 框架,容许在 iOS 和 Mac OS X 的 Objective-C 中与 R ...

  2. WPF/Silverlight中的RichTextBox总结

    WPF/Silverlight中的RichTextBox总结   在WPF或者是在Silverlight中有个非常强大的可以编辑的容器控件RichTextBox,有的时间会采取该控件来作为编辑控件.鉴 ...

  3. 自定义html标签

    自定义html标签 (觉得页面全是div 的解决办法 来个个性化) 办法一(来源于 让ie支持html5标签的方法): 在ie9以前如果要自定义要使用document.createElement的方法 ...

  4. NodeJS系列-部署

    NodeJS系列-部署 NodeJS我就不介绍了,被标题吸引进来的人可以看这个链接,了解NodeJS.下来就开始关于NodeJS开发的指南. NodeJS可以部署的平台有Windows,Unix,iO ...

  5. Mongodb 集群搭建以及常见错误

    Mongodb 集群搭建以及常见错误 1 关于Replica Sets +Sharding(主从复制加分片)搭建,不这详细去说,网上有很多,大部分的例子就三台服务器之间做主从复制,分2个shard,架 ...

  6. MFC控件(9):network address control

    这个控件的名字倒是取的不错,一看就知道是让你输入IP地址或host name的. 不过一打开看到那控件的样子就完全是个Edit control.不过该控件对应的类也确实是继承自类CEdit. 先拖个控 ...

  7. 捕鱼达人代码例子下载地址 Win版

    捕鱼达人代码例子下载地址 Win版:: http://pan.baidu.com/share/link?shareid=1601576904&uk=3189484501

  8. Eclipse 4.3正式版发布

    Eclipse 4.3正式版发布 作者:chszs,转载需注明.博客主页: http://blog.csdn.net/chszs Eclipse 4.3版代号为Kepler. 主要特性如下: 1. E ...

  9. Redis 集成Spring(spring-data-redis)

    Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis,  JRedis, and RJC)进行 ...

  10. ESLint--定制你的代码规则

    简介 ESLint是一个开源的项目,由Nicholas C. Zakas(<JavaScript高级程序设计>作者)于2013年六月创建.它的目标是为JavaScript提供一个完全可配置 ...