native-message.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { browser, getRandomKey } from '@/helpers/utils'
  2. export interface IPostMessage {
  3. api: string
  4. content?: any
  5. }
  6. /**
  7. * 劫持postMessage
  8. */
  9. const originalPostMessage = window.postMessage
  10. window.postMessage = (message: IPostMessage) => {
  11. // console.log('通过劫持', message)
  12. originalPostMessage(message, '*')
  13. }
  14. /**
  15. *
  16. * 目前已支持API
  17. *
  18. * openWebView
  19. *
  20. */
  21. type CallBack = (evt?: IPostMessage) => void
  22. // eslint-disable-next-line @typescript-eslint/no-empty-function
  23. const loop = () => {}
  24. const calls: { [key: string]: CallBack | CallBack[] } = {}
  25. const browserInfo = browser()
  26. if (browserInfo.isApp) {
  27. window.addEventListener('message', evt => {
  28. try {
  29. console.log(evt, 'message', evt.data)
  30. const data = evt.data
  31. ? typeof evt.data === 'object'
  32. ? evt.data
  33. : JSON.parse(evt.data)
  34. : {}
  35. const uuid = data.content?.uuid || data.uuid
  36. console.log(uuid, data.content, 'uuid')
  37. try {
  38. if (data.content) {
  39. data.content = JSON.parse(data.content)
  40. }
  41. } catch (error) {
  42. //
  43. }
  44. if (data?.content?.uuid) {
  45. console.log('data', data)
  46. }
  47. if (!uuid) {
  48. const keys = Object.keys(calls).filter(
  49. key => key.indexOf(data.api) === 0
  50. )
  51. console.log(keys, 'keys')
  52. console.log(data, 'data')
  53. for (const key of keys) {
  54. const callback = calls[key] || loop
  55. typeof callback === 'function' && callback(data)
  56. }
  57. return
  58. }
  59. const callId = data.content?.uuid || data.uuid || data.api + data.uuid
  60. const callback = calls[callId] || loop
  61. console.log(data, 'data')
  62. typeof callback === 'function' && callback(data)
  63. } catch (error) {
  64. console.error('通信消息解析错误', error)
  65. }
  66. })
  67. }
  68. const instance: any =
  69. (window as any).COLEXIU || (window as any).webkit?.messageHandlers?.COLEXIU
  70. export const postMessage = (data: IPostMessage, callback?: CallBack) => {
  71. if (browserInfo.isApp) {
  72. const uuid = getRandomKey()
  73. calls[uuid] = callback || loop
  74. data.content = data.content ? { ...data.content, uuid } : { uuid }
  75. instance.postMessage(JSON.stringify(data))
  76. console.log('send:', JSON.stringify(data))
  77. }
  78. }
  79. // export const listenerMessage = (api: string, callback: CallBack) => {
  80. // console.log(browserInfo, 'browserInfo', api, 'api', callback)
  81. // if (browserInfo.isApp) {
  82. // const uuid = api
  83. // if (!calls[uuid]) {
  84. // calls[uuid] = []
  85. // }
  86. // ;(calls[uuid] as CallBack[]).push(callback || loop)
  87. // }
  88. // }
  89. export const listenerMessage = (api: string, callback: CallBack) => {
  90. if (browserInfo.isApp) {
  91. const uuid = api + getRandomKey()
  92. calls[uuid] = callback || loop
  93. }
  94. }
  95. export const removeListenerMessage = (api: string, callback: CallBack) => {
  96. if (browserInfo.isApp) {
  97. const uuid = api
  98. if (Array.isArray(calls[uuid])) {
  99. const indexOf = (calls[uuid] as CallBack[]).indexOf(callback)
  100. ;(calls[uuid] as CallBack[]).splice(indexOf, 1)
  101. }
  102. }
  103. }
  104. export const promisefiyPostMessage = (
  105. data: IPostMessage
  106. ): Promise<IPostMessage | undefined> => {
  107. return new Promise(resolve => {
  108. postMessage(data, res => resolve(res))
  109. })
  110. }