ios下OC与JS交互之WKWebView
发布时间 - 2026-01-11 00:02:18 点击率:次上一篇文章我们使用了JavaScriptCore框架重写了之前的示例,iOS8苹果偏爱HTML5,重构了UIWebVIew,给我们带来了WKWebView,使其性能、稳定性、功能大幅度提升,也更好的支持了HTML5的新特性。这篇文章就们就拿WKWebView来小试牛刀

一、WKWebView Framework
WKWebView的14个类与3个协议:
WKBackForwardList: 之前访问过的 web 页面的列表,可以通过后退和前进动作来访问到。
WKBackForwardListItem: webview 中后退列表里的某一个网页。
WKFrameInfo: 包含一个网页的布局信息。
WKNavigation: 包含一个网页的加载进度信息。
WKNavigationAction: 包含可能让网页导航变化的信息,用于判断是否做出导航变化。
WKNavigationResponse: 包含可能让网页导航变化的返回内容信息,用于判断是否做出导航变化。
WKPreferences: 概括一个 webview 的偏好设置。
WKProcessPool: 表示一个 web 内容加载池。
WKUserContentController: 提供使用 JavaScript post 信息和注射 script 的方法。
WKScriptMessage: 包含网页发出的信息。
WKUserScript: 表示可以被网页接受的用户脚本。
WKWebViewConfiguration: 初始化 webview 的设置。
WKWindowFeatures: 指定加载新网页时的窗口属性。
WKWebsiteDataStore: 包含网页数据存储和查找。
WKNavigationDelegate: 提供了追踪主窗口网页加载过程和判断主窗口和子窗口是否进行页面加载新页面的相关方法。
WKUIDelegate: 提供用原生控件显示网页的方法回调。
WKScriptMessageHandler: 提供从网页中收消息的回调方法。
二、WKWebView中的三个代理方法
1. WKNavigationDelegate
该代理提供的方法,可以用来追踪加载过程(页面开始加载、加载完成、加载失败)、决定是否执行跳转。
// 页面开始加载时调用 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation; // 当内容开始返回时调用 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation; // 页面加载完成之后调用 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation; // 页面加载失败时调用 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
页面跳转的代理方法有三种,分为(收到跳转与决定是否跳转两种)
// 接收到服务器跳转请求之后调用 - (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;
2. WKUIDelegate
创建一个新的WKWebView
// 创建一个新的WebView - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
剩下三个代理方法全都是与界面弹出提示框相关的,针对于web界面的三种提示框(警告框、确认框、输入框)分别对应三种代理方法。
// 界面弹出警告框 - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler; // 界面弹出确认框 - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler; // 界面弹出输入框 - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
3. WKScriptMessageHandler
这个协议中包含一个必须实现的方法,这个方法是native与web端交互的关键,它可以直接将接收到的JS脚本转为OC或Swift对象。
// 从web界面中接收到一个脚本时调用 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
三、使用WKWebView重写
这里我们和之前的界面做了一点改动,之前OC调用JS的时候是进行弹框处理,这里我在写的时候,很郁闷,方法可以调用过去,但是唯独js的alert方法调用没有效果,所以这里采用了输出到div的形式,并增加了一个clear按钮
WKWebView不支持nib文件,所以这里需要使用代码初始化并加载WebView
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; config.preferences.minimumFontSize = 18; self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2) configuration:config]; [self.view addSubview:self.wkWebView]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; NSURL *baseURL = [[NSBundle mainBundle] bundleURL]; [self.wkWebView loadHTMLString:[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] baseURL:baseURL];
OC端:
//1. JS调用OC 添加处理脚本
[userCC addScriptMessageHandler:self name:@"showMobile"];
[userCC addScriptMessageHandler:self name:@"showName"];
[userCC addScriptMessageHandler:self name:@"showSendMsg"];
// 在代理方法中处理对应事件
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",NSStringFromSelector(_cmd));
NSLog(@"%@",message.body);
if ([message.name isEqualToString:@"showMobile"]) {
[self showMsg:@"我是下面的小红 手机号是:18870707070"];
}
if ([message.name isEqualToString:@"showName"]) {
NSString *info = [NSString stringWithFormat:@"你好 %@, 很高兴见到你",message.body];
[self showMsg:info];
}
if ([message.name isEqualToString:@"showSendMsg"]) {
NSArray *array = message.body;
NSString *info = [NSString stringWithFormat:@"这是我的手机号: %@, %@ !!",array.firstObject,array.lastObject];
[self showMsg:info];
}
}
// 2. native调用js
- (IBAction)btnClick:(UIButton *)sender {
if (!self.wkWebView.loading) {
if (sender.tag == 123) {
[self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
//TODO
NSLog(@"%@ %@",response,error);
}];
}
if (sender.tag == 234) {
[self.wkWebView evaluateJavaScript:@"alertName('小红')" completionHandler:nil];
}
if (sender.tag == 345) {
[self.wkWebView evaluateJavaScript:@"alertSendMsg('18870707070','周末爬山真是件愉快的事情')" completionHandler:nil];
}
} else {
NSLog(@"the view is currently loading content");
}
}
JS端:
function clear() {
document.getElementById('mobile').innerHTML = ''
document.getElementById('name').innerHTML = ''
document.getElementById('msg').innerHTML = ''
}
//OC调用JS的方法列表
function alertMobile() {
//这里已经调用过来了 但是搞不明白为什么alert方法没有响应
//alert('我是上面的小黄 手机号是:13300001111')
document.getElementById('mobile').innerHTML = '我是上面的小黄 手机号是:13300001111'
}
function alertName(msg) {
//alert('你好 ' + msg + ', 我也很高兴见到你')
document.getElementById('name').innerHTML = '你好 ' + msg + ', 我也很高兴见到你'
}
function alertSendMsg(num,msg) {
//window.alert('这是我的手机号:' + num + ',' + msg + '!!')
document.getElementById('msg').innerHTML = '这是我的手机号:' + num + ',' + msg + '!!'
}
//JS响应方法列表
function btnClick1() {
window.webkit.messageHandlers.showMobile.postMessage(null)
}
function btnClick2() {
window.webkit.messageHandlers.showName.postMessage('xiao黄')
}
function btnClick3() {
window.webkit.messageHandlers.showSendMsg.postMessage(['13300001111', 'Go Climbing This Weekend !!!'])
}
四、后记
至此,整个系列的示例已完成,过程中收货颇丰。每篇文章都会对知识点进行总结,在文章末尾给出示例DEMO的地址。
示例DEMO:OC-JS-WKWebView_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# wkwebview
# js交互
# ios
# oc
# react native reanimated实现动画示例详解
# react-native 封装视频播放器react-native-video的使用
# React Native全面屏状态栏和底部导航栏适配教程详细讲解
# java Nio使用NioSocket客户端与服务端交互实现方式
# iOS 16 CocoaAsyncSocket 崩溃修复详解
# iOS底层实例解析Swift闭包及OC闭包
# React Native与iOS OC之间的交互示例详解
# 加载
# 跳转
# 这是
# 弹出
# 我是
# 也很
# 能让
# 三种
# 你好
# 创建一个
# 回调
# 小红
# 输入框
# 小黄
# 都是
# 判断是否
# 我在
# 两种
# 给我们
# 不明白
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
在线制作视频网站免费,都有哪些好的动漫网站?
创业网站制作流程,创业网站可靠吗?
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】
bing浏览器学术搜索入口_bing学术文献检索地址
如何在阿里云服务器自主搭建网站?
什么是JavaScript解构赋值_解构赋值有哪些实用技巧
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
使用C语言编写圣诞表白程序
JavaScript如何实现音频处理_Web Audio API如何工作?
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
如何在阿里云香港服务器快速搭建网站?
Laravel怎么在Blade中安全地输出原始HTML内容
香港服务器部署网站为何提示未备案?
如何在阿里云通过域名搭建网站?
Laravel怎么判断请求类型_Laravel Request isMethod用法
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
网站建设保证美观性,需要考虑的几点问题!
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
Laravel如何升级到最新版本?(升级指南和步骤)
如何快速选择适合个人网站的云服务器配置?
JavaScript常见的五种数组去重的方式
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
Laravel如何生成API文档?(Swagger/OpenAPI教程)
Laravel storage目录权限问题_Laravel文件写入权限设置
nodejs redis 发布订阅机制封装实现方法及实例代码
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
JS碰撞运动实现方法详解
iOS UIView常见属性方法小结
如何在香港免费服务器上快速搭建网站?
Laravel如何操作JSON类型的数据库字段?(Eloquent示例)
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
JS去除重复并统计数量的实现方法
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧
微信小程序制作网站有哪些,微信小程序需要做网站吗?
济南网站建设制作公司,室内设计网站一般都有哪些功能?
Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门
如何快速打造个性化非模板自助建站?
原生JS获取元素集合的子元素宽度实例
如何快速登录WAP自助建站平台?
网站页面设计需要考虑到这些问题
Laravel怎么实现验证码(Captcha)功能
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
如何挑选优质建站一级代理提升网站排名?
如何登录建站主机?访问步骤全解析

