热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OC/Swift基础WKWebView的详解,使用(源码)

一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路&




一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。


前言

网上很多这方面的资料都写的很好的,例如下面的这个地址:OC: WKWebView详解 然后自己也总结了一些自己再开发中遇到的问题,顺便介绍一下WKWebView的属性和方法


正题


WKWebView新特性

在性能、稳定性、功能方面有很大提升(最直观的体现就是加载网页是占用的内存);
允许JavascriptNitro库加载并使用(UIWebView中限制);
支持了更多的HTML5特性;
高达60fps的滚动刷新率以及内置手势;
UIWebViewDelegateUIWebView重构成了14类与3个协议 查看苹果官方文档;


WebKit框架概览

在这里插入图片描述

WebKit框架中最核心的类应该属于WKWebView了,这个类专门用来渲染网页视图,其他类和协议都将基于它和服务于它。


说明
WKWebView网页的渲染与展示,通过WKWebViewConfiguration可以进行自定义配置
WKWebViewConfiguration这个类专门用来配置WKWebView
WKPreference这个类用来进行相关webView设置
WKProcessPool这个类用来配置进程池,与网页视图的资源共享有关
WKUserContentController这个类主要用来做native与Javascript的交互管理
WKUserScript用于进行Javascript注入
WKScriptMessageHandler这个类专门用来处理Javascript调用native的方法
WKNavigationDelegate网页跳转间的导航管理协议,这个协议可以监听网页的活动
WKNavigationAction网页某个活动的示例化对象
WKUIDelegate用于交互处理Javascript中的一些弹出框
WKBackForwardList堆栈管理的网页列表
WKBackForwardListItem每个网页节点对象

WKWebView的属性


属性说明
configurationwebView的自定义配置
navigationDelegate导航代理
UIDelegateUI代理
backForwardList访问过网页历史列表
title网页的标题
URL网页的URL地址
loading网页是否正在加载
estimatedProgress加载的进度 范围为[0, 1]
hasOnlySecureContent网页链接是否安全
serverTrust证书服务
canGoBack是否可以返回
canGoForward是否可以前进

方法

/// 自定义初始化webView
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
/// url加载webView视图
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
/// 文件加载webView视图
- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));
/// HTMLString字符串加载webView视图
- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
/// NSData数据加载webView视图
- (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL API_AVAILABLE(macosx(10.11), ios(9.0));
/// 返回上一个网页节点
- (nullable WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item;
/// 返回到上一个网页
- (nullable WKNavigation *)goBack;
/// 前进到下一个网页
- (nullable WKNavigation *)goForward;
/// 重新加载
- (nullable WKNavigation *)reload;
/// 忽略缓存 重新加载
- (nullable WKNavigation *)reloadFromOrigin;
/// 停止加载
- (void)stopLoading;
/// 执行Javascript
- (void)evaluateJavascript:(NSString *)JavascriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
/// 据设置的缩放因子来缩放页面,并居中显示结果在指定的点
- (void)setMagnification:(CGFloat)magnification centeredAtPoint:(CGPoint)point;

WKWebView的使用

简单使用,直接加载url地址

WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://developer.apple.com/reference/webkit"]]];
[self.view addSubview:webView];

自定义配置
WKWebView里面注册供JS调用的方法,是通过WKUserContentController类下面的方法:

// 创建配置
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
// 创建UserContentController(提供Javascript向webView发送消息的方法)
WKUserContentController* userContent = [[WKUserContentController alloc] init];
// 添加消息处理,注意:self指代的对象需要遵守WKScriptMessageHandler协议,结束时需要移除
[userContent addScriptMessageHandler:self name:@"NativeMethod"];
// 将UserConttentController设置到配置文件
config.userContentController = userContent;
// 高端的自定义配置创建WKWebView
WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:config];
// 设置访问的URL
NSURL *url = [NSURL URLWithString:@"https://developer.apple.com/reference/webkit"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[self.view addSubview:webView];

实现WKScriptMessageHandler协议方法

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
  // 判断是否是调用原生的
if ([@"NativeMethod" isEqualToString:message.name]) {
   // 判断message的内容,然后做相应的操作
  if ([@"close" isEqualToString:message.body]) {
  }
}
}

WKNavigationDelegate代理方法

typedef NS_ENUM(NSInteger, WKNavigationActionPolicy) {
WKNavigationActionPolicyCancel, // 取消跳转
WKNavigationActionPolicyAllow, // 允许跳转
} API_AVAILABLE(macosx(10.10), ios(8.0));

// 1 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSLog(@"1-------在发送请求之前,决定是否跳转 -->%@",navigationAction.request);
decisionHandler(WKNavigationActionPolicyAllow);
}
// 2 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"2-------页面开始加载时调用");
}
// 3 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
/// 在收到服务器的响应头,根据response相关信息,决定是否跳转。decisionHandler必须调用,来决定是否跳转,参数WKNavigationActionPolicyCancel取消跳转,WKNavigationActionPolicyAllow允许跳转
NSLog(@"3-------在收到响应后,决定是否跳转");
decisionHandler(WKNavigationResponsePolicyAllow);
}
// 4 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
NSLog(@"4-------当内容开始返回时调用");
}
// 5 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
NSLog(@"5-------页面加载完成之后调用");
}
// 6 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"6-------页面加载失败时调用");
}
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"-------接收到服务器跳转请求之后调用");
}
// 数据加载发生错误时调用
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
NSLog(@"----数据加载发生错误时调用");
}
// 需要响应身份验证时调用 同样在block中需要传入用户身份凭证
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
//用户身份信息
NSLog(@"----需要响应身份验证时调用 同样在block中需要传入用户身份凭证");
NSURLCredential *newCred = [NSURLCredential credentialWithUser:@""
password:@""
persistence:NSURLCredentialPersistenceNone];
// 为 challenge 的发送方提供 credential
[[challenge sender] useCredential:newCred forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
}
// 进程被终止时调用
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
NSLog(@"----------进程被终止时调用");
}

