# 与移动端通信

在混合开发时，一些 `h5` 页面经常会遇到与 `app` 交互,下面总结常用的场景

## 主动发事件,传值给app

常用的 `sendApp.js` 的 `demo` 如下结构

```js
class SendApp {
	constructor() {
		this.init()
	}
	init () {
		let platform = uni.getSystemInfoSync().platform
		this.isIos = platform === 'ios'
	}
	toJson (obj) {
		return JSON.stringify(obj)
	}
	// 安卓原生支付
	androidNativePay (orderNo, payType) {
		try {
			// payType 1：支付宝, 2:微信, 3:ios内购
			let obj = {orderNo: orderNo, payType: payType}
			let jsonStr = this.toJson(obj)
			if (this.isIos) {
        // ios不用管，使用小程序支付
				window.webkit.messageHandlers.androidNativePay.postMessage(jsonStr)
			} else {
				JsBridge.androidNativePay(jsonStr)
			}
		} catch(error) {
			console.log(error)
		}
	}
}
let sendApp = new SendApp()
export { sendApp }
```

## app主动调h5的方法，进行传值

常用的 `appReceive.js` 的 `demo` 如下结构

```js
import config from '../config'
const configAll = require('../index.js')
const jsBridge = {
	/**
	 * 初始化用户信息:供app执行load调用,isInApp 全局控制变量
	 * @param userInfo 用户信息JSON {token: '', userId: ''}
	 */
	init (userInfo) {
		config.isInApp = true
		// 测试json
		// '{"token": "deb5cfe6deb55c4e1416618354a1b844", "userId": 29}'
		let platform = uni.getSystemInfoSync().platform
		config.isIos = platform === 'ios'
		if (userInfo) {
			let userObj = JSON.parse(userInfo)
			config.appToken = userObj.token || ''
			config.appUserId = userObj.userId || ''
			uni.setStorageSync('userId', config.appUserId)
			uni.setStorageSync('access_token', config.appToken)
		}
	},
	/**
	 * 全局自定义返回上一页
	 */
	returnPrevPage () {
    // 判断页面栈,大于1返回上一页，等于1直接销毁webview
    let pages = getCurrentPages()
    if (pages.length > 1) {
      configAll.util.commonViewTap('', 99)
    } else {
      let tips = 'arrowBackDestroyPage'
      configAll.util.sendApp.leftArrowModifyClick(tips)
    }
	},
}
export { jsBridge }
```

## 在单页面应用中引入

1.  `jsBridge` 在 `main.js` 引入，挂在全局 `window` 下,这样 `app` 在 `load webview` 后可以调用

    ```js
    import { jsBridge } from './utils/communications/appReceive.js'
    window.jsBridge = jsBridge
    ```
2.  `sendApp` 挂在 `util` 对象下，方便调用

    ```js
    import { sendApp } from './communications/sendApp.js'

    module.exports = {
      sendApp: sendApp
    }
    ```

## 最优: h5主动获取token

::: code-group

```js
// 从app获取token
getTokenfromApp () {
  // 返回一个json字符串,前端自行反序列化
  // '{"token": "deb5cfe6deb55c4e1416618354a1b844", "userId": 29, "phone": '13396551860'}'
  let jsonStr = ''
  try {
    if (this.isIos) {
      // jsonStr = window.webkit.messageHandlers.addInitWebInfo.postMessage()
      // 此处ios原理是webview向网页中注入js,把用户信息写入缓存,然后h5读缓存
      jsonStr = xtyStorage.get(xtyStorage.loginTokenInfo)
    } else {
      jsonStr = AndroidObj.addInitWebInfo()
    }
  } catch (error) {
    console.log(error)
  }
  // 处理收尾单引号
  if (this.isIos) {
    return jsonStr ? this.toObj(jsonStr) : jsonStr
  }
  return jsonStr ? this.toObj(jsonStr.substr(1, jsonStr.length - 2)) : jsonStr
}
```

```js
export default {
  onLaunch: function () {
    console.log('App Launch')
    // 主动从app获取token
    util.getTokenFromApp()
  },
  onShow: function () {
    console.log('App Show')
  },
  onHide: function () {
    console.log('App Hide')
  }
}
```

:::
