Skip to content

Commit fff9bbe

Browse files
Merge pull request #3616 from NativeScript/vladimirov/fix-ios-debug-issues
fix: iOS debug issues
2 parents 2e439e5 + 75fb867 commit fff9bbe

11 files changed

+47
-20
lines changed

lib/declarations.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ interface ISocketProxyFactory extends NodeJS.EventEmitter {
643643
createWebSocketProxy(factory: () => Promise<any>, deviceIdentifier: string): Promise<any>;
644644
}
645645

646-
interface IiOSNotification {
646+
interface IiOSNotification extends NodeJS.EventEmitter {
647647
getWaitForDebug(projectId: string): string;
648648
getAttachRequest(projectId: string, deviceId: string): string;
649649
getAppLaunching(projectId: string): string;
@@ -843,4 +843,4 @@ interface IAssetsGenerationService {
843843
* @returns {Promise<void>}
844844
*/
845845
generateSplashScreens(splashesGenerationData: ISplashesGenerationData): Promise<void>;
846-
}
846+
}

lib/device-sockets/ios/notification.ts

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export class IOSNotification extends EventEmitter implements IiOSNotification {
1515
}
1616

1717
public getAttachRequest(appId: string, deviceId: string): string {
18+
// It could be too early to emit this event, but we rely that if you construct attach request,
19+
// you will execute it immediately.
1820
this.emit(ATTACH_REQUEST_EVENT_NAME, { deviceId, appId });
1921
return this.formatNotification(IOSNotification.ATTACH_REQUEST_NOTIFICATION_NAME, appId);
2022
}

lib/device-sockets/ios/socket-proxy-factory.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
9595
err.deviceIdentifier = deviceIdentifier;
9696
this.$logger.trace(err);
9797
this.emit(CONNECTION_ERROR_EVENT_NAME, err);
98-
this.$errors.failWithoutHelp("Cannot connect to device socket.");
98+
this.$errors.failWithoutHelp(`Cannot connect to device socket. The error message is ${err.message}`);
9999
}
100100

101101
this.$logger.info("Backend socket created.");

lib/services/ios-debug-service.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
3939
return "ios";
4040
}
4141

