跳到主要内容

跨端开发

@cloudbase/js-sdk 只支持常规 Web 应用(即浏览器环境)的开发,不兼容其他类 Web 平台,比如微信小程序、快应用、Cocos 等。虽然这些平台大多支持 JavaScript 运行环境,但在网络请求、本地存储、平台标识等特性上与浏览器环境有明显差异。针对这些差异特性,@cloudbase/js-sdk 提供一套完整的适配扩展方案,遵循此方案规范可开发对应平台的适配器,然后搭配 @cloudbase/js-sdk 和适配器实现平台的兼容性。

适配规范#

开发适配器之前需要安装官方提供的接口声明模块@cloudbase/adapter-interface

# npmnpm i @cloudbase/adapter-interface# yarnyarn add @cloudbase/adapter-interface

适配器模块需要导出一个adapter对象:

const adapter = {  genAdapter,  isMatch,  // runtime标记平台唯一性  runtime: '平台名称'};
export adapter;export default adapter;

必须包含以下三个字段:

  • runtime: string,平台的名称,用于标记平台唯一性;
  • isMatch: Function,判断当前运行环境是否为平台,返回boolean值;
  • genAdapter: Function,创建adapter实体。

runtime#

runtime用于标记平台的唯一性,建议尽量以平台的英文名称或简写命名,比如百度小程序baidu_miniapp、QQ 小程序qq_miniapp等等。

isMatch#

isMatch函数用于判断当前运行环境是否与适配器匹配,通常是通过判断平台特有的一些全局变量、API 等。比如以下代码是判断运行环境是否为 Cocos 原生平台:

function isMatch(): boolean {  if (typeof cc === "undefined") {    return false;  }  if (typeof WebSocket === "undefined") {    return false;  }  if (typeof XMLHttpRequest === "undefined") {    return false;  }
  if (!cc.game) {    return false;  }  if (typeof cc.game.on !== "function") {    return false;  }  if (!cc.game.EVENT_HIDE) {    return false;  }  if (!cc.game.EVENT_SHOW) {    return false;  }
  if (!cc.sys) {    return false;  }  if (!cc.sys.isNative) {    return false;  }
  return true;}

genAdapter#

genAdapter函数返回适配器的实体对象,结构如下:

interface SDKAdapterInterface {  // 全局根变量,浏览器环境为window  root: any;  // WebSocket类  wsClass: WebSocketContructor;  // request类  reqClass: SDKRequestConstructor;  // 无localstorage时persistence=local降级为none  localStorage?: StorageInterface;  // 无sessionStorage时persistence=session降级为none  sessionStorage?: StorageInterface;  // storage模式首选,优先级高于persistence  primaryStorage?: StorageType;  // 获取平台唯一应用标识的api  getAppSign?(): string;}

示例#

import {  AbstractSDKRequest,  IRequestOptions,  IUploadRequestOptions,  StorageInterface,  WebSocketInterface,  WebSocketContructor,  SDKAdapterInterface,  StorageType,  formatUrl} from "@cloudbase/adapter-interface";
// isMatch函数判断当前平台是否匹配function isMatch(): boolean {  // ...  return true;}
// Request类为平台特有的网络请求,必须实现post/upload/download三个public接口export class Request extends AbstractSDKRequest {  // 实现post接口  public post(options: IRequestOptions) {    return new Promise((resolve) => {      // ...      resolve();    });  }  // 实现upload接口  public upload(options: IUploadRequestOptions) {    return new Promise((resolve) => {      // ...      resolve();    });  }  // 实现download接口  public download(options: IRequestOptions) {    return new Promise((resolve) => {      // ...      resolve();    });  }}// Storage为平台特有的本地存储,必须实现setItem/getItem/removeItem/clear四个接口export const Storage: StorageInterface = {  setItem(key: string, value: any) {    // ...  },  getItem(key: string): any {    // ...  },  removeItem(key: string) {    // ...  },  clear() {    // ...  }};// WebSocket为平台特有的WebSocket,与HTML5标准规范一致export class WebSocket {  constructor(url: string, options: object = {}) {    const socketTask: WebSocketInterface = {      set onopen(cb) {        // ...      },      set onmessage(cb) {        // ...      },      set onclose(cb) {        // ...      },      set onerror(cb) {        // ...      },      send: (data) => {        // ...      },      close: (code?: number, reason?: string) => {        // ...      },      get readyState() {        // ...        return readyState;      },      CONNECTING: 0,      OPEN: 1,      CLOSING: 2,      CLOSED: 3    };    return socketTask;  }}
// genAdapter函数创建adapter实体function genAdapter() {  const adapter: SDKAdapterInterface = {    // root对象为全局根对象,没有则填空对象{}    root: window,    reqClass: Request,    wsClass: WebSocket as WebSocketContructor,    localStorage: Storage,    // 首先缓存存放策略,建议始终保持localstorage    primaryStorage: StorageType.local,    // sessionStorage为可选项,如果平台不支持可不填    sessionStorage: sessionStorage  };  return adapter;}
// 三者缺一不可const adapter = {  genAdapter,  isMatch,  // runtime标记平台唯一性  runtime: "平台名称"};
export default adapter;

接入流程#

第 1 步:安装并引入适配器#

安装 @cloudbase/js-sdk 和所需平台的适配器,比如 QQ 小游戏平台:

# 安装 @cloudbase/js-sdknpm i @cloudbase/js-sdk# 安装 QQ 小游戏适配器npm i cloudbase-adapter-qq_game

然后在业务代码中将引入适配器:

import cloudbase from "@cloudbase/js-sdk";import adapter from "cloudbase-adapter-qq_game";
cloudbase.useAdapters(adapter);

第 2 步:配置安全应用来源#

云开发需验证请求来源的合法性,常规 Web 通过验证安全域名,而由于上文提到的诸多类 Web 环境并没有域名的概念,所以需要借助安全应用凭证区分请求来源是否合法。

登录云开发 CloudBase 控制台,在安全配置页面中的移动应用安全来源一栏:

点击“添加应用”按钮,输入应用标识:

caution

应用标识必须是能够标记应用唯一性的信息,比如微信小程序的appId、移动应用的包名等。

添加成功后会创建一个安全应用的信息,如下图所示:

第 3 步:初始化云开发#

在业务代码中初始化云开发时将第 2 步配置的安全应用信息作为参数传递给 init 方法:

import cloudbase from '@cloudbase/js-sdk';import adapter from 'cloudbase-adapter-qq_game';
cloudbase.useAdapters(adapter);
cloudbase.init({  env: '环境ID',  appSign: '应用标识',  appSecret: {    appAccessKeyId: '应用凭证版本号'    appAccessKey: '应用凭证'  }})
  • appSignstring,应用标识,对应上图中“应用标识”一栏;
  • appSecretObject,应用凭证信息,包括以下字段:
    • appAccessKeyIdstring,对应上图中“版本”一栏,同一个应用标识可以最多可以添加两个版本的凭证信息,以便区分开发和生产环境;
    • appAccessKeystring,对应上图中“操作”一栏点击“获取凭证”之后获取到的信息。
tip

appAccessKeyappAccessKeyId必须一一对应。

第 4 步:编写业务代码#

经过以上准备工作之后便可以编写自身的业务代码。

已有适配器#

目前已有的适配器可以在云开发社区官网中查看。

tip

所有适配器均来自社区贡献,欢迎更多开发者加入。

一套代码多端适配#

如果您需要将一套代码兼容多种平台,tcb-js-sdk 可以同时引入多个适配器,在运行时通过各适配器的isMatch函数判断平台类型,然后引入对应的兼容逻辑。比如以下代码可以同时兼容 QQ 小游戏、 Cocos 原生和百度小游戏三种平台:

import cloudbase from '@cloudbase/js-sdk';import adapter as adapterOfQQGame from 'cloudbase-adapter-qq_game';import adapter as adapterOfCocosNative from 'cloudbase-adapter-cocos_native';import adapter as adapterOfBDGame from 'cloudbase-adapter-bd_game';
cloudbase.useAdapters([  adapterOfQQGame,  adapterOfCocosNative,  adapterOfBDGame]);