Skip to content

Commit 751dd3e

Browse files
blackdragonDimitar Kerezov
blackdragon
authored and
Dimitar Kerezov
committed
Use xcproj if needed to fix .pbxproject format
CocoaPods < 1.0.0 does not support Xcode 7.3 yet and leaves all .pbxprojects in XML plist format instead of the ASCII plist one. Use xcproj if the user's configuration requires it to fix the .pbxproject's format.
1 parent db0ea50 commit 751dd3e

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
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)