diff --git a/lib/commands/appstore-upload.ts b/lib/commands/appstore-upload.ts index 60642b2352..cc2235bc96 100644 --- a/lib/commands/appstore-upload.ts +++ b/lib/commands/appstore-upload.ts @@ -25,19 +25,12 @@ export class PublishIOS implements ICommand { } public async execute(args: string[]): Promise { - let username = args[0]; - let password = args[1]; + await this.$itmsTransporterService.validate(); + + const username = args[0] || await this.$prompter.getString("Apple ID", { allowEmpty: false }); + const password = args[1] || await this.$prompter.getPassword("Apple ID password"); const mobileProvisionIdentifier = args[2]; const codeSignIdentity = args[3]; - let ipaFilePath = this.$options.ipa ? path.resolve(this.$options.ipa) : null; - - if (!username) { - username = await this.$prompter.getString("Apple ID", { allowEmpty: false }); - } - - if (!password) { - password = await this.$prompter.getPassword("Apple ID password"); - } const user = await this.$applePortalSessionService.createUserSession({ username, password }, { applicationSpecificPassword: this.$options.appleApplicationSpecificPassword, @@ -49,6 +42,8 @@ export class PublishIOS implements ICommand { this.$errors.fail(`Invalid username and password combination. Used '${username}' as the username.`); } + let ipaFilePath = this.$options.ipa ? path.resolve(this.$options.ipa) : null; + if (!mobileProvisionIdentifier && !ipaFilePath) { this.$logger.warn("No mobile provision identifier set. A default mobile provision will be used. You can set one in app/App_Resources/iOS/build.xcconfig"); } @@ -58,9 +53,9 @@ export class PublishIOS implements ICommand { } this.$options.release = true; - const platform = this.$devicePlatformsConstants.iOS.toLowerCase(); if (!ipaFilePath) { + const platform = this.$devicePlatformsConstants.iOS.toLowerCase(); // No .ipa path provided, build .ipa on out own. if (mobileProvisionIdentifier || codeSignIdentity) { // This is not very correct as if we build multiple targets we will try to sign all of them using the signing identity here. diff --git a/lib/common/services/xcode-select-service.ts b/lib/common/services/xcode-select-service.ts index 98dd487961..dc2f7b13e5 100644 --- a/lib/common/services/xcode-select-service.ts +++ b/lib/common/services/xcode-select-service.ts @@ -35,15 +35,9 @@ export class XcodeSelectService implements IXcodeSelectService { this.$errors.fail("xcodebuild execution failed. Make sure that you have latest Xcode and tools installed."); } - const xcodeVersionMatch = xcodeVer.match(/Xcode (.*)/), - xcodeVersionGroup = xcodeVersionMatch && xcodeVersionMatch[1], - xcodeVersionSplit = xcodeVersionGroup && xcodeVersionGroup.split("."); - - return { - major: xcodeVersionSplit && xcodeVersionSplit[0], - minor: xcodeVersionSplit && xcodeVersionSplit[1], - patch: xcodeVersionSplit && xcodeVersionSplit[2] - }; + const [ major, minor, patch ] = xcodeVer.split("."); + + return { major, minor, patch }; } } diff --git a/lib/common/test/unit-tests/xcode-select-service.ts b/lib/common/test/unit-tests/xcode-select-service.ts index c54bbff223..9783a3a73a 100644 --- a/lib/common/test/unit-tests/xcode-select-service.ts +++ b/lib/common/test/unit-tests/xcode-select-service.ts @@ -59,7 +59,7 @@ describe("xcode-select-service", () => { }); it("gets correct Xcode version", async () => { - injector = createTestInjector({ xcodeSelectStdout: null, isDarwin: true, xcodeVersionOutput: "Xcode 7.3\nBuild version 7D175" }); + injector = createTestInjector({ xcodeSelectStdout: null, isDarwin: true, xcodeVersionOutput: "7.3" }); service = injector.resolve("$xcodeSelectService"); const xcodeVersion = await service.getXcodeVersion(); diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index d0e91d2507..7272e7cfd5 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -639,6 +639,7 @@ interface IITMSData { * Used for communicating with Xcode's iTMS Transporter tool. */ interface IITMSTransporterService { + validate(): Promise; /** * Uploads an .ipa package to iTunes Connect. * @param {IITMSData} data Data needed to upload the package diff --git a/lib/services/itmstransporter-service.ts b/lib/services/itmstransporter-service.ts index 5d769f9d42..411a3713b5 100644 --- a/lib/services/itmstransporter-service.ts +++ b/lib/services/itmstransporter-service.ts @@ -19,6 +19,13 @@ export class ITMSTransporterService implements IITMSTransporterService { return this.$injector.resolve("projectData"); } + public async validate(): Promise { + const itmsTransporterPath = await this.getITMSTransporterPath(); + if (!this.$fs.exists(itmsTransporterPath)) { + this.$errors.fail('iTMS Transporter not found on this machine - make sure your Xcode installation is not damaged.'); + } + } + public async upload(data: IITMSData): Promise { temp.track(); const itmsTransporterPath = await this.getITMSTransporterPath(); @@ -96,11 +103,12 @@ export class ITMSTransporterService implements IITMSTransporterService { @cache() private async getITMSTransporterPath(): Promise { const xcodePath = await this.$xcodeSelectService.getContentsDirectoryPath(); - const loaderAppContentsPath = path.join(xcodePath, "Applications", "Application Loader.app", "Contents"); - const itmsTransporterPath = path.join(loaderAppContentsPath, ITMSConstants.iTMSDirectoryName, "bin", ITMSConstants.iTMSExecutableName); + let itmsTransporterPath = path.join(xcodePath, "..", "Contents", "SharedFrameworks", "ContentDeliveryServices.framework", "Versions", "A", "itms", "bin", ITMSConstants.iTMSExecutableName); - if (!this.$fs.exists(itmsTransporterPath)) { - this.$errors.fail('iTMS Transporter not found on this machine - make sure your Xcode installation is not damaged.'); + const xcodeVersionData = await this.$xcodeSelectService.getXcodeVersion(); + if (+xcodeVersionData.major < 11) { + const loaderAppContentsPath = path.join(xcodePath, "Applications", "Application Loader.app", "Contents"); + itmsTransporterPath = path.join(loaderAppContentsPath, ITMSConstants.iTMSDirectoryName, "bin", ITMSConstants.iTMSExecutableName); } return itmsTransporterPath; diff --git a/test/tns-appstore-upload.ts b/test/tns-appstore-upload.ts index 9c5fa90520..b668bee89f 100644 --- a/test/tns-appstore-upload.ts +++ b/test/tns-appstore-upload.ts @@ -124,6 +124,7 @@ class AppStore { expectITMSTransporterUpload() { this.expectedItmsTransporterServiceUploadCalls = 1; + this.itmsTransporterService.validate = () => Promise.resolve(); this.itmsTransporterService.upload = (options: IITMSData) => { this.itmsTransporterServiceUploadCalls++; chai.assert.equal(options.ipaFilePath, "/Users/person/git/MyProject/platforms/ios/archive/MyProject.ipa");