• iOS OC和JS的交互 javaScriptCore方法封装


    一、javaScriptCore

    javaScriptCore是一种JavaScript引擎,主要为webKit提供脚本处理能力,javaScriptCore是开源webkit的一部分,他提供了强大的整合能力.下面以JS调用OC方法为例,OC调用JS为例说明.

    • JSContext, JSContext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码
    • JSValue, JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等
    • JSExport, JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用

    二、封装源码

    注:JSExport 也可实现JS调用OC方法,但是个人感觉过于复杂,不如直接调用直接

    还可以使用WebViewJavascriptBridge第三方库去实现,具体的实现方式根据和后台人员商量决定

    根据实用性需求,封装出三个方法,一个初始化(要在UIWebview加载完成方法中创建) 一个JS调用OC的方法(id为JS传给OC的参数,id类型为JSValue数组) 一个是OC调用JS的方法(id为OC传递给JS的参数,类型根据需求定义)

    // 初始化

    + (instancetype)bridgeForWebView:(UIWebView *)webView;

    // JS调OC

    - (void)registerHandler:(NSString *)objcName handler:(JSHandler)handler;

    // OC调JS

    - (void)callHandler:(NSString*)jsName data:(id)data;

    /***********************************WebViewJavascriptBridge.h**********************************/

    #import <Foundation/Foundation.h>

    #import <UIKit/UIKit.h>

    #import <JavaScriptCore/JavaScriptCore.h>

    @protocol WebViewJavascriptBridgeProtocol <JSExport>

    // 通过JS调用OC方法 (采用代理的方法)

    - (void)CallOCFunction;

    - (void)CallOCFunctionFirstParameter:(NSString *)parameter;

    @end

    typedef void(^JSResponseCallback)(id responseData);

    typedef void(^JSHandler)(id data);

    @interface WebViewJavascriptBridge : NSObject <WebViewJavascriptBridgeProtocol>

    // 初始化

    + (instancetype)bridgeForWebView:(UIWebView *)webView;

    // JS调OC

    - (void)registerHandler:(NSString *)objcName handler:(JSHandler)handler;

    // OC调JS

    - (void)callHandler:(NSString*)jsName data:(id)data;

    @end

    /***********************************WebViewJavascriptBridge.m**********************************/

    #import "WebViewJavascriptBridge.h"

    @interface WebViewJavascriptBridge ()

    {

        JSContext *_jsContext;

        UIWebView *_webView;

    }

    @end

    @implementation WebViewJavascriptBridge

    static WebViewJavascriptBridge * gThis = nil;

    + (WebViewJavascriptBridge *) instance

    {

        if ( gThis == nil ){

            static dispatch_once_t onceToken;

            dispatch_once(&onceToken, ^{

                gThis = [[WebViewJavascriptBridge alloc] init];

            });

        }

        return gThis;

    }

    + (instancetype)bridgeForWebView:(UIWebView *)webView {

        WebViewJavascriptBridge *bridge = [self instance];

        [bridge platformSpecificSetup:webView];

        return bridge;

    }

    - (void)platformSpecificSetup:(UIWebView *)webView {

        _webView = webView;

        

        // 对JSContext对象进行初始化

        _jsContext = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

        

        // 验证JSContext对象是否初始化成功

        _jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {

          

            context.exception = exception;

            NSLog(@"异常信息:%@", exception);

        };

    }

    #pragma mark - public

    // objcName : oc函数名

    // handler  : block回调

    - (void)registerHandler:(NSString *)objcName handler:(JSHandler)handler {

        

        // 创建objcEcho对象赋值给js对象self

    //    _jsContext[objcName] = self;

        

        // JS调用OC函数

        _jsContext[objcName] = ^() {

            

            // 获取JS传来的参数 (JSValue对象数组)

            NSArray *args = [JSContext currentArguments];

            

            // 回调

            handler(args);

        };

    }

    // jsName : js函数名

    // data   : 传给js的参数

    // responseCallback 回调

    - (void)callHandler:(NSString*)jsName data:(id)data {

        

        // OC调用JS函数

        JSValue *jsValue = _jsContext[jsName];

        

        // 传字典

    //    NSDictionary *dict = @{@"key1" : @"参数1", @"key2" : @"参数2"};

        

        // 传对象

    //    Person *person = [[Person alloc] init];

    //    JSValue *value = [JSValue valueWithObject:person inContext:_jsContext];

    //    [value setValue:@"朱凯巍" forProperty:@"name"];

    //    [value setValue:@(10) forProperty:@"age"];

        

        // OC为JS传参数

        [jsValue callWithArguments:@[data]];

    }

    #pragma mark - JSWebViewObjectProtocol

    // 通过JS调用OC方法

    - (void)CallOCFunction {

        NSLog(@"%s",__func__);

    }

    - (void)CallOCFunctionFirstParameter:(NSString *)parameter {

        NSLog(@"%s",__func__);

    }

  • 相关阅读:
    状压DP
    数位dp
    浅谈网络最大流
    Luogu p2456 二进制方程
    dp基础√
    双联通分量与二分图
    是时候再写一篇新的博客了
    神仙网络最大流
    状态压缩dp相关
    图论 test solution
  • 原文地址:https://www.cnblogs.com/yang-shuai/p/7284080.html
Copyright © 2020-2023  润新知