橘莲溢香的学习笔记
  • 首页
  • 归档
  • 分类
  • 标签
  • 友链
  • 关于
  • 登录
bg
_
icon
Made with Next.js
Copyright © 2021 橘莲溢香京ICP备2021035188号

icon目录

  • UserAgent
  • 网络请求
    • httpRequest
  • 界面交互
    • showLoading
    • hideLoading
    • showModal
    • showToast
  • 图片相关
    • previewImage
    • saveImage
    • pickImage
    • uploadImage
    • playVideo
  • 数据存储
    • sessionStorage.setItem
    • sessionStorage.getItem
    • sessionStorage.removeItem
    • localStorage.setItem
    • localStorage.getItem
    • localStorage.removeItem
  • 事件通知
    • emitter.on
    • emitter.off
    • emitter.emit
  • 窗口控制
    • window.open
    • window.close
    • window.setProps
    • window.setGoBack
    • window.resetGoBack
    • 特殊参数
    • window.onblur
    • window.onfocus
    • backToHome
    • backPreviousPage
    • navigateTo
    • navigateBack
    • existRoute
    • presentMask
    • dismissMask
  • 设备功能
    • getDeviceInfo
    • scanQRcode
    • copyText
    • callPhone
    • navigation
  • 联系客服
    • contactService
  • 支付宝支付
    • tradePay
  • 微信分享
    • appShare
  • 用户登录
    • appLogin
  • 跟踪事件(埋点)
    • trackEvent

UserAgent

Native会定制浏览器的 UserAgent 的值,在末尾添加一段字符串,逗号拼接,H5可split或正则式判断。

host=gyyx-mobile // 运行在 移动端APP WebView中

app-name=cos // 应用名称:cos, lns , xfx

app-ver=1.36.2 // 应用版本

os-type=iOS // 系统统类型:iOS , Android

os-version=12.2 // 系统版本, 安卓端是 API Level

status-height=44 // 状态栏高度(留海高度)

比如 iOS WebView的 UserAgent 内容:

"Mozilla/5.0 AppleWebKit host=gyyx-mobile,os-type=iOS,app-name=cos,app-ver=1.57,os-version=14.6,status-height=44"

navigator.userAgent.split(/\s+/).pop().split(',').reduce((acc,curr)=> {
  const [k, v=''] = curr.split('='); 
  acc[k] = v; 
  return acc
}, {})

输出结果:

img

注意,APP使用的dsBridge有个限制:函数只能有一个参数,和一个回调(如果异步)。

参数的类型是string, 多个参数需要JSON.stringify({ k1: xxx, k2: yyy }) 。下文中 “参数:” 后面加了大括号的(参数:{...} ),需要JSON.stringify() 。

回调的参数也是string类型。下文中 “返回:” 后面加了大括号的(返回: {...} ), 需要JSON.parse() 。

建议使用 Typescript 版本的Bridge,它封装了dsBridge和JSON解析,参数类型定义清晰,方便易用。

网络请求

httpRequest

参数:

{
    url: 'https://app.gxcospower.cn/app_v1/account/user/logoff/reason/type/list'
    method: 'GET', // 默认'GET'。其他还有 POST, PATCH, PUT, DELETE
    params: { k1: xxx, k2: yyy } , // 请求参数,可选
    encode: 'form', // 默认'form'。还可以是'json'。 当method为GET/DELETE时,可忽略此参数
    headers: { token: xxxx } , // 可选
}

界面交互

showLoading

显示loading,还有一个类似的API: loadingShown

hideLoading

隐藏loading, 还有一个类似的API: loadingHidden

showModal

参数:

{
    title: string // 非必填,但 title 和 content 至少要填一个
    content: string // 非必填,但 title 和 content 至少要填一个
    contentAlignCenter: boolean // 内容文本水平居中?, 默认 false, 居左
    showCancel: boolean // 默认 true
    cancelText: string //默认 '取消'
    cancelColor: string // 默认'#333333'
    confirmText: string // 默认 '确定'
    confirmColor: string // 默认 APP主题色
}

返回字符串: 'confirm' 或 'cancel'

showToast

参数:

{
    title:string,
    style: string // 'success' | 'error' | 'info' ,默认 info
    duration: number // 毫秒,默认 2000
}

图片相关

previewImage

全屏预览图片,支持手势缩放、滑动切换

参数:

{
    imageUrls: ['url1', 'url2'...],
    index: 0 // 初始预览的索引。可选,默认0,第一张
}

saveImage

保存图片到相册

参数:

