iOS原生与H5交互方法

UIWebView

Objective-C 调用 JavaScript

在使用UIWebView时,可以使用stringByEvaluatingJavaScriptFromString:方法来执行JavaScript代码。

示例代码:
NSString *result = [webView stringByEvaluatingJavaScriptFromString:@"returnFunction()"];
NSLog(@"JavaScript返回值: %@", result);

JavaScript 调用 Objective-C

通过自定义URL scheme实现。

使用webView的一个返回BOOL类型的监听网页的代理:shouldStartLoadWithRequest,在JS中,window.location.href = “hhh://callback”
在监听中监听头,然后把后面的string截取出来,用SEL变为函数名,然后调用

当在JavaScript中需要调用Objective-C代码时,可以通过改变window.location来触发Objective-C中的代理方法。

示例代码:

在Objective-C中,你可以在UIWebViewDelegatewebView:shouldStartLoadWithRequest:navigationType:方法中捕获这些请求:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {NSURL *URL = [request URL];if ([[URL scheme] isEqualToString:@"hhh"]) {NSString *functionName = [URL host]; // 获取"callback"SEL selector = NSSelectorFromString([functionName stringByAppendingString:@":"]);if ([self respondsToSelector:selector]) {[self performSelector:selector withObject:nil afterDelay:0];}return NO;}return YES;
}

在JavaScript中,你可以这样触发Objective-C代码:

window.location.href = "hhh://callback";

建议使用更安全的方式

虽然上述方法可行,但自定义URL scheme方法可能导致安全问题,例如,可能会被恶意利用执行未授权的方法。因此,推荐使用更安全和现代的方法如WKWebViewWKScriptMessageHandler进行Native和JavaScript的交互。

注意:UIWebView已经被苹果于弃用,使用会造成审核不通过,推荐使用WKWebView


WKWebView

1. JavaScriptCore

JavaScriptCore是一个JavaScript引擎,提供了与JavaScript上下文(context)的接口,可以用来执行JavaScript代码和访问JavaScript对象。JavaScriptCore封装了一些基础的JavaScript对象,如Date、Array等,并允许你定义自己的对象和函数。

原生调用H5

在Objective-C代码中执行你需要的JavaScript代码。

示例代码:

JSContext *context = [[JSContext alloc] init];// 执行JavaScript
[context evaluateScript:@"your javascript code here"];
H5调用原生

在Objective-C中,可以通过context[@"functionName"]来注册一个可以被JavaScript调用的方法。

示例代码:

JSContext *context = [[JSContext alloc] init];// 定义Objective-C block
context[@"log"] = ^(NSString *msg) {NSLog(@"JS: %@", msg);
};

然后在你的JavaScript代码中调用该方法:

log('Hello from JavaScript');

2. evaluateJavaScript

evaluate:评价,评估,估值

使用WKWebViewevaluateJavaScript方法调用JavaScript代码,并从中获取结果。

示例代码:

在Objective-C中通过WKWebView调用JavaScript:

#import <WebKit/WebKit.h>// 假设self.webView是你的WKWebView实例
WKWebView *webView = [[WKWebView alloc] init];// JavaScript代码字符串
NSString *script = @"document.title";// 执行JavaScript
[webView evaluateJavaScript:script completionHandler:^(id _Nullable result, NSError * _Nullable error) {if (error) {NSLog(@"JavaScript执行错误: %@", error);return;}NSLog(@"页面标题: %@", result);
}];

3. WKScriptMessageHandler

WKWebView提供了更现代和功能更强大的接口来与JavaScript交互。evaluateJavaScript:completionHandler:方法可以执行JavaScript代码,并通过回调接收结果。你也可以使用WKScriptMessageHandler创建一个消息处理器,当JavaScript通过window.webkit.messageHandlers.YourHandler.postMessage(data)发送消息时,你可以在Objective-C的userContentController:didReceiveScriptMessage:方法中接收到。

原生调用H5

在Objective-C中调用JavaScript代码,和JavaScriptCore类似,通过evaluateJavaScript:completionHandler:调用。

示例代码:

[webView evaluateJavaScript:@"your javascript code here" completionHandler:nil];
H5调用原生

首先在Objective-C中创建消息处理器:

// 在didFinishNavigation代理方法中添加JS调用OC的方法
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {// 注册一个name为hello的js方法[webView.configuration.userContentController addScriptMessageHandler:self name:@"hello"];
}//实现WKScriptMessageHandler此代理,然后在网页端通过window.webkit.messageHandlers.hello.postMessage({body: 'test'});即可调用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {NSLog(@"body: %@", message.body);
}

然后在JavaScript中,你可以使用下面的JavaScript代码发送消息到Objective-C:

window.webkit.messageHandlers.hello.postMessage({body: 'Hello, world!'});

以上就是JavaScriptCore和WKWebView的原生调用H5和H5调用原生的常用方式。

4. WKWebViewJavascriptBridge

WKWebViewJavascriptBridge是一个流行的开源库,用于在iOS应用中的WKWebView和HTML页面之间进行JavaScript与Objective-C或Swift代码的交互。它提供了一个简化的接口来发送消息和调用函数,使得原生代码和Web代码之间的通信更加便捷。

WKWebViewJavascriptBridge不完全属于之前提到的三种方法,它实际上是基于WKWebViewWKScriptMessageHandler封装而成的一个桥接工具,但它提供了更加高级和易用的API。

示例代码:

首先,项目中安装WKWebViewJavascriptBridge,通常通过CocoaPods安装:

pod 'WKWebViewJavascriptBridge', '~> 1.0.0'

然后,可以在你的Objective-C代码中这样使用它:

#import <WebKit/WebKit.h>
#import "WKWebViewJavascriptBridge.h"@interface ViewController ()@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) WKWebViewJavascriptBridge *bridge;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// 设置WebViewself.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];[self.view addSubview:self.webView];// 初始化bridgeself.bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];[self.bridge setWebViewDelegate:self];// 注册一个供JS调用的方法[self.bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {NSLog(@"testObjcCallback called: %@", data);responseCallback(@"Response from testObjcCallback");}];// 调用JS的方法[self.bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }];// 加载页面NSURL *url = [NSURL URLWithString:@"https://example.com"];[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}@end

在你的HTML/JavaScript中,你也需要设置对应的处理函数和调用:

// Connect to the Objective-C bridge
document.addEventListener('DOMContentLoaded', function() {window.WebViewJavascriptBridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {console.log("ObjC called testJavascriptHandler with", data);var responseData = { 'Javascript Says':'Right back atcha!' };responseCallback(responseData);});
});

这样,就设置了一个双向通信的桥,可以从JavaScript调用Objective-C代码,也可以从Objective-C调用JavaScript代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/1585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubesphere使用教程

一、简介 KubeSphere是一个开源的容器平台&#xff0c;它提供了Kubernetes集群的部署、运维和管理能力&#xff0c;并且具有友好的Web UI界面&#xff0c;降低了Kubernetes的使用门槛。本教程将引导你逐步了解KubeSphere的基本使用。 二、环境准备 准备至少三台服务器或虚拟…

Darknet,看过很多篇,这个最清晰了

Darknet深度学习框架&#xff1a;YOLO背后的强大支持 Darknet&#xff0c;一个由Joseph Redmon开发的轻量级神经网络框架&#xff0c;以其在计算机视觉任务&#xff0c;特别是目标检测中的卓越表现而闻名。本文将详细介绍Darknet的基本概念、结构以及它在深度学习领域的应用。…

UE4_动画基础_根运动Root Motion

学习笔记&#xff0c;仅供参考&#xff01; 在游戏动画中&#xff0c;角色的碰撞胶囊体&#xff08;或其他形状&#xff09;通常由控制器驱动通过场景。然后来自该胶囊体的数据用于驱动动画。例如&#xff0c;如果胶囊体在向前移动&#xff0c;系统就会知道在角色上播放一个跑步…

Kivy Pyinstaller Windows 打包

各种报错 ImportErrorWhenRunningHook: Failed to import module __PyInstaller_hooks_0_kivy required by hook for module 三天美好时光啥也没干&#xff0c;就研究这个了。 打包成功&#xff0c;运行应用程序exe闪退的。终于打包成功了。 这所有的原因都是因为我爱你。如果…

请编写一个函数int fun(int*s,int t,int *k),用来求出数组的最大元素在数组中的下标并存放在k所指的存储单元中。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法和详细的解析。 题干 请编写一个函…

小型架构实验模拟

一 实验需求 二 实验环境 22 机器&#xff1a; 做nginx 反向代理 做静态资源服务器 装 nginx keepalived filebeat 44机器&#xff1a; 做22 机器的备胎 装nginx keepalived 99机器&#xff1a;做mysql的主 装mysqld 装node 装filebeat 77机器&#xff1a;做mysq…

pytorch 今日小知识2——F.avg_pool2d、clamp

今天看到 def gem(self, ipts):return F.avg_pool2d(ipts.clamp(minself.eps).pow(self.p), (1, ipts.size(-1))).pow(1. / self.p) 这个函数中的F.avg_pool2d 不是很理解就查了一下 ipts.clamp(1.0e-6): 这个操作将ipts中的每个元素限制在[1.0e-6, inf)的范围内。也就是说&a…

【Python】——字典

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

【python】一文读懂python函数

