首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分享超详细 WKWebView 开发和使用经验

分享超详细 WKWebView 开发和使用经验

作者头像
网罗开发
发布2021-08-13 16:23:57
4.4K0
发布2021-08-13 16:23:57
举报
文章被收录于专栏:网罗开发网罗开发

根据需求需要将老项目中的 WebView 替换成 WKWebView,期间查阅了不少文档和资料,之前也发布了几篇 WKWebView 相关的优秀文章。

WKWebView 几个不常用的特性

WKWebview 加载过程中的性能指标图解

WKWebview 秒开的实践及踩坑之路

今天分享的这篇文章全面的介绍了 WKWebView,作者根据开发和使用经验从属性、方法、代理等方面详细的做出了总结。

文章较长大家可以先通过目录了解文章内容。

  • WKWebView 初始化
    • WKWebViewConfiguration
  • 代理方法
    • WKNavigationDelegate
    • WKUIDelegate
  • 属性和方法
    • 历史记录管理
    • WKBackForwardList
    • WKBackForwardListItem
    • 网页加载
  • WKWebViewConfiguration
    • 进程池 WKProcessPool
    • 偏好设置 WKPreferences
    • 用户内容控制 WKUserContentController
  • 存储 WKWebsiteDataStore
    • 内容渲染控制 suppressesIncrementalRendering
    • 追加 User-Agent applicationNameForUserAgent
    • 网页多媒体播放
    • 选择粒度 WKSelectionGranularity
    • 数据类型检测 WKDataDetectorTypes
    • 忽略网页缩放设置 ignoresViewportScaleLimits
    • 自定义拦截协议 iOS11 以上新支持
  • 代理 WKNavigationDelegate
    • decidePolicyForNavigationAction 首先决定网页是否继续访问
    • iOS13 新增 WKWebpagePreferences
    • decidePolicyForNavigationResponse 是否允许响应回调
    • 当主 Frame 开始加载页面 didStartProvisionalNavigation
    • 当服务器发起重定向请求 didReceiveServerRedirectForProvisionalNavigation
    • 当容器在加载数据时发生了错误 didFailProvisionalNavigation
    • 当容器开始加载数据
    • 当网页内容开始在主 Frame 开始渲染
    • 在提交主 Frame 导航期间发生了错误
    • 当接受 HTTPS 请求证书后执行
    • 当容器内容发生崩溃
  • UI代理 WKUIDelegate
    • 打开新的 WebView createWebViewWithConfiguration
    • 关闭网页 webViewDidClose
    • 提示信息 runJavaScriptAlertPanelWithMessage
    • 确认信息提示框 runJavaScriptConfirmPanelWithMessage
    • 输入提示框 runJavaScriptTextInputPanelWithPrompt
    • iOS 13 新增方法 contextMenu 的处理方法
    • FAQ

WKWebView 初始化

WKWebViewConfiguration

WKWebView 如果需要个性化配置,则应该使用以下方法进行初始化。

- (instancetype)initWithFrame:(CGRect)frame 
   configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;

示例代码:

WKWebViewConfiguration *conf = [WKWebViewConfiguration new];
WKWebView *wk = [[WKWebView alloc] initWithFrame:CGRectZero configuration:conf];

代理方法

WKNavigationDelegate

WKWebView 网页的导航代理,可以理解为网页的生命周期事件循环。

WKUIDelegate

WKWebView 网页的UI交互代理,对于 JS 中的 UI 类型操作需要实现对应的方法,例如 window.alertwindow.confirm 等操作。

属性和方法

历史记录管理

WKWebView 系统默认支持对网页历史记录的管理,经过实际测试 302 状态码的网页请求不属于历史记录,200 状态码的网页请求属于正常的历史记录。

WKBackForwardList

支持仅对历史记录列表和数据的获取

WKBackForwardListItem

WKBackForwardListItem 为每一项历史记录的数据模型。

/*! @abstract The URL of the webpage represented by this item.
 */
@property (readonly, copy) NSURL *URL;


/*! @abstract The title of the webpage represented by this item.
 */
@property (nullable, readonly, copy) NSString *title;


