Xcode8发布以后,编译器开始不支持IOS7,所以很多应用在适配IOS10之后都不在适配IOS7了,
支持到IOS8,第一个要改的自然是用WKWebView替换原来的UIWebView。WKWebView有很多明显优势:
1.占用更少的内存
2.官方宣称的高达60fps的滚动刷新率以及内置手势
4 提供的接口也丰富了
5.增加加载进度属性:estimatedProgress
首先回顾一下UIWebView的基本使用
UIWebView的使用基本步骤分三步 分别为 创建并设置位置 设置代理为控制器对象 添加到控制器视图上
UIWebView不仅可以加载本地和网络上的页面,还可以加载pdf,word,txt,以及各种图片和mp4格式的视频
代码如下
#import "ViewController.h"
@interface ViewController ()<UIWebViewDelegate>
@property (nonatomic,strong)UIWebView *myWeb;
@end
@implementation ViewController
-(void)viewDidLoad{
[super viewDidLoad];
_myWeb = [[UIWebViewalloc]initWithFrame:[UIScreenmainScreen].bounds];
_myWeb.delegate =self;
[self.viewaddSubview:self.myWeb];
[self test1];
}
-(void)test1
{
NSURL *url = [NSURLURLWithString:@"http://www.baidu.com"];
//加载网络网页
[self.myWebloadRequest:[NSURLRequestrequestWithURL:url]];
}
-(void)test2
{
NSURL *url = [NSURLfileURLWithPath:@"/Users/fengyayun/Desktop/123.png"];
//加载图片
[self.myWebloadRequest:[NSURLRequestrequestWithURL:url]];
self.myWeb.scrollView.contentInset =UIEdgeInsetsMake(100,0,0,0);
}
-(void)test3
{
NSURL *url = [NSURLURLWithString:@"/Users/fengyayun/Desktop/123.mp4"];
//加载视频只支持mp4格式
[self.myWebloadRequest:[NSURLRequestrequestWithURL:url]];
self.myWeb.scrollView.contentInset =UIEdgeInsetsMake(100,0,0,0);
}
还提供了三个使用的加载方法
- (void)loadRequest:(NSURLRequest *)request;
- (void)loadHTMLString:(NSString *)string baseURL:(nullableNSURL *)baseURL;
- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL;
与网页导航刷新有关的方法和属性的使用
#import "ViewController.h"
@interface ViewController ()<UIWebViewDelegate>
@property (weak,nonatomic)IBOutletUIWebView *webView;
@property (weak,nonatomic)IBOutletUIBarButtonItem *goback;
@property (weak,nonatomic)IBOutletUIBarButtonItem *goforward;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
NSURLRequest *request = [NSURLRequestrequestWithURL:[NSURLURLWithString:@"http://www.baidu.com"]];
[self.webViewloadRequest:request];
self.webView.delegate =self;
}
- (IBAction)goBack:(id)sender {
[self.webViewgoBack];
}
- (IBAction)goforward:(id)sender {
[self.webViewgoForward];
}
- (IBAction)reload:(id)sender {
[self.webViewreload];
}
-(void)webViewDidStartLoad:(UIWebView *)webView{
NSLog(@"webViewDidStartLoad");
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
self.goback.enabled =self.webView.canGoBack;
self.goforward.enabled =self.webView.canGoForward;
NSLog(@"webViewDidFinishLoad");
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
NSLog(@"didFailLoadWithError");
}
3 代理协议的使用 UIWebViewDelegate
//这个方法就是拦截 前端会告诉你特定协议头 你点击网页web发请求就会调用这个方法拦截到了你可以自己用原生的做需要做的事情 比如说网页上一个打电话按钮 就可以用原生去实现打电话功能了
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
//可以做一些拦截操作 360 图片什么的操作就拦截请求的url
NSString *path = request.URL.absoluteString;
if ([pathcontainsString:@"image"]) {
//返回NO就代表不跳转了
returnNO;
}
returnYES;
}
//网页开始加载数据时调用
- (void)webViewDidStartLoad:(UIWebView *)webView;
//网页开始结束调用
- (void)webViewDidFinishLoad:(UIWebView *)webView;
//网页开始出现错误调用
- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullableNSError *)error;
UIWebView和JS之间的交互主要有三种方式
根据代理方法进行拦截- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
}上述有改方法进行拦截的判断
第二种方式使用JavaScriptCore(这个是iOS7之后苹果推出的一个JS于OC交互的一个框架,极大的方便了我们对js的操作)
先导入
#import <JavaScriptCore/JavaScriptCore.h>
主要用的类是JSContext
在这里主要讲oc调用js 因为js调用oc前面已经说过
代码如下
#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
@interface ViewController ()<UIWebViewDelegate>
@property (weak,nonatomic)IBOutletUIWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.webView.delegate =self;
//加载本地网页
[self.webViewloadRequest:[NSURLRequestrequestWithURL:[NSURLfileURLWithPath:@"/Users/fengyayun/Desktop/测试/Html5的知识/Html5--day2/登陆首页/index.html"]]];
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
//获取网页中js文件(个人理解)
JSContext *context = [self.webViewvalueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//拼接js文件中的方法
NSString *alertJS =@"pressBtnClick(111)";
//调用js文件中的方法
[context evaluateScript:alertJS];
}
对应的效果图
对应的js代码
上面是用到<JavaScriptCore/JavaScriptCore.h> 这个框架获得的js文件
我们也可以直接获得网页中标签然后修改其内容,删除等等 代码如下
#import "ViewController.h"
@interface ViewController ()<UIWebViewDelegate>
@property (weak,nonatomic)IBOutletUIWebView *webView;
/** 1*/
@property(nonatomic,weak)UIActivityIndicatorView *activity ;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
self.webView.scrollView.hidden = YES;
self.webView.backgroundColor = [UIColorgrayColor];
// 加载一个网页
NSURL *url = [NSURLURLWithString:@"http://www.xianhua.cn/m/"];
NSURLRequest *request = [NSURLRequestrequestWithURL:url];
[self.webViewloadRequest:request];
}
#pragma mark - <UIWebViewDelegate>
-(void)webViewDidFinishLoad:(UIWebView *)webView{
// 删除底部的广告
// NSString *str = @" document.getElementsByClassName('detail_btns2')[0].remove();";
// [webView stringByEvaluatingJavaScriptFromString:str];
// 修改标题
// NSString *str2 = @"document.getElementsByTagName('h1')[0].innerText = '大神5期鲜花网';";
// [webView stringByEvaluatingJavaScriptFromString:str2];
// 修改底部的标题
NSString *str3 =@"document.getElementById('xiazaiapp').getElementsByTagName('a')[0].innerText = '下载大神5期鲜花网APP';";
[webView stringByEvaluatingJavaScriptFromString:str3];
}
@end
第三种方式是用到一个库
WebViewJavascriptBridge把js和oc之间搭建一个桥,来实现相互通信 他需要依赖第三方库来实现,通过互相注册方法,增加代码量并且并不是每次方法都能注册上,有一定的失败几率,由于不推荐,所以就安排在最后,不做太详细的解释
下面介绍WKWbview的使用
- 更多的支持HTML5的特性
- 官方宣称的高达60fps的滚动刷新率
- Safari相同的JavaScript引擎
- 将UIWebViewDelegate与UIWebView拆分成了14类与3个协议(官方文档说明)
- 另外用的比较多的,增加加载进度属性:
estimatedProgress
WKWebView相对于UIWebView强大了很多,内存的消耗相对少了,所提供的接口也丰富了。
有2个代理 WKWebView代理有两个,是WKNavigationDelegate和WKUIDelegate
使用WKWbview的步骤1 先导入
#import <WebKit/WebKit.h>
2 创建和设置代理 也要遵守代理(如果要做交互还要使用这个da
WKScriptMessageHandler
)
_MyWk = [[WKWebViewalloc]initWithFrame:CGRectMake(0,0, KW,KH)];
[_MyWkloadRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"https://www.baidu.com"]]];
_MyWk.UIDelegate =self;
_MyWk.navigationDelegate =self;
3 添加到View上去
[self.viewaddSubview:self.MyWk];
介绍常用的代理方法
1. navigationDelegate
// 类似UIWebView的 -webViewDidStartLoad:
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
类似 UIWebView 的 -webViewDidFinishLoad:
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
类似 UIWebView 的- webView:didFailLoadWithError:
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
2 WKNavigtionDelegate来进行页面跳转 // 接收到服务器跳转请求之后再执行
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
- // 类似 UIWebView 的 -webView: shouldStartLoadWithRequest: navigationType:
- NSLog(@"4.%@",navigationAction.request);
- NSString *url = [navigationAction.request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- decisionHandler(WKNavigationActionPolicyAllow);
}
2 UIDelegate
- - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
- // 接口的作用是打开新窗口委托
- [self createNewWebViewWithURL:webView.URL.absoluteString config:configuration];
- return currentSubView.webView;
- }
- - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler
- { // js 里面的alert实现,如果不实现,网页的alert函数无效
- UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
- message:nil
- preferredStyle:UIAlertControllerStyleAlert];
- [alertController addAction:[UIAlertAction actionWithTitle:@"确定"
- style:UIAlertActionStyleCancel
- handler:^(UIAlertAction *action) {
- completionHandler();
- }]];
- [self presentViewController:alertController animated:YES completion:^{}];
- }
- - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
- // js 里面的alert实现,如果不实现,网页的alert函数无效 ,
- UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
- message:nil
- preferredStyle:UIAlertControllerStyleAlert];
- [alertController addAction:[UIAlertAction actionWithTitle:@"确定"
- style:UIAlertActionStyleDefault
- handler:^(UIAlertAction *action) {
- completionHandler(YES);
- }]];
- [alertController addAction:[UIAlertAction actionWithTitle:@"取消"
- style:UIAlertActionStyleCancel
- handler:^(UIAlertAction *action){
- completionHandler(NO);
- }]];
- [self presentViewController:alertController animated:YES completion:^{}];
- }
- - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler {
- completionHandler(@"Client Not handler");
- }
UIWebView 中会自动保存Cookie,如果登录了一次,下次再次进入的时候,会记住登录状态
而在WKWebView中,并不会这样,WKWebView在初始化的时候有一个方法
- - (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
通过这个方法,设置 configuration 让WKWebView知道登录状态,configuration 可以通过已有的Cookie进行设置,也可以通过保存上一次的configuration进行设置
参考 stackoverflow上回答:http://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303