Skip to content

fix: iOS debug issues #3616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/common
4 changes: 2 additions & 2 deletions lib/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ interface ISocketProxyFactory extends NodeJS.EventEmitter {
createWebSocketProxy(factory: () => Promise<any>, deviceIdentifier: string): Promise<any>;
}

interface IiOSNotification {
interface IiOSNotification extends NodeJS.EventEmitter {
getWaitForDebug(projectId: string): string;
getAttachRequest(projectId: string, deviceId: string): string;
getAppLaunching(projectId: string): string;
Expand Down Expand Up @@ -843,4 +843,4 @@ interface IAssetsGenerationService {
* @returns {Promise<void>}
*/
generateSplashScreens(splashesGenerationData: ISplashesGenerationData): Promise<void>;
}
}
2 changes: 2 additions & 0 deletions lib/device-sockets/ios/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export class IOSNotification extends EventEmitter implements IiOSNotification {
}

public getAttachRequest(appId: string, deviceId: string): string {
// It could be too early to emit this event, but we rely that if you construct attach request,
// you will execute it immediately.
this.emit(ATTACH_REQUEST_EVENT_NAME, { deviceId, appId });
return this.formatNotification(IOSNotification.ATTACH_REQUEST_NOTIFICATION_NAME, appId);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/device-sockets/ios/socket-proxy-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
err.deviceIdentifier = deviceIdentifier;
this.$logger.trace(err);
this.emit(CONNECTION_ERROR_EVENT_NAME, err);
this.$errors.failWithoutHelp("Cannot connect to device socket.");
this.$errors.failWithoutHelp(`Cannot connect to device socket. The error message is ${err.message}`);
}

this.$logger.info("Backend socket created.");
Expand Down
12 changes: 9 additions & 3 deletions lib/services/ios-debug-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
return "ios";
}