/*! @abstract The URL of the initial request that created this item.
 */
@property (readonly, copy) NSURL *initialURL;

其中 initialURLURL 的区别:

  1. initialURL 为本次网页加载的初始请求
  2. URL 为本次网页加载结束后的最终请求
  3. 两者 URL 区别在于首次发起 302 跳转的请求
  4. title 为本次网页加载结束时的 <title></title> 标签

网页加载

加载在线地址

正常情况下,一般用 loadRequest 方法加载即可。

- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;

loadDataloadHTML 也能加载网络地址,原理都是通过先获取 NSData 后,利用该方法加载,但是要注意获取 NSData 的过程是同步,如果网络请求较慢,会造成主线程阻塞。

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
// 直接加载H5数据
// [wk loadHTMLString:[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] baseURL:nil];
[wk loadData:data MIMEType:@"text/html" characterEncodingName:@"UTF-8" baseURL:nil];

loadHTMLStringloadData 中的参数说明:

baseURL:会影响网页加载过程中 cssjs、图片等资源文件的相对路径,并不会影响绝对路径。

MIMEType:为支持加载网页的类型,有如下类型

文件拓展名

MIMEType

png

image/png

bmp/dib

image/bmp

jpg/jpeg/jpg

image/ipeg

gif

image/gif

mp3

audio/mpeg

mp4/mpg4/m4v/mp4v

video/mp4

js

application/javascript

pdf

application/pdf

text/txt

text/plain

json

application/json

xml

text/xml

characterEncodingName:当前返回信息的数据编码格式:UTF-8、UTF-16、UTF-32、GBK、GB2312等,一般使用 UTF-8。

加载本地地址
Bundle下资源加载
iOS9.0 以上可以使用以下方法加载
- (nullable WKNavigation *)loadFileURL:(NSURL *)URL 
               allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macos(10.11), ios(9.0));
  • 其中 readAccessURL 参数不能为空,否则会造成应用崩溃。
  • readAccessURL 参数:允许访问的资源路径,如果是在 Bundle 中加载本地 HTML,则需要设置该 HTML 所在的 Bundle 路径,路径设置好后,该目录在 WKWebView 中被视为沙盒目录,HTML 就可以访问同级目录下的资源文件。
Bundle 下示例:
HTML 主地址应为:

YOUR_APP_PATH/WKBundle.bundle/sandbox/index.html

readAccessURL 应为以下两种:
  1. YOUR_APP_PATH/WKBundle.bundle/sandbox
  2. YOUR_APP_PATH/WKBundle.bundle/

readAccessURL 的参数为当前 HTML 所在目录允许访问,该参数对 Bundle 目录影响不大,对沙盒目录影响较大。这个参数不可以设置为:YOUR_APP_PATH/WKBundle.bundle/sandbox/js,否则会造成访问出错。

其余访问本地 HTML 的方法

[wk loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:indexPath]]];

同样,上文中的 loadDataloadHTML 也可以访问本地 html,同样也存在同步阻塞的问题。

沙盒目录下资源加载

DocuemntLibrarytmp 目录

如果本地 HTML 放置在 Docuemnt ,Library 下的话, 则需要将目录设置为所有静态资源的最外层。例如目录结构为:

├─ html-demo
 | ├─ common
 |  | ├─ index.css
 |  | └─ index.js
 | ├─ pages
 |  | ├─ relative-common
 |  |  | ├─ index.css
 |  |  | └─ index.js
 |  | └─ index.html
如果将 html-demo 目录放置在 Document、Library 目录下
  1. 通过 [WKWebView loadFileURL:allowingReadAccessToURL:] 方法可以访问当前目录下的相对资源,还需要设置指定访问 allowingReadAccessToURL 下的资源,注意 allowingReadAccessToURL 需要设置 htmlcss 同时存在的最外层目录,如上例中,我们将 allowingReadAccessToURL 所需参数设置为 html-demo 目录的话,这样既能访问 common 目录下的资源,也能访问 relative-common 下的资源。
  2. 通过 [WKWebView loadRequest:] 方法访问 index.html 的话,仅能访问当前页面所在目录下的相对路径资源,无法访问目录外的资源,例如上例中,index.html 仅能访问 relative-common 目录下的资源,不能访问 common 目录下的资源。
  3. 通过 [WKWebView loadData:][WKWebView loadHTMLString:] 方法仅能加载当前HTML内容,无法加载资源文件,这种加载模式下,由于不需要访问其他路径下的资源,属于单页渲染和加载,所以效率高。