{
    imageUrls: ['url1', 'url2'...], // 或者
    imageBase64: 'base64 string', // base64格式 只支持一张图
}

返回:

{
    success: boolean,
    message: '...reason...' // 失败原因
}

pickImage

采集照片

参数:

{
    source?: number, // 照片来源,0:相册, 1:相机,2:让用户选择相机或相册。 默认相册
    crop?: boolean, // 是否需要裁剪
    cropRate?: number, // 如果需要裁剪,裁剪区域的高宽比,高/宽。(宽度是屏幕宽度)
    label?: string, // 为图片指定一个标识。后续要上传时,会用到此标识。
}

返回:

{
    success: boolean,
    data: '...base64String...', // base64格式
}

注意:原生会对照片做压缩处理:单张照片最大不超过300K, 宽或高最大1080p,超过则缩小至此值(等比缩小)

uploadImage

上传图片

参数:

{
    label: string, // 图片标识
    folder?: string, // 目录(图片上传的目录)
    service?: string, // 存储服务
}

返回:

{
    success: boolean,
    data: 'http://path/to/image',  // 图片url
}

playVideo

播放视频

参数:

{
    url: 'http://..../...mp4' // 视频链接
}

数据存储

sessionStorage.setItem

参数:{ key1: val1, key2: val2, ... }

sessionStorage.getItem

参数: key名称

sessionStorage.removeItem

参数: key名称

localStorage.setItem

参数:{ key1: val1, key2: val2, ... }

localStorage.getItem

参数: key名称

localStorage.removeItem

参数: key名称

注意:localStorage是持久存储,重启APP后不会丢失。 sessionStorage是临时存储,重启APP后会丢失。

存储能用来传递数据,比如原生和H5约定用“userInfo”做为key存取用户信息,原生存入,H5读出。反之亦然。

事件通知

emitter.on

监听事件。

参数:

{
    name: "事件名称",
    listener: "回调函数名称", // 通过dsBridge.register注册 回调函数。
    tag: '自定义标签' , // 可选,传递给回调函数的 额外参数。
    func: (arg:string) => void; // Typescript版本+,可免除显式register注册。
}

注意:目前一个事件只能关联一个回调函数,重复监听会发生覆盖。

emitter.off

取消监听。

参数:

{
    name: "事件名称",
    listener: "回调函数名称",// Typescript版本+
}

emitter.emit

发出事件。

参数:

{
    name: "事件名称",
    args: "事件参数",// 可选。多个参数可逗号拼接,或k1=v1&k2=v2, 或JSON.stringify({ k1: v1 })
}

H5发出的事件,原生能监听到; 原生发出的事件,H5也能监听到。 浏览器A中的H5发出的事件,浏览器B中的H5也能监听到。

环境参数或公共参数建议使用特殊命名,可以是大写或下划线,比如 来源页面,参数:_source_ 前后加下划线,以区别普通参数。

窗口控制

window.open

新开浏览器窗口,

参数:

{
    url: 'https://.....', 
    windowId: 'xxx', //窗口ID, 用于标识窗口。可选
    option: 'redirect', // 目前只支持一个值:redirect. 可选。
}

option: 'redirect': 页面A -> 页面窗口B,如果在B打开C时,使用了redirect,那么从C返回前一页时,会返回到A(不再是B).

常用场景是 第三方Web页面,如 微信文章,xx客服,xx商场,xx问卷调查 等,或者 技术实现不同,如 在React页面中打开jQurey实现的页面

注意:如果url值以 file:// 开头,会被认为是本地路径,尝试加载本地html文件

window.close

关闭浏览器窗口

参数:

{
    windowId: 'xxx', // 目标窗口ID, 可选
    serial: boolean, // 关闭连续的浏览器窗口,可选
}

如果不传参数,就关闭当前浏览器窗口

windowId: 从右向左查找相应windowId的Web窗口(可跨越非Web窗口),找到就显示此窗口(关闭其右侧的所有窗口),若找不到,则不做任何动作。 返回失败: {success:false,message:'未找到目标ID窗口'}

serial: 从右向左关闭Web窗口,只到不是Web窗口为止,如果第一个窗口也是Web窗口,则不做任何动作。返回失败:{success:false, message:'未找到非Web窗口'}

window.setProps

设置窗口属性

参数:

{
     windowId: string // 窗口ID, 可选
     backgroundColor: '#FAFAFA', // 底色,可选
}

window.setGoBack

定制返回行为, 参数:回调函数名称 (通过dsBridge.register注册)

// Typescript版本,使用第2个参数 可以免除显式register注册函数
function setGoBack(label: string, func?: () => void)