public debug(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
public async debug(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
await this.device.openDeviceLogStream();

if (debugOptions.debugBrk && debugOptions.start) {
this.$errors.failWithoutHelp("Expected exactly one of the --debug-brk or --start options.");
}
Expand Down Expand Up @@ -106,12 +108,13 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS

private async emulatorDebugBrk(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
const args = debugOptions.debugBrk ? "--nativescript-debug-brk" : "--nativescript-debug-start";
const launchResult = await this.$iOSEmulatorServices.runApplicationOnEmulator(debugData.pathToAppPackage, {
const launchResult = await this.$iOSEmulatorServices.runApplicationOnEmulator(debugData.pathToAppPackage, {
waitForDebugger: true,
captureStdin: true,
args: args,
appId: debugData.applicationIdentifier,
skipInstall: true
skipInstall: true,
device: debugData.deviceIdentifier
});

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

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

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

private async deviceStartCore(device: Mobile.IiOSDevice, debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
await this.$iOSSocketRequestExecutor.executeAttachRequest(device, AWAIT_NOTIFICATION_TIMEOUT_SECONDS, debugData.applicationIdentifier);
return this.wireDebuggerClient(debugData, debugOptions, device);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/services/ios-debugger-port-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export class IOSDebuggerPortService implements IIOSDebuggerPortService {

constructor(private $iOSLogParserService: IIOSLogParserService,
private $iOSProjectService: IPlatformProjectService,
private $iOSNotification: IiOSNotification,
private $logger: ILogger,
private $projectData: IProjectData) { }

Expand Down Expand Up @@ -62,7 +63,7 @@ export class IOSDebuggerPortService implements IIOSDebuggerPortService {

@cache()
private attachToAttachRequestEvent(device: Mobile.IDevice): void {
device.applicationManager.on(ATTACH_REQUEST_EVENT_NAME, (data: IIOSDebuggerPortData) => {
this.$iOSNotification.on(ATTACH_REQUEST_EVENT_NAME, (data: IIOSDebuggerPortData) => {
this.$logger.trace(ATTACH_REQUEST_EVENT_NAME, data);
const timer = setTimeout(() => {
this.clearTimeout(data);
Expand Down
15 changes: 9 additions & 6 deletions lib/services/ios-log-parser-service.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
import { DEBUGGER_PORT_FOUND_EVENT_NAME, DEVICE_LOG_EVENT_NAME } from "../common/constants";
import { cache } from "../common/decorators";
import { EventEmitter } from "events";

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

private startedDeviceLogInstances: IDictionary<boolean> = {};

constructor(private $deviceLogProvider: Mobile.IDeviceLogProvider,
private $iosDeviceOperations: IIOSDeviceOperations,
private $iOSSimulatorLogProvider: Mobile.IiOSSimulatorLogProvider,
private $logger: ILogger,
private $projectData: IProjectData) {
super();
}
super();
}

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

this.startParsingLogCore(device);
this.startLogProcess(device);
if (!this.startedDeviceLogInstances[device.deviceInfo.identifier]) {
this.startParsingLogCore(device);
this.startLogProcess(device);
this.startedDeviceLogInstances[device.deviceInfo.identifier] = true;
}
}

@cache()
private startParsingLogCore(device: Mobile.IDevice): void {
const logProvider = device.isEmulator ? this.$iOSSimulatorLogProvider : this.$iosDeviceOperations;
logProvider.on(DEVICE_LOG_EVENT_NAME, (response: IOSDeviceLib.IDeviceLogData) => this.processDeviceLogResponse(response));
Expand Down
3 changes: 3 additions & 0 deletions lib/services/livesync/ios-livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I
$devicePathProvider: IDevicePathProvider,
$logger: ILogger,
$projectFilesProvider: IProjectFilesProvider,
private $iOSDebuggerPortService: IIOSDebuggerPortService,
) {
super($fs, $logger, $platformsData, $projectFilesManager, $devicePathProvider, $projectFilesProvider);
}
Expand All @@ -24,6 +25,8 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I
return super.fullSync(syncInfo);
}

this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);

const projectData = syncInfo.projectData;
const platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
const deviceAppData = await this.getAppData(syncInfo);
Expand Down
6 changes: 3 additions & 3 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"inquirer": "0.9.0",
"ios-device-lib": "0.4.12",
"ios-mobileprovision-finder": "1.0.10",
"ios-sim-portable": "3.4.1",
"ios-sim-portable": "3.4.3",
"jimp": "0.2.28",
"lockfile": "1.0.3",
"lodash": "4.13.1",
Expand Down
16 changes: 14 additions & 2 deletions test/services/ios-debugger-port-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { IOSLogParserService } from "../../lib/services/ios-log-parser-service";
import { IOSSimulatorLogProvider } from "../../lib/common/mobile/ios/simulator/ios-simulator-log-provider";
import { Yok } from "../../lib/common/yok";
import { EventEmitter } from "events";
import * as sinon from "sinon";

class DeviceApplicationManagerMock extends EventEmitter { }

Expand Down Expand Up @@ -50,6 +51,7 @@ function createTestInjector() {
projectName: "test",
projectId: appId
});
injector.register("iOSNotification", DeviceApplicationManagerMock);

return injector;
}
Expand Down Expand Up @@ -82,11 +84,17 @@ function getMultilineDebuggerPortMessage(port: number) {

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

beforeEach(() => {
injector = createTestInjector();
iOSDebuggerPortService = injector.resolve("iOSDebuggerPortService");
iosDeviceOperations = injector.resolve("iosDeviceOperations");
clock = sinon.useFakeTimers();
});

afterEach(() => {
clock.restore();
});

function emitDeviceLog(message: string) {
Expand Down Expand Up @@ -142,7 +150,9 @@ describe("iOSDebuggerPortService", () => {
emitDeviceLog(getDebuggerPortMessage(testCase.emittedPort));
}

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

const port = await iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId });
const promise = iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId });
clock.tick(10000);
const port = await promise;
assert.deepEqual(port, testCase.emittedPort);
});
});
Expand Down