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

相关推荐
问道飞鱼13 分钟前
【移动端知识】移动端多 WebView 互访方案:Android、iOS 与鸿蒙实现
android·ios·harmonyos·多webview互访
mascon2 小时前
U3D打包IOS的自我总结
ios
名字不要太长 像我这样就好2 小时前
【iOS】继承链
macos·ios·cocoa
karshey3 小时前
【IOS webview】IOS13不支持svelte 样式嵌套
ios
潜龙95273 小时前
第4.3节 iOS App生成追溯关系
macos·ios·cocoa
期待のcode10 小时前
图片上传实现
java·前端·javascript·数据库·servlet·交互
游戏开发爱好者812 小时前
iOS App 电池消耗管理与优化 提升用户体验的完整指南
android·ios·小程序·https·uni-app·iphone·webview
DogDaoDao14 小时前
GitHub开源轻量级语音模型 Vui:重塑边缘智能语音交互的未来
大模型·github·音视频·交互·vui·语音模型·智能语音
nbsaas-boot15 小时前
AI交互的初期魅力与后期维护挑战
人工智能·交互
神策技术社区18 小时前
iOS 全埋点点击事件采集白皮书
大数据·ios·app