window.resetGoBack

恢复自然返回

返回行为:点击页面左上角的【返回】,或者从屏幕左边缘向右扫,或者按物理键返回(某些安卓手机有),

默认行为都是 返回上一页。但 原生APP的上一页 和 浏览器的上一页 不是一个概念。浏览器的上一页是历史回溯,history.back(),还能前进,history.forward(),而 原生返回上一页,当前页就彻底消失了。站在H5的角度理解,就是原生的每一页就相当于一个独立的浏览器,返回上一页就是把当前浏览器关闭了,其history 自然也随之消失。

为了使返回行为更为自然,原生先检查浏览器能否返回,若能,就调用浏览器的hostory.back(), 若不能,则走原生的返回,也就是关闭浏览器,暂时称这种返回方式为「自然返回」。

自然返回能满足大多数情况,然而有例外,比如 返回时提示:“......,确定返回吗?”,这时可以 定制返回行为(setGoBack),传入自定义函数,即 告诉原生:当返回行为触发时,不要自然返回,而是调用自定义函数。

代码示例:

// 指定(返回时调用的)函数名称:myBack
Bridge.window.setGoBack('myBack', () => {
    if (confirm('确定返回吗?')){
        Bridge.window.close() // 或 history.go(-1)
    }
); 

特殊参数

特殊的 url查询参数,前后缀下载线,拼接在url后面(? | &)。

  • _hidenavbar_

​ 隐藏页面导航栏。(导航栏是有标题 和 返回按钮 的那一栏)

只要url中出现这个参数:_hidenavbar_,就表示要隐藏,无论其值是什么

​ _hidenavbar_=0 // 0, 1, 2, 3

​ 它的值 指定 状态栏 的样式。(状态栏是有电池电量、信号强度 的那一栏):

​ 0 :隐藏状态栏,非0 不隐藏

​ 1: 状态栏前景色 白色

​ 2: 状态栏前景色 黑色

​ 3: 状态栏前景色 默认

  • _title_

​ 指定页面标题。

​ 不再取html中的<title>,而是使用url中的_title_ 参数的值做为页面标题.

注意:如果标题中包含中文,要经过 url编码。

window.onblur

当窗口将要不可见时(被新窗口覆盖,或退后台),原生将调用H5注册的 window.onblur 函数。

window.onfocus

当窗口可见或重新可见时(覆盖窗口消失,或回前台),原生将调用H5注册的 window.onfocus 函数。

页面初次加载完毕时,也会调用window.onfocus, 同时传入一个值为'loadFinish'的字符串参数。

注意:onblur和onfocus不是必需的,不注册也不会有问题。

backToHome

回首页

backPreviousPage

参数:

{
    checkHistory: true, // 先尝试history.back(),如果不可以,就关闭WebView窗口。默认false
}

返回前一页

navigateTo

页面导航

参数:

{
    url: 'app://xxx', 
    option: 'redirect', // 目前只支持一个值:redirect. 可选。(其作用 参考window.open)
}

和window.open不同,这里的url值是原生APP定义的页面路由,符合URL规则,可拼接查询参数.

对于换电APP,有一个特殊的路由:app://offline/[business]/[entry] ,意思是让原生APP导航到本地H5页面。

business指定业务模块,entry指定模块入口

navigateBack

页面返回

参数:

{
    route: 'app//xxx' // 页面路由
}

existRoute

导航栈中是否存在某页面

参数:

{
    route: 'app//xxx' // 页面路由
}

如果存在,返回“YES”, 否则 “” (空串)

presentMask

创建一个全屏透明浏览器窗口,遮罩在现有页面上方。

参数:

{
    url: "app://offline/<business>/<entry>",// business指定业务模块,entry指定模块入口
}

遮罩中的页面加载一定要快,为保证速度,这里不允许在线加载,只允许本地、离线加载。

dismissMask

关闭全屏遮罩,同时还可以附加一个动作,比如 导航至某页面,或打开浏览器,或广播事件。

参数:

{
  navUrl: string;  // 页面导航路径,同 navigateTo 的 url 参数。
  navOpt: string;  // 页面导航选项,同 navigateTo 的 option 参数。
  winOpenUrl: string; // 打开浏览器窗口的链接,同 window.open 的 url 参数。
  winOpenOpt: string; // 打开浏览器窗口的选项,同 window.open 的 option 参数。
  emitName: string;  // 发出事件的名称, 同 emitter.emit 的 name 参数。
  emitArg: string;  // 发出事件的参数, 同 emitter.emit 的 args 参数。
}

注意:可以不附加动作。如果要附加动作,只能附加一个,即 页面导航、打开浏览器、发出事件 三选一。

这个API的使用场景略微特殊:展示H5页面的浏览器(WebView)被做成一个 全屏的、透明的 浮层,覆盖在原页面上,达到的效果是 既能看到H5页面内容,也能看到(被覆盖在下面的)原页面内容。 比如 用H5实现一个弹框,覆盖在原生APP页面上,看上去就像原生实现的弹框。 而要关闭全屏透明的浏览器浮层,就要用到dismissMask。

设备功能

getDeviceInfo

设备信息

返回:

{
    equipmentId: "设备ID",
    appVersion: "应用版本",
    appType: "应用类型",
    osType: "操作系统类型",
    systemVersion: "操作系统版本",
    deviceModel: "设备型号",
    mac: "Mac地址",
    deviceBrand: "设备品牌",
    oaid: "安卓设备标识",
    androidid: "安卓ID",
    platform: "平台类型",
    deviceOs: "设备操作系统",
    deviceId: "设备ID",
    channel: "应用渠道",
    idfa: "广告ID",
}

scanQRcode

扫码

参数:

{
    notice: string; // 扫码页面上的 提示文案。比如 '请扫描担保二维码'
    showAlbum?: boolean; // 是否显示 相册按钮,默认false
    showNoCodeExchange?: boolean; // 是否显示 无码换电 按钮, 默认false
}

返回:

{
    code: string, // 二维码的值
    action: string, // 动作名称(用户没有扫码,而是点击了页面上的按钮(比如 【无码换电】)。
}

注意:code和action互斥。只会一个有值,另一个是空字符串。

目前 action只有一个取值:'noCodeExchange'

copyText

复制文本(至系统剪贴板)

参数:文本

callPhone

拨打电话

参数:电话号码

另: tel://18621529129,也应该可以拨打电话。

比如:<a href="tel://18621529129">联系某人

navigation

第三方导航

参数:

{ 
    longitude: "经度", 
    latitude: "纬度", 
    address: "地址名称"
} 

拉起的是Native中的第三方导航弹层,Native会检测当前设备中安装了哪些第三方导航软件,Android最多且仅支持拉起(高德、百度、腾讯),iOS最多且仅支持拉起(高德、百度、苹果);

联系客服

contactService

对于换电APP,它会弹出一个菜单(在线客服、电话客服)

支付宝支付

tradePay

参数:

{
    orderStr:string; // 接口返回的订单号
}

返回:

{
    resultStatus:string // 支付状态值
}

注意:虽然可以判断resultStatus,但有例外:用户不点支付宝的【确定】或【放弃】返回APP,而是通过Home键切换应用的方式 返回APP,这会导致无法回调resultStatus。推荐方式是监听窗口事件(window.onfocus),手动轮询支付结果。

微信分享

appShare

参数:

{
     title: string //卡片标题
     link: string //跳转目标链接,如果不是http开头,就用当前页面的url后面拼接这个值做为目标链接
     imgUrl: string //卡片图片logo
     desc: string //卡片描述
}

用户登录

appLogin

参数:自定义对象。

Native登录完成后(登录页关闭),会发一个事件通知:USER_LOGIN_SUCCESS, 参数是 token 值

// H5 监听用户登录事件,注册回调,回调函数的参数就是token值
Bridge.emitter.on({ 
  name: 'USER_LOGIN_SUCCESS', 
  listener: 'onLoginSuccess',
    func: (token: string) => {
    // 根据 token 请求数据
  }
});

Native同时会在本地存储中设置token值,key为 APP_USER_TOKEN。 退出登录时,也会清空token值。

// Native APP端 设置:
localStorage.setItem('APP_USER_TOKEN', token)// H5端无需设置,原生APP会设置
// H5 获取:
const token = Bridge.localStorage.getItem('APP_USER_TOKEN')

跟踪事件(埋点)

trackEvent

参数:

{ 
    name: "事件名称", 
    type: "事件类型", 
    category: "分类",
    params: { key1: val1, key2: val2, ... }
} 

params是个对象,可选,其属性和属性值 目前仅支持string类型

注意:在换电APP中,categroy的值是“lingGe”时,表示灵鸽埋点(取name),否则是普通埋点(取name+type)

1条留言
avatar
小狐狸

这些API如何使用,有Demo示例么?

作者回复: 有的,可参考:https://jvlian.cn/static/bridge/ds.html 这个是使用dsbridge原始方式调用的,还有一份TS封装版,本文档中部分示例使用了TS封装版本。

2024-03-24
login登录后留言