• iOS原生与H5交互方法


    UIWebView

    Objective-C 调用 JavaScript

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

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

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

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

    建议使用更安全的方式

    虽然上述方法可行,但自定义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"];
    
    • 1
    • 2
    • 3
    • 4
    H5调用原生

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

    示例代码:

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

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

    log('Hello from JavaScript');
    
    • 1

    2. evaluateJavaScript和WKScriptMessageHandler

    evaluate:评价,评估,估值

    evaluateJavaScript:实现原生调用H5

    使用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);
    }];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    WKScriptMessageHandler:实现H5调用原生

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

    首先在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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    以上就是使用
    evaluateJavaScript 来实现原生调用H5
    WKScriptMessageHandler 来实现H5调用原生

    3. WKWebViewJavascriptBridge

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

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

    示例代码:

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

    pod 'WKWebViewJavascriptBridge', '~> 1.0.0'
    
    • 1

    然后,可以在你的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];
    
        // 设置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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在你的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);
        });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

  • 相关阅读:
    如何通过进程启动来分析和解决EasyCVR内核端口报错问题?
    数字化采购管理系统开发:精细化采购业务流程管理,赋能企业实现“阳光采购”
    2022-11-30 mysql-innodb-ibd文件读取工具
    【洛谷题解】P1036 [NOIP2002 普及组] 选数
    版本号正则校验及大小比较
    【Java 进阶篇】数据库介绍与MySQL详细介绍
    flutter显示这样的错误如何解决
    【C++】C++的IO流
    用Python开发QQ机器人详解
    告别互信息:跨模态人员重新识别的变分蒸馏
  • 原文地址:https://blog.csdn.net/IOSSHAN/article/details/137957561