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]

Reply via email to