42-
public debug(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
42+
public async debug(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
43+
await this.device.openDeviceLogStream();
44+
4345
if (debugOptions.debugBrk && debugOptions.start) {
4446
this.$errors.failWithoutHelp("Expected exactly one of the --debug-brk or --start options.");
4547
}
@@ -106,12 +108,13 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
106108

107109
private async emulatorDebugBrk(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
108110
const args = debugOptions.debugBrk ? "--nativescript-debug-brk" : "--nativescript-debug-start";
109-
const launchResult = await this.$iOSEmulatorServices.runApplicationOnEmulator(debugData.pathToAppPackage, {
111+
const launchResult = await this.$iOSEmulatorServices.runApplicationOnEmulator(debugData.pathToAppPackage, {
110112
waitForDebugger: true,
111113
captureStdin: true,
112114
args: args,
113115
appId: debugData.applicationIdentifier,
114-
skipInstall: true
116+
skipInstall: true,
117+
device: debugData.deviceIdentifier
115118
});
116119

117120
const pid = getPidFromiOSSimulatorLogs(debugData.applicationIdentifier, launchResult);
@@ -126,6 +129,8 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
126129
}
127130

128131
private async emulatorStart(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
132+
const device = await this.$devicesService.getDevice(debugData.deviceIdentifier);
133+
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
129134
const result = await this.wireDebuggerClient(debugData, debugOptions);
130135

131136
const attachRequestMessage = this.$iOSNotification.getAttachRequest(debugData.applicationIdentifier, debugData.deviceIdentifier);
@@ -174,6 +179,7 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
174179
}
175180

176181
private async deviceStartCore(device: Mobile.IiOSDevice, debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
182+
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
177183
await this.$iOSSocketRequestExecutor.executeAttachRequest(device, AWAIT_NOTIFICATION_TIMEOUT_SECONDS, debugData.applicationIdentifier);
178184
return this.wireDebuggerClient(debugData, debugOptions, device);
179185
}

lib/services/ios-debugger-port-service.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export class IOSDebuggerPortService implements IIOSDebuggerPortService {
99

1010
constructor(private $iOSLogParserService: IIOSLogParserService,
1111
private $iOSProjectService: IPlatformProjectService,
12+
private $iOSNotification: IiOSNotification,
1213
private $logger: ILogger,
1314
private $projectData: IProjectData) { }
1415

@@ -62,7 +63,7 @@ export class IOSDebuggerPortService implements IIOSDebuggerPortService {
6263

6364
@cache()
6465
private attachToAttachRequestEvent(device: Mobile.IDevice): void {
65-
device.applicationManager.on(ATTACH_REQUEST_EVENT_NAME, (data: IIOSDebuggerPortData) => {
66+
this.$iOSNotification.on(ATTACH_REQUEST_EVENT_NAME, (data: IIOSDebuggerPortData) => {
6667
this.$logger.trace(ATTACH_REQUEST_EVENT_NAME, data);
6768
const timer = setTimeout(() => {
6869
this.clearTimeout(data);

lib/services/ios-log-parser-service.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
import { DEBUGGER_PORT_FOUND_EVENT_NAME, DEVICE_LOG_EVENT_NAME } from "../common/constants";
2-
import { cache } from "../common/decorators";
32
import { EventEmitter } from "events";
43

54
export class IOSLogParserService extends EventEmitter implements IIOSLogParserService {
65
private static MESSAGE_REGEX = /NativeScript debugger has opened inspector socket on port (\d+?) for (.*)[.]/;
76

7+
private startedDeviceLogInstances: IDictionary<boolean> = {};
8+
89
constructor(private $deviceLogProvider: Mobile.IDeviceLogProvider,
910
private $iosDeviceOperations: IIOSDeviceOperations,
1011
private $iOSSimulatorLogProvider: Mobile.IiOSSimulatorLogProvider,
1112
private $logger: ILogger,
1213
private $projectData: IProjectData) {
13-
super();
14-
}
14+
super();
15+
}
1516

1617
public startParsingLog(device: Mobile.IDevice): void {
1718
this.$deviceLogProvider.setProjectNameForDevice(device.deviceInfo.identifier, this.$projectData.projectName);
1819

19-
this.startParsingLogCore(device);
20-
this.startLogProcess(device);
20+
if (!this.startedDeviceLogInstances[device.deviceInfo.identifier]) {
21+
this.startParsingLogCore(device);
22+
this.startLogProcess(device);
23+
this.startedDeviceLogInstances[device.deviceInfo.identifier] = true;
24+
}
2125
}
2226

23-
@cache()
2427
private startParsingLogCore(device: Mobile.IDevice): void {
2528
const logProvider = device.isEmulator ? this.$iOSSimulatorLogProvider : this.$iosDeviceOperations;
2629
logProvider.on(DEVICE_LOG_EVENT_NAME, (response: IOSDeviceLib.IDeviceLogData) => this.processDeviceLogResponse(response));

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

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I
1313
$devicePathProvider: IDevicePathProvider,
1414
$logger: ILogger,
1515
$projectFilesProvider: IProjectFilesProvider,
16+
private $iOSDebuggerPortService: IIOSDebuggerPortService,
1617
) {
1718
super($fs, $logger, $platformsData, $projectFilesManager, $devicePathProvider, $projectFilesProvider);
1819
}
@@ -24,6 +25,8 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I
2425
return super.fullSync(syncInfo);
2526
}
2627

28+
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
29+
2730
const projectData = syncInfo.projectData;
2831
const platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
2932
const deviceAppData = await this.getAppData(syncInfo);

npm-shrinkwrap.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"inquirer": "0.9.0",
4444
"ios-device-lib": "0.4.12",
4545
"ios-mobileprovision-finder": "1.0.10",
46-
"ios-sim-portable": "3.4.1",
46+
"ios-sim-portable": "3.4.3",
4747
"jimp": "0.2.28",
4848
"lockfile": "1.0.3",
4949
"lodash": "4.13.1",

test/services/ios-debugger-port-service.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { IOSLogParserService } from "../../lib/services/ios-log-parser-service";
66
import { IOSSimulatorLogProvider } from "../../lib/common/mobile/ios/simulator/ios-simulator-log-provider";
77
import { Yok } from "../../lib/common/yok";
88
import { EventEmitter } from "events";
9+
import * as sinon from "sinon";
910

1011
class DeviceApplicationManagerMock extends EventEmitter { }
1112

@@ -50,6 +51,7 @@ function createTestInjector() {
5051
projectName: "test",
5152
projectId: appId
5253
});
54+
injector.register("iOSNotification", DeviceApplicationManagerMock);
5355

5456
return injector;
5557
}
@@ -82,11 +84,17 @@ function getMultilineDebuggerPortMessage(port: number) {
8284

8385
describe("iOSDebuggerPortService", () => {
8486
let injector: IInjector, iOSDebuggerPortService: IIOSDebuggerPortService, iosDeviceOperations: IIOSDeviceOperations;
87+
let clock: sinon.SinonFakeTimers = null;
8588

8689
beforeEach(() => {
8790
injector = createTestInjector();
8891
iOSDebuggerPortService = injector.resolve("iOSDebuggerPortService");
8992
iosDeviceOperations = injector.resolve("iosDeviceOperations");
93+
clock = sinon.useFakeTimers();
94+
});
95+
96+
afterEach(() => {
97+
clock.restore();
9098
});
9199

92100
function emitDeviceLog(message: string) {
@@ -142,7 +150,9 @@ describe("iOSDebuggerPortService", () => {
142150
emitDeviceLog(getDebuggerPortMessage(testCase.emittedPort));
143151
}
144152

145-
const port = await iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId });
153+
const promise = iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId });
154+
clock.tick(10000);
155+
const port = await promise;
146156
assert.deepEqual(port, testCase.emittedPort);
147157
});
148158
it(`${testCase.name} for multiline debugger port message.`, async () => {
@@ -154,7 +164,9 @@ describe("iOSDebuggerPortService", () => {
154164
emitDeviceLog(getMultilineDebuggerPortMessage(testCase.emittedPort));
155165
}
156166

157-
const port = await iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId });
167+
const promise = iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId });
168+
clock.tick(10000);
169+
const port = await promise;
158170
assert.deepEqual(port, testCase.emittedPort);
159171
});
160172
});

0 commit comments

Comments
 (0)