native-message.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { browser, getRandomKey } from "/src/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. originalPostMessage(message, "*");
  12. };
  13. /**
  14. *
  15. * 目前已支持API
  16. *
  17. * openWebView
  18. *
  19. */
  20. export type CallBack = (evt?: IPostMessage) => void;
  21. const loop = () => {};
  22. const calls: { [key: string]: CallBack | CallBack[] } = {};
  23. const instance: any =
  24. (window as any).DAYA ||
  25. (window as any).webkit?.messageHandlers?.DAYA ||
  26. (window as any).COLEXIU ||
  27. (window as any).webkit?.messageHandlers?.COLEXIU ||
  28. (window as any).ORCHESTRA ||
  29. (window as any).webkit?.messageHandlers?.ORCHESTRA;
  30. if (instance) {
  31. window.addEventListener("message", (evt) => {
  32. try {
  33. const data = evt.data ? (typeof evt.data === "object" ? evt.data : JSON.parse(evt.data)) : {};
  34. const uuid = data.content?.uuid || data.uuid;
  35. try {
  36. if (data.content) {
  37. data.content = JSON.parse(data.content);
  38. }
  39. } catch (error) {}
  40. console.log("h5_接受_api:", data?.api, data.content);
  41. if (!uuid) {
  42. const keys = Object.keys(calls).filter((key) => key.indexOf(data.api) === 0);
  43. for (const key of keys) {
  44. const callback = calls[key] || loop;
  45. typeof callback === "function" && callback(data);
  46. if (Array.isArray(callback)) {
  47. callback.forEach((cb) => {
  48. typeof cb === "function" && cb(data);
  49. });
  50. }
  51. }
  52. return;
  53. }
  54. const callid = data.content?.uuid || data.uuid || data.api + data.uuid;
  55. const callback = calls[callid] || loop;
  56. typeof callback === "function" && callback(data);
  57. } catch (error) {
  58. console.error("通信消息解析错误", error);
  59. }
  60. });
  61. }
  62. export const postMessage = (data: IPostMessage, callback?: CallBack) => {
  63. if (instance) {
  64. const uuid = getRandomKey();
  65. calls[uuid] = callback || loop;
  66. data.content = data.content ? { ...data.content, uuid } : { uuid };
  67. instance.postMessage(JSON.stringify(data));
  68. console.log("h5_请求_api:", data);
  69. }
  70. };
  71. export const listenerMessage = (api: string, callback: CallBack) => {
  72. const uuid = api;
  73. if (!calls[uuid]) {
  74. calls[uuid] = [];
  75. }
  76. (calls[uuid] as CallBack[]).push(callback || loop);
  77. };
  78. export const removeListenerMessage = (api: string, callback: CallBack) => {
  79. const uuid = api;
  80. if (Array.isArray(calls[uuid])) {
  81. const indexOf = (calls[uuid] as CallBack[]).indexOf(callback);
  82. (calls[uuid] as CallBack[]).splice(indexOf, 1);
  83. }
  84. };
  85. export const promisefiyPostMessage = (data: IPostMessage): Promise<IPostMessage | undefined> => {
  86. return new Promise((resolve) => {
  87. postMessage(data, (res) => resolve(res));
  88. });
  89. };