【python】一文读懂python函数 文章目录 【python】一文读懂python函数(一)简单入门理解函数(二)函数的基本结构:(三)函数的默认值(四)可变参数(五)基于字典的可变参数(**可变参数)(六)函数中变量的作用域(七)lambda函数(八) 过滤函数filter()在Python中,…

谷歌Gemini 1.5 Pro国内怎么用?国内镜像来了

长期以来&#xff0c;许多人向我咨询是否存在一个稳定而高效的全球AI大模型测试平台&#xff0c;这个平台需要不仅真实可靠&#xff0c;而且能够提供稳定和快速的服务&#xff0c;不会频繁出现故障或响应缓慢的问题。然而&#xff0c;当我发现了AskManyAI时&#xff0c;我被其所…

蛋白质治病突变的计算方法(三)

3 用于识别致病突变的特征 文献中使用了几种特征来识别蛋白质中的致病突变。它们大致分为三类&#xff1a;(1)序列&#xff0c;(2)结构和(3)网络&#xff0c;以及它们的组合。图1说明了这三组中的一些重要属性。 图1 用于识别致病突变和热点的重要特征。 基于氨基酸序列的特性…

go下载依赖时超时timeout

go下载依赖时超时timeout go: module k8s.io/component-base/logs: Get “https://proxy.golang.org/k8s.io/component-base/logs/v/list”: dial tcp 172.217.160.113:443: i/o timeout 解决办法如下&#xff0c;运行命令&#xff1a; go env -w GO111MODULEon go env -w GO…

李宏毅2022机器学习/深度学习 个人笔记(3)

本系列用于推导、记录该系列视频中本人不熟悉、或认为有价值的知识点 本篇记录代码效果不佳时应该怎么做 如下图所示&#xff1a; 接下来探讨&#xff0c;当optimization不佳的时候&#xff0c;如何判断是遇到了鞍点还是遇到了局部最小值点&#xff1f;可以通过多元函数的泰勒…

【大语言模型+Lora微调】10条对话微调Qwen-7B-Chat并进行推理 (聊天助手)

代码&#xff1a;https://github.com/QwenLM/Qwen/tree/main 国内源安装说明&#xff1a;https://modelscope.cn/models/qwen/Qwen-7B-Chat/summary 通义千问&#xff1a;https://tongyi.aliyun.com/qianwen 一、环境搭建 下载源码 git clone https://github.com/QwenLM/Qwen…

是用computed获取vuex数据后,修改数据页面不响应的问题

问题描述&#xff1a; 代码里使用computed获取mapGetters的数据后&#xff0c;直接在页面使用&#xff0c;在methods中更新数据后&#xff0c;控制台打印数据已经更改&#xff0c;但是页面上的数据没有同步更改和响应。 分析&#xff1a; 1.computed是计算属性&#xff0c;所有…

【Linux 进程间通信】管道(三)

文章目录 1.管道的五种特征2.管道的四种情况 1.管道的五种特征 ①&#x1f34e;匿名管道只能用于有血缘关系的进程之间进行通信&#xff08;爷孙进程之间可以进行通信&#xff09;&#xff0c;常用于父子之间进行通信&#xff1b; ②&#x1f34e;管道内部&#xff0c;自带进…

【数据结构】时间复杂度的例题

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;数据结构 &#x1f337;追光的人&#xff0c;终会万丈光芒 前言&#xff1a; 这篇文章是关于时间复杂度的一些例题&#xff0c;关于时间复杂度和空间复杂度和算法的计算效率的基本知识点我放在…

Linux之C编程入门

目录 第1关&#xff1a;第一个C程序 任务描述 相关知识 编译C程序 编程要求 答案及其步骤&#xff1a; 第2关&#xff1a;Linux编译C程序 任务描述 相关知识 gcc编译器使用方法 编程要求 答案及其步骤&#xff1a; 第3关&#xff1a;Linux之静态库编写 任务描述 相关知识 生成…

Leetcode 3122. Minimum Number of Operations to Satisfy Conditions

Leetcode 3122. Minimum Number of Operations to Satisfy Conditions 1. 解题思路2. 代码实现 题目链接&#xff1a;3122. Minimum Number of Operations to Satisfy Conditions 1. 解题思路 这一题就是一个动态规划的思路&#xff0c;我们只需要对每一列取0到9的情况各自进…

玩转云计算:教你在Akamai Linode上构建IT架构—确定需求

时至今日&#xff0c;选择以云计算方式来运维业务&#xff0c;已经成为大部分情况下的最优选。那么如果要从零开始开发一个新应用&#xff0c;并依托云平台来设计、开发、部害和远维&#xff0c;具体该从何处下手&#xff1f;这一系列文章将介绍如何基于Akamai Linode平台实现这…