OC 加载本地数据

OC-WKWebView(本地数据) 源码
本地数据加载方式一:
在这里插入图片描述

[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Javascript" ofType:@"html"]]]];

本地数据加载方式二:
在这里插入图片描述

NSString *text = @"

本文转自【央视新闻客户端】;当地时间8日下午,德国联邦交通部长维辛在新闻发布会上表示,德国两个不同地点的电缆被故意切断,随后便立即启动了安全机制,但目前没有肇事者的证据,犯罪动机尚不清楚。根据官方提供的信息,电缆故障初步认定在北莱茵-威斯特法伦州和柏林。如果两个地点的破坏情况得到确认,则必须评估这是出于政治动机的国家安全犯罪还是来自外部的破坏行为。当天早上,德国北部铁路运输大规模中断 ,大量旅客被困在火车站。德国铁路公司给出的理由是“数字火车无线电系统的故障”。德国铁路公司警告说,尽管铁路服务已恢复,但预计当天仍有取消和延误。这次袭击发生在对连接俄罗斯和德国的“北溪-1”和“北溪-2”天然气管道的破坏性袭击之后仅两周多,从而引发了德国国内对于基础设施安全性的讨论。(总台记者 李长皓)本文转自【央视新闻客户端】;当地时间8日下午,德国联邦交通部长维辛在新闻发布会上表示,德国两个不同地点的电缆被故意切断,随后便立即启动了安全机制,但目前没有肇事者的证据,犯罪动机尚不清楚。根据官方提供的信息,电缆故障初步认定在北莱茵-威斯特法伦州和柏林。如果两个地点的破坏情况得到确认,则必须评估这是出于政治动机的国家安全犯罪还是来自外部的破坏行为。当天早上,德国北部铁路运输大规模中断 ,大量旅客被困在火车站。德国铁路公司给出的理由是“数字火车无线电系统的故障”。德国铁路公司警告说,尽管铁路服务已恢复,但预计当天仍有取消和延误。这次袭击发生在对连接俄罗斯和德国的“北溪-1”和“北溪-2”天然气管道的破坏性袭击之后仅两周多,从而引发了德国国内对于基础设施安全性的讨论。(总台记者 李长皓)本文转自【央视新闻客户端】;当地时间8日下午,德国联邦交通部长维辛在新闻发布会上表示,德国两个不同地点的电缆被故意切断,随后便立即启动了安全机制,但目前没有肇事者的证据,犯罪动机尚不清楚。根据官方提供的信息,电缆故障初步认定在北莱茵-威斯特法伦州和柏林。如果两个地点的破坏情况得到确认,则必须评估这是出于政治动机的国家安全犯罪还是来自外部的破坏行为。当天早上,德国北部铁路运输大规模中断 ,大量旅客被困在火车站。德国铁路公司给出的理由是“数字火车无线电系统的故障”。德国铁路公司警告说,尽管铁路服务已恢复,但预计当天仍有取消和延误。这次袭击发生在对连接俄罗斯和德国的“北溪-1”和“北溪-2”天然气管道的破坏性袭击之后仅两周多,从而引发了德国国内对于基础设施安全性的讨论。(总台记者 李长皓)
";

NSString *baseURL = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Html"];
[self.webView loadHTMLString:text baseURL:[NSURL fileURLWithPath:baseURL]];

有些Html带有斜杠的,注意使用分隔符

NSString *name = @"

\r\n\t点击个人中心-‘待发货’,选择要退货退款的商品,点击‘退货/退款’,填写理由说明后提交申请,等待售后人员处理\r\n\n\n \n\n\n \n\n\n\r\n\t\t提交申请后,可在‘售后’中查看维权进度\r\n\t\n \n
";

OC 加载网络数据

OC-WKWebView(网络连接) 源码

[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];

Swift 加载本地数据

Swift-WKWebView(本地数据) 源码
在这里插入图片描述

webView.load(URLRequest(url: URL(fileURLWithPath: Bundle.main.path(forResource: "Javascript", ofType: "html") ?? "")))

Swift 加载网络数据


Swift-WKWebView(网络连接) 源码
在这里插入图片描述

guard let url = URL(string: "https://www.baidu.com") else { return }
let request = URLRequest(url: url)
webView.load(request)

经验

OC 技术 WKWebView新闻详情(源码)

OC 技术 UIWebView新闻详情

OC 技术 WKWebView OC跟JS JS跟OC交互(视频+源码)

OC 技术 商品详情WebView加载详情图片(代码+视频讲解)







推荐阅读
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • C#设计模式之八装饰模式(Decorator Pattern)【结构型】
    一、引言今天我们要讲【结构型】设计模式的第三个模式,该模式是【装饰模式】,英文名称:DecoratorPattern。我第一次看到这个名称想到的是另外一个词语“装修”,我就说说我对“装修”的理 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • 本文详细介绍了Mybatis中#与$的区别及其作用。#{}可以防止sql注入,拼装sql时会自动添加单引号,适用于单个简单类型的形参。${}则将拿到的值直接拼装进sql,可能会产生sql注入问题,需要手动添加单引号,适用于动态传入表名或字段名。#{}可以实现preparedStatement向占位符中设置值,自动进行类型转换,有效防止sql注入,提高系统安全性。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
  • Spring Batch中多线程配置及实现例子
    本文介绍了在Spring Batch中开启多线程的配置方法,包括设置线程数目和使用线程池。通过一个示例演示了如何实现多线程从数据库读取数据并输出。同时提到了在多线程情况下需要考虑Reader的线程安全问题,并提供了解决方法。 ... [详细]
  • PeopleSoft安装镜像版本及导入语言包的方法
    本文介绍了PeopleSoft安装镜像的两个版本,分别是VirtualBox虚拟机版本和NativeOS版本,并详细说明了导入语言包的方法。对于Windows版本,可以通过psdmt.exe登录进入,并使用datamover脚本导入语言包。对于Linux版本,同样可以使用命令行方式执行datamover脚本导入语言包。导入语言包后,可以实现多种语言的登录。参考文献提供了相关链接以供深入了解。 ... [详细]
  • Question该提问来源于开源项目:react-native-device-info/react-native-device-info ... [详细]
author-avatar
fgsZHdgsz
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有