如果将 html-demo 目录放置在 tmp 目录下
  1. 通过 [WKWebView loadRequest:] 方法访问 index.html 的话,既能访问 common 下的资源,也能访问 relative-common 下的资源。
  2. 其余规则同上。
WKWebView 属性
webView 属性
  • title: 网页的标题,一般为 html 中的 <title></title> 中的内容
  • URL: 网页的URL地址,为最终加载的地址
  • loading: 网页是否处于加载中,YES 加载中、 NO 加载完成
  • estimatedProgress: 网页加载进度
  • hasOnlySecureContent: 网页上的所有资源是否已通过 https 加载
  • serverTrust: 加载 HTTPS 请求服务端所信任的证书

以上属性都可以采用 KVO 观察属性变化:

// NSKeyValueObservingOptionNew 更改后的值
// NSKeyValueObservingOptionOld 更改前的值
// NSKeyValueObservingOptionInitial 观察初始化的值(在注册观察服务时会调用一次触发方法)
// NSKeyValueObservingOptionPrior 分别在值修改前后触发方法(即一次修改有两次触发)
[wk addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionInitial context:NULL];

注意:添加观察者模式后,一定要在合适的时机将观察者模式移除,否则在 iOS10 以下的设备会造成崩溃,原因是 WKWebView 在释放的时候,扔被强持有观察者。

  • allowsBackForwardNavigationGestures: 允许手势交互进行页面导航跳转
  • customUserAgent: 自定义 Web 页面的 UserAgent,会覆盖容器原有的 User-Agent 请求头信息
  • allowsLinkPreview: 允许 3Dtouch 预览页面,压力屏存在的情况下
webView 方法
  • canGoBack: 是否可以返回上一页
  • canGoForward: 是否可以前进一页
  • goBack: 返回上一页
  • goForward: 前进一页
  • eload: 根据当前URL刷新页面
  • reloadFromOrigin: 根据最初 URL 刷新页面
  • stopLoading: 停止加载
  • evaluateJavaScript: 执行一段 js 代码
  • handlesURLScheme:(NSString *)urlScheme: 拦截自定义请求协议,不允许拦截 httphttpswswssftp
  • takeSnapshotWithConfiguration: 截图配置只能截取当前一屏画面

WKWebViewConfiguration

WebView 配置之 WKWebViewConfiguration

进程池 WKProcessPool

WKProcessPool 用于提供给 WKWebView 获取 Web 内容的进程池,里面包括 cookie 。当一个 WebView初始化,一个新的 Web 内容进程会从一个特殊的进程池中创建,或者一个已存在的进程会被使用。

WKProcessPool 本身没有任何方法和属性,通过实现单例进程池后,可以达到 WKWebView 间共享 cookie 的能力,注意:如果在账户退出登录后,单例进程需要释放。

偏好设置 WKPreferences

WKWebView 的偏好设置,支持以下设置:
  • minimumFontSize: 最小字体设置,默认为 0, H5css“font-size” 的值如果小于该值,则会使用该值作为字体的最小尺寸。
  • javaScriptEnabled: 是否启用 js 脚本,默认启用,关闭则不会运算 js 脚本,加快渲染速度。
  • javaScriptCanOpenWindowsAutomatically: 允许使用 js 自动打开 Window,默认不允许,js 在调用 window.open 方法的时候,必须将改值设置为 YES,才能从 WKUIDelegate 的代理方法中获取到。

用户内容控制 WKUserContentController

  • 支持注入、移除 js 脚本
  • 支持 Web 内容规则
