自定义 JSAPI

要从页面发起 Native 功能调用,例如显示一个 ActionSheet,或显示联系人对话框,您需要扩展一个 JavaScript API(JSAPI)。使用 JSAPI,可以让您在 H5 页面增加 Native 功能调用入口。通过实现自定义 JSAPI 类中的 handler 方法,以 Native 的形式实现特定功能。

H5 容器组件提供以下能力:

  • 丰富的内置 JSAPI,实现例如页面 push、pop、标题设置等功能。更多信息,请参见 内置 JSAPI

  • 支持用户自定义 JSAPI 和插件功能,扩展业务需求。

本文将结合 H5容器和离线包 Demo,自定义一个在 H5 页面加载时,修改页面导航栏的插件。

关于此任务

自定义一个 JSAPI 可以有以下两种方式:

  • Plist 注册

  • 代码注册

操作步骤

Plist 注册

  1. 创建 JSAPI 类:

    • 命名规范:为与容器默认提供的插件命名保持一致,创建的 JSAPI 类命名以 XXJsApiHandler4 开头,其中 XX 为自定义的前缀。

    • 基类:所有 JSAPI 均继承自 PSDJsApiHandler

    • 实现基础方法:在 .m 文件中,需重写方法 -(void)handler:context:callback:。当在前端调用此 JSAPI 时,会转发到此方法。

    • 该方法的参数含义如下:

      参数

      描述

      data

      H5 页面调用此 JSAPI 时传入的参数。

      context

      当前 H5 页面的上下文,具体可参考 PSDContext.h

      callback

      调用此 JSAPI 完成后的回调方法,以字典方式传递调用结果到 H5 页面。

      示例代码如下:

        #import <NebulaPoseidon/NebulaPoseidon.h>
        @interface MPJsApiHandler4OpenSms : PSDJsApiHandler
        @end
        @implementation MPJsApiHandler4OpenSms
        - (void)handler:(NSDictionary *)data context:(PSDContext *)context callback:(PSDJsApiResponseCallbackBlock)callback
        {
        [super handler:data context:context callback:callback];
        // 打开系统短信
        NSURL *url = [NSURL URLWithString:@"sms://xxx"];
        BOOL reasult = [[UIApplication sharedApplication] openURL:url];
        callback(@{@"success":@(reasult)});
        }
        @end
  2. 注册 JSAPI。在自定义的 Plist 文件中注册此 JSAPI。

    • 为统一管理自定义的 JSAPI 和 Plugin,新建一个 Plsit 文件,您可以直接下载此模板文件 DemoCustomPlugins.bundle.zip 并添加到工程中。

    • JsApis 数组下注册上一步创建的 JSAPI 类:111

    • 注册的 JSAPI 是一个字典类型,包含以下两项内容:

      名称

      描述

      jsApi

      在 H5 页面中调用的 JSAPI 接口名。

      重要

      为防止自定义的 JSAPI 与容器内置 JSAPI 相互影响导致不可用,请给自定义 JSAPI 名加上前缀予以区分。

      name

      创建的 JSAPI 的类名。

    • 同时需在初始化容器配置时,指定自定义的 Plist 文件的路径。

      示例代码如下:

        - (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
        {  
            // 初始化容器
            // [MPNebulaAdapterInterface initNebula];
      
            // 自定义 JSAPI 路径和预置离线包信息
            NSString *presetApplistPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPresetApps.bundle/h5_json.json"] ofType:nil];
            NSString *appPackagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPresetApps.bundle"] ofType:nil];
            NSString *pluginsJsapisPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPlugins.bundle/Poseidon-UserDefine-Extra-Config.plist"] ofType:nil];
            [MPNebulaAdapterInterface initNebulaWithCustomPresetApplistPath:presetApplistPath customPresetAppPackagePath:appPackagePath customPluginsJsapisPath:pluginsJsapisPath]
        }

代码注册

除使用 Plist 方式自定义一个 JSAPI 外,容器也支持直接调用 Nebula 容器提供的接口方法注册一个自定义的 JSAPI。

  1. 参考 自定义插件 文档,新建一个 Plugin。

  2. 在 Plugin 中实现 addJSApis 方法。

     - (void)addJSApis
     {
         [super addJSApis];
    
         // 代码注册 jsapi
         PSDJsApi *jsApi4DemoTest2 = [PSDJsApi jsApi:@"demoTest2"
                                               handler:^(NSDictionary *data, PSDContext *context, PSDJsApiResponseCallbackBlock responseCallbackBlock) {
                                                   responseCallbackBlock(@{@"result":@"jsapi-demoTest2调用 Native 的处理结果"});
                                               }
                                           checkParams:NO
                                             isPrivate:NO
                                                 scope:self.scope];
         [self registerJsApi2Target:jsApi4DemoTest2];
     }
    • 下表列出注册时各参数及其含义:

      参数

      描述

      jsApi

      在 H5 页面中调用的 JSAPI 接口名。

      handler

      JSAPI 处理函数,功能同 Plist 注册方式中的 handler 方法。

      checkParams

      是否检查参数,请设置为 NO。

      isPrivate

      是否私有 JSAPI,请设置为 NO。

      scope

      作用域,请设置为 self.scope。

具体示例,请参考代码示例中 MPPlugin4TitleView 类相关实现。

后续操作

  1. 在 H5 页面中调用自定义的 JSAPI。

    53
  2. 在 handler 方法中添加断点,观察 H5 页面提供的参数是否符合预期。

    54
  3. 查看 H5 页面返回的结果是否符合预期。

    55