-
Notifications
You must be signed in to change notification settings - Fork 208
/
MobileRpcManager.ts
98 lines (84 loc) · 3.96 KB
/
MobileRpcManager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2019 Bentley Systems, Incorporated. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license terms.
*--------------------------------------------------------------------------------------------*/
/** @module RpcInterface */
import { RpcInterfaceDefinition } from "../../RpcInterface";
import { RpcConfiguration } from "../core/RpcConfiguration";
import { RpcEndpoint, RpcMobilePlatform } from "../core/RpcConstants";
import { interop, MobileRpcProtocol } from "./MobileRpcProtocol";
import { IModelError } from "../../IModelError";
import { BentleyStatus } from "@bentley/bentleyjs-core";
/** Holds configuration for the RpcInterfaces used by the application.
* @beta
*/
export abstract class MobileRpcConfiguration extends RpcConfiguration {
public abstract protocol: MobileRpcProtocol;
private static getArgs(): any {
if (typeof window === "undefined") {
return {};
}
const queryArgs: any = {};
const matches = window.location.hash.match(/([^#=&]+)(=([^&]*))?/g);
if (matches) {
for (const comp of matches) {
const array = comp.split("=");
if (array.length === 2) {
const key = decodeURIComponent(array[0]);
const val = decodeURIComponent(array[1]);
queryArgs[key] = val;
} else {
throw new IModelError(BentleyStatus.ERROR, "Unexpected parameters");
}
}
}
return queryArgs;
}
private static getMobilePlatform(): RpcMobilePlatform {
if (!MobileRpcConfiguration.args.platform)
return RpcMobilePlatform.Unknown;
const win: any = window;
if (/android/i.test(MobileRpcConfiguration.args.platform)) {
return RpcMobilePlatform.Android;
}
if (/iOS|iPadOS/i.test(MobileRpcConfiguration.args.platform) && !win.MSStream) {
return RpcMobilePlatform.iOS;
}
return RpcMobilePlatform.Unknown;
}
/** Read the mobile rpc args */
public static readonly args: any = MobileRpcConfiguration.getArgs();
/** Return type of mobile platform using browser userAgent */
public static readonly platform: RpcMobilePlatform = MobileRpcConfiguration.getMobilePlatform();
/** Check if running backend running on mobile */
public static get isMobileBackend() { return interop !== null; }
/** Check if running backend running on mobile */
public static get isMobileFrontend() { return this.platform !== RpcMobilePlatform.Unknown; }
/** Check if running backend running on wkwebview on ios */
public static get isIOSFrontend() { return MobileRpcConfiguration.isMobileFrontend && (window as any).webkit && (window as any).webkit.messageHandlers; }
}
/** Coordinates usage of RPC interfaces for an Mobile-based application.
* @beta
*/
export class MobileRpcManager {
private static performInitialization(interfaces: RpcInterfaceDefinition[], endPoint: RpcEndpoint): MobileRpcConfiguration {
const config = class extends MobileRpcConfiguration {
public interfaces = () => interfaces;
public protocol: MobileRpcProtocol = new MobileRpcProtocol(this, endPoint);
};
for (const def of interfaces) {
RpcConfiguration.assign(def, () => config);
}
const instance = RpcConfiguration.obtain(config);
RpcConfiguration.initializeInterfaces(instance);
return instance;
}
/** Initializes MobileRpcManager for the frontend of an application. */
public static initializeClient(interfaces: RpcInterfaceDefinition[]): MobileRpcConfiguration {
return MobileRpcManager.performInitialization(interfaces, RpcEndpoint.Frontend);
}
/** Initializes MobileRpcManager for the backend of an application. */
public static initializeImpl(interfaces: RpcInterfaceDefinition[]): MobileRpcConfiguration {
return MobileRpcManager.performInitialization(interfaces, RpcEndpoint.Backend);
}
}