用户脚本 WKUserScript
WKUserScript *userScript = [[WKUserScript alloc] initWithSource:@"window.open('https://www.baidu.com')" 
injectionTime:(WKUserScriptInjectionTimeAtDocumentStart) 
forMainFrameOnly:YES];
属性解释:
  1. injectionTime: js 代码的注入时机,支持 WKUserScriptInjectionTimeAtDocumentStartWKUserScriptInjectionTimeAtDocumentEND,分别代表页面刚渲染前执行,和页面渲染后执行。
  2. forMainFrameOnly: 是否仅注入在主框架,还是包括所有的 iframe 全部注入。
添加用户脚本 addUserScript

使用 addUserScript 方法来添加 js 脚本。

移除所有用户脚本 removeAllUserScripts

如果注入时机为在网页渲染前,那么网页加载完毕后执行移除脚本操作,则脚本的运算结果并不会受影响,但是在网页加载完毕前移除脚本的后,脚本将不会执行。

添加脚本消息通道 addScriptMessageHandler

用于 Nativejs 通信,需要实现 WKScriptMessageHandler 协议。

WKUserContentController *userController = [[WKUserContentController alloc] init];
[userController addScriptMessageHandler:self name:@"JSBridge"];
[userController addScriptMessageHandler:self name:@"HWH5"];
conf.userContentController = userController;
JS代码
window.webkit.messageHandlers.JSBridge.postMessage(...args)
window.webkit.messageHandlers.HWH5.postMessage(...args)
  1. 可以在任何时机添加,可以添加多个
  2. 实现 WKScriptMessageHandler 协议,并实现 didReceiveScriptMessage 方法接受消息,通过 message.name 区分不通的协议
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    NSLog(@"%@", message.name);
}
移除脚本消息通道 removeScriptMessageHandlerForName

根据脚本消息通道名称移除对应的脚本消息通道。可以在任何时机移除,移除后对应的js代码也会移除。

iOS 11 以上支持内容过滤规则配置

该配置需要结合内容过滤器编译一起使用,通过对 js 指定的规则编译后得到一个 WKContentRuleList ,并且通过 userController 添加进 WebView 中。

存储 WKWebsiteDataStore

以下情况中,WKWebView 在主动发送请求时不会携带 cookie

  • Ajax 请求不会带上 ResponseSet-Cookie 的值
  • 302 跳转不会带上 ResponseSet-Cookie 的值

可以使用 iOS11 的新 API 对 WKWebView 进行 cookie 的设置,利用以下代码对 Cookie 进行持久化设置

NSHTTPCookie *cookie = ....;
[[WKWebsiteDataStore defaultDataStore].httpCookieStore setCookie:cookie ...];
  • 该方法如果在 WKWebView 初始化之前设置,则请求可以立马带上 Cookie

示例代码:

WKWebViewConfiguration *conf = [WKWebViewConfiguration new];

// 在初始化方法之前,设置 cookie
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithPropertie:...];
[[WKWebsiteDataStore defaultDataStore].httpCookieStore setCookie:cookie ...];

WKWebView *wk = [[WKWebView alloc] initWithFrame:CGRectZero configuration:conf];
[wk loadRequest:...];
  • 该方法如果在 loadRequest 之前设置 cookie,则请求不会立马带上该 Cookie,会在下次请求中携带该 cookie
WKWebViewConfiguration *conf = [WKWebViewConfiguration new];
WKWebView *wk = [[WKWebView alloc] initWithFrame:CGRectZero configuration:conf];

// 在初始化方法之后,设置 cookie
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithPropertie:...];
[[WKWebsiteDataStore defaultDataStore].httpCookieStore setCookie:cookie ...];

[wk loadRequest:...];

内容渲染控制 suppressesIncrementalRendering

是否等待 H5 内容全部加载完成后才开始渲染画面,默认为 NO,如果设置为 YES,则 H5 在加载完成之前一直处于白屏状态。

例如 H5 代码:

// 在测试H5页面尾巴处加入如下代码,可以查看区别。
<script type="text/javascript">
  setTimeout(function(){
      for(var i = 1; i<10000; i++)
      {
          alert(i);
      }
  })
</script>

追加 User-Agent applicationNameForUserAgent

不会覆盖原来的请求头重 User-Agent 的值属性,在之后追加自定义的内容。

网页多媒体播放

