Skip to content

Commit 9202b9a

Browse files
committed
Merge pull request #1690 from NativeScript/kerezov/pbxproject-format
Use xcproj if needed to fix .pbxproject format
2 parents 294979a + 46e6219 commit 9202b9a

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

lib/services/ios-project-service.ts

+39-6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
4040
private $devicesService: Mobile.IDevicesService,
4141
private $mobileHelper: Mobile.IMobileHelper,
4242
private $pluginVariablesService: IPluginVariablesService,
43+
private $staticConfig: IStaticConfig,
44+
private $sysInfo: ISysInfo,
4345
private $xcodeSelectService: IXcodeSelectService) {
4446
super($fs, $projectData, $projectDataService);
4547
}
@@ -146,7 +148,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
146148
this.replaceFileName("-Prefix.pch", projectRootFilePath).wait();
147149
this.replaceFileName(IOSProjectService.XCODE_PROJECT_EXT_NAME, this.platformData.projectRoot).wait();
148150

149-
let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj");
151+
let pbxprojFilePath = this.pbxProjPath;
150152
this.replaceFileContent(pbxprojFilePath).wait();
151153
}).future<void>()();
152154
}
@@ -355,7 +357,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
355357
let isUpdateConfirmed = this.$prompter.confirm(`We need to override xcodeproj file. The old one will be saved at ${this.$options.profileDir}. Are you sure?`, () => true).wait();
356358
if(isUpdateConfirmed) {
357359
// Copy old file to options["profile-dir"]
358-
let sourceDir = path.join(this.platformData.projectRoot, `${this.$projectData.projectName}.xcodeproj`);
360+
let sourceDir = this.xcodeprojPath;
359361
let destinationDir = path.join(this.$options.profileDir, "xcodeproj");
360362
this.$fs.deleteDirectory(destinationDir).wait();
361363
shell.cp("-R", path.join(sourceDir, "*"), destinationDir);
@@ -367,7 +369,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
367369
shell.cp("-R", path.join(cachedPackagePath, "*"), sourceDir);
368370
this.$logger.info(`Copied from ${cachedPackagePath} at ${this.platformData.projectRoot}.`);
369371

370-
let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj");
372+
let pbxprojFilePath = this.pbxProjPath;
371373
this.replaceFileContent(pbxprojFilePath).wait();
372374
}
373375

@@ -512,6 +514,14 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
512514
return (<IPluginsService>this.$injector.resolve("pluginsService")).getAllInstalledPlugins();
513515
}
514516

517+
private get xcodeprojPath(): string {
518+
return path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME);
519+
}
520+
521+
private get cocoaPodsXcodeprojPath(): string {
522+
return path.join(this.platformData.projectRoot, "Pods", "Pods" + IOSProjectService.XCODE_PROJECT_EXT_NAME);
523+
}
524+
515525
private get projectPodFilePath(): string {
516526
return path.join(this.platformData.projectRoot, "Podfile");
517527
}
@@ -539,7 +549,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
539549
}
540550

541551
private get pbxProjPath(): string {
542-
return path.join(this.platformData.projectRoot, this.$projectData.projectName + ".xcodeproj", "project.pbxproj");
552+
return path.join(this.xcodeprojPath, "project.pbxproj");
543553
}
544554

545555
private createPbxProj(): any {
@@ -585,8 +595,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
585595
this.$logger.warn(`Podfile contains more than one post_install sections. You need to open ${this.projectPodFilePath} file and manually resolve this issue.`);
586596
}
587597

588-
let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "xcuserdata");
589-
if(!this.$fs.exists(pbxprojFilePath).wait()) {
598+
let xcuserDataPath = path.join(this.xcodeprojPath, "xcuserdata");
599+
if(!this.$fs.exists(xcuserDataPath).wait()) {
590600
this.$logger.info("Creating project scheme...");
591601
let createSchemeRubyScript = `ruby -e "require 'xcodeproj'; xcproj = Xcodeproj::Project.open('${this.$projectData.projectName}.xcodeproj'); xcproj.recreate_user_schemes; xcproj.save"`;
592602
this.$childProcess.exec(createSchemeRubyScript, { cwd: this.platformData.projectRoot }).wait();
@@ -664,6 +674,24 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
664674
this.$errors.failWithoutHelp("CocoaPods or ruby gem 'xcodeproj' is not installed. Run `sudo gem install cocoapods` and try again.");
665675
}
666676

677+
let cocoapodsVer = this.$sysInfo.getSysInfo(this.$staticConfig.pathToPackageJson).wait().cocoapodVer,
678+
xcodeVersion = this.$xcodeSelectService.getXcodeVersion().wait();
679+
680+
xcodeVersion.patch = xcodeVersion.patch || "0";
681+
let shouldUseXcproj = semver.lt(cocoapodsVer, "1.0.0") && ~helpers.versionCompare(xcodeVersion, "7.3.0");
682+
683+
// CocoaPods with version lower than 1.0.0 don't support Xcode 7.3 yet
684+
// https://github.com/CocoaPods/CocoaPods/issues/2530#issuecomment-210470123
685+
// as a result of this all .pbxprojects touched by CocoaPods get converted to XML plist format
686+
if (shouldUseXcproj) {
687+
// if that's the case we can use xcproj gem to convert them back to ASCII plist format
688+
try {
689+
this.$childProcess.exec("xcproj --version").wait();
690+
} catch(e) {
691+
this.$errors.failWithoutHelp(`You are using CocoaPods version ${cocoapodsVer} which does not support Xcode ${xcodeVersion.major}.${xcodeVersion.minor} yet. In order for the NativeScript CLI to be able to work correctly with this setup you need to install xcproj command line tool and add it to your PATH.`);
692+
}
693+
}
694+
667695
this.$logger.info("Installing pods...");
668696
let podTool = this.$config.USE_POD_SANDBOX ? "sandbox-pod" : "pod";
669697
let childProcess = this.$childProcess.spawnFromEvent(podTool, ["install"], "close", { cwd: this.platformData.projectRoot, stdio: ['pipe', process.stdout, 'pipe'] }).wait();
@@ -683,6 +711,11 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
683711
}
684712
}
685713

714+
if (shouldUseXcproj) {
715+
this.$childProcess.exec(`xcproj --project ${this.xcodeprojPath} touch`).wait();
716+
this.$childProcess.exec(`xcproj --project ${this.cocoaPodsXcodeprojPath} touch`).wait();
717+
}
718+
686719
return childProcess;
687720
}).future<any>()();
688721
}

test/ios-project-service.ts

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ function createTestInjector(projectPath: string, projectName: string): IInjector
7676
testInjector.register("loggingLevels", LoggingLevels);
7777
testInjector.register("utils", Utils);
7878
testInjector.register("iTunesValidator", {});
79+
testInjector.register("sysInfo", {});
7980
testInjector.register("pluginVariablesService", PluginVariablesService);
8081
testInjector.register("pluginVariablesHelper", PluginVariablesHelper);
8182
return testInjector;

0 commit comments

Comments
 (0)