Skip to content

Commit 719a870

Browse files
committed
fix(ios): launch the app once when restarting it on a device
restartApplication launched the app and then connected to its debug socket with ensureAppStarted, which launched it again with --terminate-existing and killed the first process. The socket now connects to the running instance. A launch waiting for a debugger keeps the second start, since that instance cannot answer the attach request.
1 parent 226fd44 commit 719a870

2 files changed

Lines changed: 71 additions & 4 deletions

File tree

‎lib/services/livesync/ios-device-livesync-service.ts‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ export class IOSDeviceLiveSyncService
5858
}
5959

6060
private async setupSocketIfNeeded(
61-
projectData: IProjectData
61+
projectData: IProjectData,
62+
ensureAppStarted: boolean = true
6263
): Promise<boolean> {
6364
// TODO: persist the sockets per app in order to support LiveSync on multiple apps on the same device
6465
if (this.socket) {
@@ -67,8 +68,6 @@ export class IOSDeviceLiveSyncService
6768

6869
const appId = projectData.projectIdentifiers.ios;
6970
try {
70-
// TODO: temp workaround till we setup the sockets along with the app start
71-
const ensureAppStarted = true;
7271
this.socket = await this.device.getDebugSocket(
7372
appId,
7473
projectData.projectName,
@@ -217,7 +216,13 @@ export class IOSDeviceLiveSyncService
217216

218217
if (liveSyncInfo.useHotModuleReload) {
219218
// enable HOT updates
220-
await this.setupSocketIfNeeded(projectData);
219+
// Starting the app again here would terminate the instance launched
220+
// above. Only a launch that waits for a debugger still needs it, as
221+
// that instance cannot answer the attach request.
222+
await this.setupSocketIfNeeded(
223+
projectData,
224+
!!liveSyncInfo.waitForDebugger
225+
);
221226
}
222227
}
223228

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import * as assert from "assert";
2+
import { IOSDeviceLiveSyncService } from "../../../lib/services/livesync/ios-device-livesync-service";
3+
4+
describe("IOSDeviceLiveSyncService", () => {
5+
const projectData: any = {
6+
projectName: "app",
7+
projectDir: "/app",
8+
projectIdentifiers: { ios: "org.app" },
9+
};
10+
11+
const restart = async (waitForDebugger: boolean) => {
12+
const calls: string[] = [];
13+
const ensureAppStartedValues: boolean[] = [];
14+
const device: any = {
15+
applicationManager: {
16+
restartApplication: async () => {
17+
calls.push("restart");
18+
},
19+
},
20+
getDebugSocket: async (
21+
_appId: string,
22+
_projectName: string,
23+
_projectDir: string,
24+
ensureAppStarted: boolean
25+
) => {
26+
calls.push("socket");
27+
ensureAppStartedValues.push(ensureAppStarted);
28+
return { on: () => {}, removeAllListeners: () => {} };
29+
},
30+
};
31+
const service = new (<any>IOSDeviceLiveSyncService)(
32+
{ trace: () => {} },
33+
{},
34+
{},
35+
{},
36+
{},
37+
{},
38+
device
39+
);
40+
41+
await service.restartApplication(projectData, {
42+
deviceAppData: { appIdentifier: "org.app" },
43+
useHotModuleReload: true,
44+
waitForDebugger,
45+
});
46+
47+
return { calls, ensureAppStartedValues };
48+
};
49+
50+
it("connects to the app it restarted without starting it again", async () => {
51+
const { calls, ensureAppStartedValues } = await restart(false);
52+
53+
assert.deepStrictEqual(calls, ["restart", "socket"]);
54+
assert.deepStrictEqual(ensureAppStartedValues, [false]);
55+
});
56+
57+
it("starts the app again when the restarted instance waits for a debugger", async () => {
58+
const { ensureAppStartedValues } = await restart(true);
59+
60+
assert.deepStrictEqual(ensureAppStartedValues, [true]);
61+
});
62+
});

0 commit comments

Comments
 (0)