allowsAirPlayForMediaPlayback

是否允许 AirPlay 投屏播放,默认允许

mediaTypesRequiringUserActionForPlayback

哪些媒体文件需要强制用户进行手势交互后才能播放。

  1. WKAudiovisualMediaTypeNone = 0, // 默认无
  2. WKAudiovisualMediaTypeAudio = 1 << 0,// 音频
  3. WKAudiovisualMediaTypeVideo = 1 << 1, //视频
  4. WKAudiovisualMediaTypeAll = NSUIntegerMax// 所有

该属性将影响 H5video 标签的 autoplay 属性

allowsInlineMediaPlayback
  • 允许 H5 中的 Video 标签支持局部视频播放,不会全屏视频。
  • 需要配合 Video 标签的 playinline="true" 属性,就可以实现局部播放。
allowsPictureInPictureMediaPlayback

A Boolean value indicating whether HTML5 videos may play picture-in-picture.

允许 H5Video 标签支持画中画模式,默认 YES

可以使用 H5 中的 JS 代码实现画中画,video.requestPictureInPicture()iPhone 不支持,iPad 支持。

选择粒度 WKSelectionGranularity

用户可以交互选择web视图中的内容的粒度级别.默认是 WKSelectionGranularityDynamic 暂时不知道用于什么场景之下。

数据类型检测 WKDataDetectorTypes

支持识别 HTML 的中字符信息:

UIDataDetectorTypePhoneNumber // 手机号
UIDataDetectorTypeLink // 网页地址
UIDataDetectorTypeAddress // 邮件地址
UIDataDetectorTypeCalendarEvent //  格式化为日历事件的信息
UIDataDetectorTypeShipmentTrackingNumber // 快递包裹信息
UIDataDetectorTypeFlightNumber // 航班号信息
UIDataDetectorTypeLookupSuggestion // 用户可能要查找的信息
UIDataDetectorTypeNone // 默认,不检测
UIDataDetectorTypeAll // 识别全部信息

默认为 UIDataDetectorTypeNone,开启检测会影响网页渲染速度。

忽略网页缩放设置 ignoresViewportScaleLimits

ignoresViewportScaleLimits 是否忽略页面缩放限制,默认为 NO。

  • 如果配置为 YES,当前 Web 页面可以通过放大手势进行缩放。

和 H5 中的参数存在关联:

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=0.5,user-scalable=yes" />
  • minimum-scale=1
  • maximum-scale=1
  • user-scalable=yes

名称

ignoresViewportScaleLimits

NO

NO

YES

YES

user-scalable

YES

NO

YES

NO

结论

按照指定尺寸进行缩放

无法进行缩放

任意放大

任意放大

自定义拦截协议 iOS11 以上新支持

- (void)setURLSchemeHandler:(nullable id <WKURLSchemeHandler>)urlSchemeHandler 
 forURLScheme:(NSString *)urlScheme API_AVAILABLE(macos(10.13), ios(11.0));

- (nullable id <WKURLSchemeHandler>)urlSchemeHandlerForURLScheme:(NSString *)urlScheme API_AVAILABLE(macos(10.13), ios(11.0));

我们可以通过上述方法对 WKWebView 进行自定义协议拦截,无法拦截 httphttpswswssftp 协议。

示例代码:

[conf setURLSchemeHandler:[ViewSchemaHandler new] forURLScheme:@"h5"];

ViewSchemaHandler 实现协议中的内容

- (void)webView:(WKWebView *)webView startURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask
{
    // 在这里可以对同一资源进行本地缓存,无需要再次访问。
    NSMutableURLRequest *request = urlSchemeTask.request.mutableCopy;
    request.URL = [NSURL URLWithString:[request.URL.absoluteString stringByReplacingOccurrencesOfString:@"h5://" withString:@"http://"]];
    NSLog(@"%@", request.URL.absoluteURL);
    NSURLSession* session = [NSURLSession sharedSession];
    NSURLSessionTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        [urlSchemeTask didReceiveResponse:response];
        [urlSchemeTask didReceiveData:data];
        [urlSchemeTask didFinish];
    }];
    [task resume];
}
- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask
{
   // 当前urlSchemeTask由于某些原因提前结束了(会收到stopURLSchemeTask回调)
}

