nativescript
Version: 
Command-line interface for building NativeScript projects
124 lines • 6.05 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IOSSimulatorApplicationManager = void 0;
const application_manager_base_1 = require("../../application-manager-base");
const helpers_1 = require("../../../helpers");
const decorators_1 = require("../../../decorators");
const constants_1 = require("../../../constants");
const path = require("path");
const log4js = require("log4js");
const _ = require("lodash");
class IOSSimulatorApplicationManager extends application_manager_base_1.ApplicationManagerBase {
    constructor($childProcess, iosSim, device, $options, $fs, $deviceLogProvider, $tempService, $logger, $hooksService) {
        super($logger, $hooksService, $deviceLogProvider);
        this.$childProcess = $childProcess;
        this.iosSim = iosSim;
        this.device = device;
        this.$options = $options;
        this.$fs = $fs;
        this.$deviceLogProvider = $deviceLogProvider;
        this.$tempService = $tempService;
        this._lldbProcesses = {};
    }
    async getInstalledApplications() {
        return this.iosSim.getInstalledApplications(this.device.deviceInfo.identifier);
    }
    async installApplication(packageFilePath) {
        if (this.$fs.exists(packageFilePath) &&
            path.extname(packageFilePath) === ".zip") {
            const dir = await this.$tempService.mkdirSync("simulatorPackage");
            await this.$fs.unzip(packageFilePath, dir);
            const app = _.find(this.$fs.readDirectory(dir), (directory) => path.extname(directory) === ".app");
            if (app) {
                packageFilePath = path.join(dir, app);
            }
        }
        await this.iosSim.installApplication(this.device.deviceInfo.identifier, packageFilePath);
    }
    async uninstallApplication(appIdentifier) {
        await this.detachNativeDebugger(appIdentifier);
        return this.iosSim.uninstallApplication(this.device.deviceInfo.identifier, appIdentifier);
    }
    async startApplication(appData) {
        const args = process.env.IOS_SIMULATOR_RUN_ARGS || "";
        const options = appData.waitForDebugger
            ? {
                waitForDebugger: true,
                args: `--nativescript-debug-brk ${args}`.trim(),
            }
            : args
                ? { args }
                : {};
        await this.setDeviceLogData(appData);
        const launchResult = await this.iosSim.startApplication(this.device.deviceInfo.identifier, appData.appId, options);
        const pid = (0, helpers_1.getPidFromiOSSimulatorLogs)(appData.appId, launchResult);
        this.$deviceLogProvider.setApplicationPidForDevice(this.device.deviceInfo.identifier, pid);
        if (appData.waitForDebugger) {
            this.attachNativeDebugger(appData.appId, pid);
        }
    }
    async stopApplication(appData) {
        const { appId } = appData;
        await this.device.destroyDebugSocket(appId);
        await this.detachNativeDebugger(appId);
        await this.iosSim.stopApplication(this.device.deviceInfo.identifier, appData.appId, appData.projectName);
    }
    async getDebuggableApps() {
        return [];
    }
    async getDebuggableAppViews(appIdentifiers) {
        // Implement when we can find debuggable applications for iOS.
        return Promise.resolve(null);
    }
    // iOS will kill the app if we freeze it in the NativeScript Runtime and wait for debug-brk.
    // In order to avoid that, we are attaching lldb and passing it "process continue".
    // In this way, iOS will not kill the app because it has a native debugger attached
    // and the users will be able to attach a debug session using the debug-brk flag.
    attachNativeDebugger(appId, pid) {
        this._lldbProcesses[appId] = this.$childProcess.spawn("lldb", ["-p", pid]);
        if (log4js.levels.TRACE.isGreaterThanOrEqualTo(this.$logger.getLevel())) {
            this._lldbProcesses[appId].stdout.pipe(process.stdout);
        }
        this._lldbProcesses[appId].stderr.pipe(process.stderr);
        this._lldbProcesses[appId].stdin.write("process continue\n");
    }
    async detachNativeDebugger(appId) {
        if (this._lldbProcesses[appId]) {
            this._lldbProcesses[appId].stdin.write("process detach\n");
            await this.killProcess(this._lldbProcesses[appId]);
            this._lldbProcesses[appId] = undefined;
        }
    }
    async killProcess(childProcess) {
        if (childProcess) {
            return new Promise((resolve, reject) => {
                childProcess.on("close", resolve);
                childProcess.kill();
            });
        }
    }
    async setDeviceLogData(appData) {
        this.$deviceLogProvider.setProjectNameForDevice(this.device.deviceInfo.identifier, appData.projectName);
        this.$deviceLogProvider.setProjectDirForDevice(this.device.deviceInfo.identifier, appData.projectDir);
        if (!this.$options.justlaunch) {
            await this.startDeviceLog();
        }
    }
    startDeviceLog() {
        return this.device.openDeviceLogStream({ predicate: constants_1.IOS_LOG_PREDICATE });
    }
}
exports.IOSSimulatorApplicationManager = IOSSimulatorApplicationManager;
__decorate([
    (0, helpers_1.hook)("install")
], IOSSimulatorApplicationManager.prototype, "installApplication", null);
__decorate([
    (0, decorators_1.cache)()
], IOSSimulatorApplicationManager.prototype, "startDeviceLog", null);
//# sourceMappingURL=ios-simulator-application-manager.js.map