iOS原生与H5交互方法

UIWebView

Objective-C 调用 JavaScript

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

示例代码:
c 复制代码
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:方法中捕获这些请求:

c 复制代码
- (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代码:

javascript 复制代码
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代码。

示例代码:

c 复制代码
JSContext *context = [[JSContext alloc] init];

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

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

示例代码:

c 复制代码
JSContext *context = [[JSContext alloc] init];

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

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

c 复制代码
log('Hello from JavaScript');

2. evaluateJavaScript

evaluate:评价,评估,估值

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

示例代码:

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

objc 复制代码
#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:调用。

示例代码:

c 复制代码
[webView evaluateJavaScript:@"your javascript code here" completionHandler:nil];
H5调用原生

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

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:

js 复制代码
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安装:

ruby 复制代码
pod 'WKWebViewJavascriptBridge', '~> 1.0.0'

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

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];

    // 设置WebView
    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.webView];

    // 初始化bridge
    self.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中,你也需要设置对应的处理函数和调用:

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代码。

相关推荐
hurrycry_小亦13 小时前
苹果WWDC 2026前瞻:Ferret-Pro端侧大模型即将亮相|小亦之闻|AI 编程三日速递!(5月26日~5月28日)
macos·ios·wwdc
UTF_817 小时前
一次NSMutableAttributedString误用的思考
ios·面试·github
Ulyanov21 小时前
深入QML-Python通信 构建响应式交互界面的桥梁设计:QML+PySide6现代开发入门(五)
开发语言·python·算法·交互·qml·系统仿真
人月神话-Lee21 小时前
【图像处理】Core Image 与 GPU 渲染管线——让滤镜飞起来
图像处理·人工智能·ios·chatgpt·ai编程·swift·gpu
郝学胜-神的一滴21 小时前
Qt 高级开发 019:从零定制登录窗口按钮、Logo 样式与交互悬浮效果
开发语言·c++·qt·程序人生·交互·用户界面
夏天的峰没有风1 天前
Typora+gitcode+picgo搭建免费图床
开发语言·ios·swift
库奇噜啦呼1 天前
【iOS】源码学习-分类、扩展、关联对象
学习·ios·分类
LONGZETECH1 天前
Unity 3D工业级教育软件实战:200+无人机装调任务的碰撞检测与交互落地
3d·unity·架构·游戏引擎·无人机·交互·cocos2d
不羁的木木1 天前
Form Kit(卡片开发服务)学习笔记04-交互事件与跳转处理
笔记·学习·交互·harmonyos
帅次2 天前
Android 17 开发者实战:核心更新与应用场景落地指南
android·java·ios·android studio·iphone·android jetpack·webview