注意:

  • H5 前端所有想要拦截的 jscss 或者其他网络请求资源,需要将路径写成自适应协议路径,例如如下写法即可:
<script type="text/javascript" src="//192.168.1.150:3206/7.3.7/js/libs/jquery.min.js" ></script>
  • H5 前端所有想要拦截的 Ajax 请求,需要将请求更改为相对或者绝对路径,即可实现拦截
$.ajax({
 url:"/abcd"
});

可以利用上述特性实现应用秒开。

代理 WKNavigationDelegate

decidePolicyForNavigationAction 首先决定网页是否继续访问

可以通过 decidePolicyForNavigationAction 中的 decisionHandler 回调方法进行回调。

WKNavigationActionPolicyCancel 取消访问 WKNavigationActionPolicyAllow 允许继续访问,如果不实现该代理方法,则默认允许访问

示例代码:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
  // decisionHandler(WKNavigationActionPolicyCancel);
    decisionHandler(WKNavigationActionPolicyAllow);
}

iOS13 新增 WKWebpagePreferences

支持偏好设置,暂不理解。

decidePolicyForNavigationResponse 是否允许响应回调

是否允许响应回调,操作同 decidePolicyForNavigationAction 一致。

当主 Frame 开始加载页面 didStartProvisionalNavigation

didStartProvisionalNavigation 发起首次请求会执行这个方法,多次 302 重定向请求,该方法只会执行一次,发生 多次 302 跳转的时候,每次都会先执行 decidePolicyForNavigationAction ,如果这时候用户选择 cancel 操作,则 didReceiveServerRedirectForProvisionalNavigation 方法不会执行。

当服务器发起重定向请求 didReceiveServerRedirectForProvisionalNavigation

didReceiveServerRedirectForProvisionalNavigation,发生 302 重定向会走该方法

当容器在加载数据时发生了错误 didFailProvisionalNavigation

正常加载地址或者使用 js 中的 location.href 加载错误的地址发生失败会走该回调。

// oc 代码
[WKWebView loadRequest:] // 发生失败会走该回调
// js代码
location.href="http://abcd" // 发生失败会走该回调

当容器开始加载数据

didCommitNavigation,网络请求加载完成后执行。

当网页内容开始在主 Frame 开始渲染

didFinishNavigation 完成 js,css,html 渲染后执行。

在提交主 Frame 导航期间发生了错误

didFailNavigation,例如:

window.open("http://abcd") // 发生失败后会走该回调

当接受 HTTPS 请求证书后执行

didReceiveAuthenticationChallenge,可以通过 completionHandler 来选择对证书的操作,例如忽略证书。

/*
NSURLSessionAuthChallengeUseCredential = 0,                 使用证书
NSURLSessionAuthChallengePerformDefaultHandling = 1,   忽略证书(默认的处理方式)
NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2,     忽略书证, 并取消这次请求
NSURLSessionAuthChallengeRejectProtectionSpace = 3,            拒绝当前这一次, 下一次再询问
*/
// NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];

NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
 completionHandler(NSURLSessionAuthChallengeUseCredential , card);

当容器内容发生崩溃

webViewWebContentProcessDidTerminatewebView 内容发生崩溃而终止,将会执行该回调方法。

UI代理 WKUIDelegate

UI 代理方法,是 H5 部分 UI 操作和原生交互的代理方法,其中包括如下:

打开新的 WebView createWebViewWithConfiguration

H5 中需要打开新窗口的操作,都会被这个方法拦截,例如

<a href="https://www.baidu.com" target="_blank" >打开新窗口</a>
window.open("https://www.baidu.com");

关闭网页 webViewDidClose

H5 执行 window.close() 方法,则会执行这个代理方法。

提示信息 runJavaScriptAlertPanelWithMessage

H5 执行 window.alert(...args) 方法,则会执行这个代理方法,需要注意:

completionHandler 这个 block 方法必须执行,否则会发生崩溃,弹出窗口如果使用 UIAlertController 作为对接,则要考虑控制器是否存在,是否有并发的弹出窗操作,因为这些会导致 UIAlertController弹不出来,最终可能在逻辑上造成 completionHandler 无法执行导致崩溃,最好建议弹窗应该使用 UIView 设计。

确认信息提示框 runJavaScriptConfirmPanelWithMessage

H5 执行 window.confirm(...args),则会执行这个代理方法,注意事项同上。

输入提示框 runJavaScriptTextInputPanelWithPrompt

当H5执行 window.prompt(...args),则会执行这个代理方法,注意事项同上。

iOS 13 新增方法 contextMenu 的处理方法

contextMenu 的相关处理方法,暂时不理解在手机端有何用处。

FAQ

  • WKWebViewH5 css 动画失效的问题?

目前测试下来

  • [UIView snapshotViewAfterScreenUpdates:YES];
  • [UIView drawViewHierarchyInRect:CGRect afterScreenUpdates:YES];

这两种方法在进行系统 UIView 的截图操作时候并且将参数 afterScreenUpdates 设置为 YES 的情况下,最后 频繁调用后会导致 H5css 动画失效,原因不明。

作者:兜里有糖同志74828

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 网罗开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • WKWebView 初始化
    • WKWebViewConfiguration
    • 代理方法
      • WKNavigationDelegate
        • WKUIDelegate
        • 属性和方法
          • 历史记录管理
            • WKBackForwardList
              • WKBackForwardListItem
                • 网页加载
                  • 加载在线地址
                  • 加载本地地址
                  • Bundle下资源加载
                  • WKWebView 属性
              • WKWebViewConfiguration
                • 进程池 WKProcessPool
                  • 偏好设置 WKPreferences
                    • WKWebView 的偏好设置,支持以下设置:
                  • 用户内容控制 WKUserContentController
                    • 用户脚本 WKUserScript
                    • 添加用户脚本 addUserScript
                    • 移除所有用户脚本 removeAllUserScripts
                    • 添加脚本消息通道 addScriptMessageHandler
                    • 移除脚本消息通道 removeScriptMessageHandlerForName
                    • iOS 11 以上支持内容过滤规则配置
                • 存储 WKWebsiteDataStore
                  • 内容渲染控制 suppressesIncrementalRendering
                    • 追加 User-Agent applicationNameForUserAgent
                      • 网页多媒体播放
                        • allowsAirPlayForMediaPlayback
                        • mediaTypesRequiringUserActionForPlayback
                        • allowsInlineMediaPlayback
                        • allowsPictureInPictureMediaPlayback
                      • 选择粒度 WKSelectionGranularity
                        • 数据类型检测 WKDataDetectorTypes
                          • 忽略网页缩放设置 ignoresViewportScaleLimits
                            • 自定义拦截协议 iOS11 以上新支持
                            • 代理 WKNavigationDelegate
                              • decidePolicyForNavigationAction 首先决定网页是否继续访问
                                • iOS13 新增 WKWebpagePreferences
                                  • decidePolicyForNavigationResponse 是否允许响应回调
                                    • 当主 Frame 开始加载页面 didStartProvisionalNavigation
                                      • 当服务器发起重定向请求 didReceiveServerRedirectForProvisionalNavigation
                                        • 当容器在加载数据时发生了错误 didFailProvisionalNavigation
                                          • 当容器开始加载数据
                                            • 当网页内容开始在主 Frame 开始渲染
                                              • 在提交主 Frame 导航期间发生了错误
                                                • 当接受 HTTPS 请求证书后执行
                                                  • 当容器内容发生崩溃
                                                  • UI代理 WKUIDelegate
                                                    • 打开新的 WebView createWebViewWithConfiguration
                                                      • 关闭网页 webViewDidClose
                                                        • 提示信息 runJavaScriptAlertPanelWithMessage
                                                          • 确认信息提示框 runJavaScriptConfirmPanelWithMessage
                                                            • 输入提示框 runJavaScriptTextInputPanelWithPrompt
                                                              • iOS 13 新增方法 contextMenu 的处理方法
                                                                • FAQ
                                                                相关产品与服务
                                                                容器服务
                                                                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                                                领券
                                                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档