全部产品

自定义 JSAPI

更新时间:2020-09-15 17:08:24

要从页面发起 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 类命名以 XXJsApi4 开头,其中 XX为自定义的前缀。
    • 基类:所有 JSAPI 均继承自 PSDJsApiHandler
    • 实现基础方法:在 .m文件中,需重写方法 -(void)handler:context:callback:。当在前端调用此 JSAPI 时,会转发到此方法。
    • 该方法的参数含义如下:

      参数名 含义
      data H5 页面调用此 JSAPI 时传入的参数。
      context 当前 H5 页面的上下文,具体可参考 PSDContext.h
      callback 调用此 JSAPI 完成后的回调方法,以字典方式传递调用结果到 H5 页面。

      示例代码如下:

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

    • 为统一管理自定义的 JSAPI 和 Plugin,新建一个 plsit 文件,您可以直接下载此模板文件 DemoCustomPlugins.bundle.zip 并添加到工程中。
    • JsApis 数组下注册上一步创建的 JSAPI 类:
      111
    • 注册的 JSAPI 是一个字典类型,包含以下两项内容:

      名称 含义
      jsApi 在 H5 页面中调用的 JSAPI 接口名。
      注意: 为防止自定义的 JSAPI 与容器内置 JSAPI 相互影响导致不可用,请给自定义 JSAPI 名加上前缀予以区分。
      name 创建的 JSAPI 的类名。
    • 同时需在初始化容器配置时,指定自定义的 Plist 文件的路径。
  1. ```objective-c
  2. - (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  3. {
  4. // 初始化容器
  5. // [MPNebulaAdapterInterface initNebula];
  6. // 自定义jsapi路径和预置离线包信息
  7. NSString *presetApplistPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPresetApps.bundle/h5_json.json"] ofType:nil];
  8. NSString *appPackagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPresetApps.bundle"] ofType:nil];
  9. NSString *pluginsJsapisPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPlugins.bundle/Poseidon-UserDefine-Extra-Config.plist"] ofType:nil];
  10. [MPNebulaAdapterInterface initNebulaWithCustomPresetApplistPath:presetApplistPath customPresetAppPackagePath:appPackagePath customPluginsJsapisPath:pluginsJsapisPath]
  11. }
  12. ```

代码注册

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

  1. 参考 自定义插件 文档,新建一个 Plugin。
  2. 在 Plugin 中实现 addJSApis 方法。

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

      参数 含义
      jsApi 在 H5 页面中调用的 JSAPI 接口名。
      handler JSAPI 处理函数,功能同 Plist 注册方式中的 handler 方法。
      checkParams 是否检查参数,请设置为 NO。
      isPrivate 是否私有 JSAPI,请设置为 NO。
      scope 作用域,请设置为 self.scope。
  1. 具体示例,请参考 代码示例 中 MPPlugin4TitleView 类相关实现。

后续操作

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

    1

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

    2

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