-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathios-application-manager.ts
122 lines (99 loc) · 5.02 KB
/
ios-application-manager.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { EOL } from "os";
import { hook } from "../../../helpers";
import { ApplicationManagerBase } from "../../application-manager-base";
import { cache } from "../../../decorators";
export class IOSApplicationManager extends ApplicationManagerBase {
private applicationsLiveSyncInfos: Mobile.IApplicationInfo[];
constructor(protected $logger: ILogger,
protected $hooksService: IHooksService,
private device: Mobile.IiOSDevice,
private $errors: IErrors,
private $iOSNotificationService: IiOSNotificationService,
private $iosDeviceOperations: IIOSDeviceOperations,
private $options: IOptions,
private $deviceLogProvider: Mobile.IDeviceLogProvider) {
super($logger, $hooksService);
}
public async getInstalledApplications(): Promise<string[]> {
const applicationsLiveSyncStatus = await this.getApplicationsInformation();
return _(applicationsLiveSyncStatus)
.map(appLiveSyncStatus => appLiveSyncStatus.applicationIdentifier)
.sortBy((identifier: string) => identifier.toLowerCase())
.value();
}
@hook('install')
public async installApplication(packageFilePath: string): Promise<void> {
await this.$iosDeviceOperations.install(packageFilePath, [this.device.deviceInfo.identifier], (err: IOSDeviceLib.IDeviceError) => {
this.$errors.failWithoutHelp(`Failed to install ${packageFilePath} on device with identifier ${err.deviceId}. Error is: ${err.message}`);
});
}
public async getApplicationsInformation(): Promise<Mobile.IApplicationInfo[]> {
const deviceIdentifier = this.device.deviceInfo.identifier;
const applicationsOnDeviceInfo = _.first((await this.$iosDeviceOperations.apps([deviceIdentifier]))[deviceIdentifier]);
const applicationsOnDevice = applicationsOnDeviceInfo ? applicationsOnDeviceInfo.response : [];
this.$logger.trace("Result when getting applications information: ", JSON.stringify(applicationsOnDevice, null, 2));
this.applicationsLiveSyncInfos = _.map(applicationsOnDevice, app => ({
applicationIdentifier: app.CFBundleIdentifier,
configuration: app.configuration,
deviceIdentifier: this.device.deviceInfo.identifier
}));
return this.applicationsLiveSyncInfos;
}
public async uninstallApplication(appIdentifier: string): Promise<void> {
await this.$iosDeviceOperations.uninstall(appIdentifier, [this.device.deviceInfo.identifier], (err: IOSDeviceLib.IDeviceError) => {
this.$logger.warn(`Failed to uninstall ${appIdentifier} on device with identifier ${err.deviceId}`);
});
this.$logger.trace("Application %s has been uninstalled successfully.", appIdentifier);
}
public async startApplication(appData: Mobile.IStartApplicationData): Promise<void> {
if (!await this.isApplicationInstalled(appData.appId)) {
this.$errors.failWithoutHelp("Invalid application id: %s. All available application ids are: %s%s ", appData.appId, EOL, this.applicationsLiveSyncInfos.join(EOL));
}
await this.setDeviceLogData(appData);
await this.runApplicationCore(appData);
this.$logger.info(`Successfully run application ${appData.appId} on device with ID ${this.device.deviceInfo.identifier}.`);
}
public async stopApplication(appData: Mobile.IApplicationData): Promise<void> {
const { appId } = appData;
await this.device.destroyDebugSocket(appId);
const action = () => this.$iosDeviceOperations.stop([{ deviceId: this.device.deviceInfo.identifier, ddi: this.$options.ddi, appId }]);
try {
await action();
} catch (err) {
this.$logger.trace(`Error when trying to stop application ${appId} on device ${this.device.deviceInfo.identifier}: ${err}. Retrying stop operation.`);
await action();
}
}
public async restartApplication(appData: Mobile.IStartApplicationData): Promise<void> {
try {
await this.setDeviceLogData(appData);
await this.stopApplication(appData);
await this.runApplicationCore(appData);
} catch (err) {
await this.$iOSNotificationService.postNotification(this.device.deviceInfo.identifier, `${appData.appId}:NativeScript.LiveSync.RestartApplication`);
throw err;
}
}
private async setDeviceLogData(appData: Mobile.IApplicationData): Promise<void> {
this.$deviceLogProvider.setProjectNameForDevice(this.device.deviceInfo.identifier, appData.projectName);
if (!this.$options.justlaunch) {
await this.startDeviceLog();
}
}
private async runApplicationCore(appData: Mobile.IStartApplicationData): Promise<void> {
const waitForDebugger = appData.waitForDebugger && appData.waitForDebugger.toString();
await this.$iosDeviceOperations.start([{ deviceId: this.device.deviceInfo.identifier, appId: appData.appId, ddi: this.$options.ddi, waitForDebugger }]);
}
@cache()
private async startDeviceLog(): Promise<void> {
await this.device.openDeviceLogStream();
}
public getDebuggableApps(): Promise<Mobile.IDeviceApplicationInformation[]> {
// Implement when we can find debuggable applications for iOS.
return Promise.resolve([]);
}
public getDebuggableAppViews(appIdentifiers: string[]): Promise<IDictionary<Mobile.IDebugWebViewInfo[]>> {
// Implement when we can find debuggable applications for iOS.
return Promise.resolve(null);
}
}