dpolivy opened a new issue, #1357:
URL: https://github.com/apache/cordova-ios/issues/1357
# Bug Report
## Problem
I have an `after_prepare` hook that adds a new build phase to the Xcode
project file. This worked fine on `cordova-ios` up to v6.3.0 but now fails on
7.0.0. While this may be a bug in `cordova-node-xcode`, it is exposed by
changes to the project file in `cordova-ios`. I'm not sure if the project
template structure can be adjusted to resolve this? It seems that some elements
(e.g. `Assets.xcassets`) are now missing a `path` variable which is causing an
exception in the `addBuildPhase` function.
### What is expected to happen?
After adding the hook and running `cordova prepare ios`, the build phase
should get added to the project file.
### What does actually happen?
````
$ cordova platform add ios
Using cordova-fetch for cordova-ios
Adding ios project...
Creating Cordova project for the iOS platform:
Path: platforms/ios
Package: com.hook.test
Name: Test
iOS project created with [email protected]
Platform Root: /Users/dan/Projects/hooktest/platforms/ios
Project Name: Test
Project location:
/Users/dan/Projects/hooktest/platforms/ios/Test.xcodeproj/project.pbxproj
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type
string. Received undefined
at new NodeError (node:internal/errors:399:5)
at validateString (node:internal/validators:163:11)
at Object.basename (node:path:1309:5)
at new pbxFile
(/Users/dan/Projects/hooktest/node_modules/xcode/lib/pbxFile.js:189:26)
at pbxProject.addBuildPhase
(/Users/dan/Projects/hooktest/node_modules/xcode/lib/pbxProject.js:921:26)
at pbxProject.<anonymous>
(/Users/dan/Projects/hooktest/script/addbuildphase.js:86:26)
at pbxProject.emit (node:events:513:28)
at pbxProject.<anonymous>
(/Users/dan/Projects/hooktest/node_modules/xcode/lib/pbxProject.js:48:18)
at ChildProcess.emit (node:events:513:28)
at emit (node:internal/child_process:937:14) {
code: 'ERR_INVALID_ARG_TYPE'
}
````
## Information
<!-- Include all relevant information that might help understand and
reproduce the problem -->
The issue is related to two assets in the project file: `Assets.xcassets`
and `CDVLaunchScreen.storyboard` are missing a `path` parameter in
`cordova-ios@7`:
For example, this line:
https://github.com/apache/cordova-ios/blob/master/templates/project/__PROJECT_NAME__.xcodeproj/project.pbxproj#L61
Should be modified to include a path variable like so:
0207DA571B56EA530066E2B4 /* Assets.xcassets */ = {isa =
PBXFileReference; lastKnownFileType = folder.assetcatalog; name =
Assets.xcassets; path = Project/Assets.xcassets; sourceTree = "<group>"; };
### Command or Code
<!-- What command or code is needed to reproduce the problem? -->
- Create a new cordova project: `cordova create . com.test.app Test`
- Save the following to the project folder as `afterprepare.js`:
````
const fs = require('fs');
const path = require('path');
const xcode = require('xcode');
const deferral = require('q').defer();
const BUILD_PHASE_NAME = 'Settings Bundle Version Update';
/**
* Finds the Xcode project for the app
*/
function findXCodeProjectNameIn(projectPath) {
var files = fs.readdirSync(projectPath).filter(function(elm) {
return elm.match(/.*\.xcodeproj/ig);
});
if (files.length > 1) {
console.log('WARNING: Found multiple .xcodeproj directories!');
}
else if (files.length === 0) {
console.log('ERROR: No Xcode project found.');
return;
}
return files[0].replace('.xcodeproj', '');
}
module.exports = function(ctx) {
if (ctx.opts.platforms.indexOf('ios') < 0) {
return;
}
var platforms = ctx.cordova.platforms['ios'].parse;
var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/ios');
var projName = findXCodeProjectNameIn(platformRoot);
if (!projName) return;
console.log('Platform Root:', platformRoot);
console.log('Project Name:', projName);
var projFileLocation = path.join(platformRoot, projName + '.xcodeproj',
'project.pbxproj');
var myProj = xcode.project(projFileLocation);
console.log('Project location:', projFileLocation);
// Parse the project file
myProj.parse(function (err) {
var scriptBuildPhases =
myProj.hash.project.objects['PBXShellScriptBuildPhase'];
// See if the build phase already exists
for (var phase in scriptBuildPhases) {
if (scriptBuildPhases[phase].name === '"' +
BUILD_PHASE_NAME + '"') {
deferral.resolve();
console.log('Settings: Build phase already
exists in ' + projFileLocation)
return;
}
}
var options = {
shellPath: '/bin/sh',
shellScript: 'app_version=`/usr/libexec/PlistBuddy -c
\"Print CFBundleShortVersionString\" $SRCROOT/' + projName + '/' + projName +
'-Info.plist`\\n\\napp_bundle_version=`/usr/libexec/PlistBuddy -c \"Print
CFBundleVersion\" $SRCROOT/' + projName + '/' + projName +
'-Info.plist`\\n\\n/usr/libexec/PlistBuddy \"$SRCROOT/' + projName +
'/Resources/Settings.bundle/Root.plist\" -c \"set
PreferenceSpecifiers:0:DefaultValue $app_version ($app_bundle_version)\"'
};
try {
var newPhase = myProj.addBuildPhase([],
'PBXShellScriptBuildPhase', BUILD_PHASE_NAME, myProj.getFirstTarget().uuid,
options);
} catch (e) { console.log(e) }
// Move the new phase to the top so it runs before the build
var buildPhases =
myProj.pbxNativeTargetSection()[myProj.getFirstTarget().uuid].buildPhases;
for (var phase in buildPhases) {
if (buildPhases[phase].value === newPhase.uuid) {
buildPhases.splice(0, 0,
buildPhases.splice(phase, 1)[0]);
}
}
fs.writeFileSync(projFileLocation, myProj.writeSync());
console.log('Settings: Added build phase to project ' +
projFileLocation);
deferral.resolve();
});
return deferral.promise;
};
````
- Add the following to `config.xml`: `<hook type="after_prepare"
src="afterprepare.js" />`
- Add the ios platform: `cordova platform add ios`
### Environment, Platform, Device
<!-- In what environment, on what platform or on which device are you
experiencing the issue? -->
cordova-ios@7
### Version information
<!--
What are relevant versions you are using?
For example:
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
Other Frameworks: Ionic Framework and CLI version
Operating System, Android Studio, Xcode etc.
-->
Cordova CLI 12
cordova-ios 7
## Checklist
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
- [x] I searched for existing GitHub issues
- [x] I updated all Cordova tooling to most recent version
- [x] I included all the necessary information above
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]