//
//  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. Hibernate配置XML连接数据库

    一.hibernate.cfg.xml 1.配置连接Oracle <?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate ...

  2. web前端安全---读书笔记

    web前端安全---读书笔记 粗略的看完了Web前端黑客技术揭秘前两章了,由于自身的前端功力不深,当然也是初涉前端的安全问题,所以实话还是有些问题看不太明白的.在豆瓣看到的这本书,名字真心有点很肥主流 ...

  3. (Sql Server)数据的拆分和合并

    (Sql Server)数据的拆分和合并 背景: 今天遇到了数据合并和拆分的问题,尝试了几种写法.但大致可分为两类:一.原始写法.二.Sql Server 2005之后支持的写法.第一种写法复杂而且效 ...

  4. ArcEngine关于单位转换示例

    示例界面: 转换代码: private void Button1_Click(object sender, System.Windows.RoutedEventArgs e) { // Get the ...

  5. ok6410 u-boot-2012.04.01移植二修改源码支持单板

    继ok6410 u-boot-2012.04.01移植一后修改代码,对ok6410单板初始化,主要包括时钟.串口.NAND.DDR等初始化.这些工作在以前的裸板程序都写了,直接拿来用.我觉得先写裸板程 ...

  6. Wget 命令详解

    Wget主要用于下载文件,在安装软件时会经常用到,以下对wget做简单说明. 1.下载单个文件:wget http://www.baidu.com.命令会直接在当前目录下载一个index.html的文 ...

  7. eclipse 中导入 maven项目 启动报错

    导入Maven项目到Eclipse中时,出现问题如下: java.lang.ClassNotFoundException: org.springframework.web.context.Contex ...

  8. [ios2] ios7UI适配 【转】

    http://blog.csdn.net/toss156/article/details/11843873#comments (1)如果应用程序始终隐藏 status bar 那么恭喜呢,你在UI上需 ...

  9. [ios2]tableView去除空行的singleLine

    http://www.winddisk.com/2013/03/29/tableview%E5%8E%BB%E9%99%A4%E7%A9%BA%E8%A1%8C%E7%9A%84singleline/ ...

  10. Mybatis学习笔记(一) 之框架原理

    原生态JDBC编程中问题总结 1.单独使用jdbc连接数据库 maven依赖包: <!-- mysql --> <dependency> <groupId>mysq ...