cordova-cli icon indicating copy to clipboard operation
cordova-cli copied to clipboard

[iOS] Changes made by plugin hooks are rewritten due to project file caching

Open smishenk opened this issue 4 years ago • 0 comments

Bug Report

Changes which are made in .xcodeproj by plugin in before_compile hook are rewritten by Сordova build scripts.

Problem

I have a project that uses BlackBerry Dynamics SDK for Cordova. To enable core BlackBerry features I have to add cordova-plugin-bbd-base plugin. This plugin adds some BlackBerry frameworks to .xcodeproj to build and link a project against within before_compile hook (I have no idea on why they've chosen exactly that hook). Unfortunately, if I use Cordova CLI commands like build or run , I get build and link errors, because Cordova scripts unintentionally re-write project configurations.

What is expected to happen?

Project builds successfully if I run one of this command:

cordova build ios --release --device
cordova run ios --release --device

What does actually happen?

Project build is failed because required BlackBerry frameworks wasn't added to project configuration. Worth to mention: if I try to execute all build phases separately, like:

cordova prepare ios
cordova compile ios --release --device

Then I have no issues with project build

Information

I managed to find out what is the root cause of my issue by exploring Cordova build scripts. Just to be clear, I'm talking about scripts that are located within <project_dir>/platforms/ios/cordova/ after execution of cordova platform add ios command. My problem is connected with projectFile.js module since it caches project files by project directory. In the same time, when I execute cordova build command, both prepare and compile phases are run in the same environment and share the same instance of projectFile module. Thus, project file is cached during prepare phase, then it is changed in before_compile hook (and Cordova scripts are unaware of it) and finally it is restored to 'cordova-scripts' version when compile phase processes build options and make final adjustments within project file here:

function writeCodeSignStyle (value) {
    const project = createProjectObject(projectPath, projectName);

    events.emit('verbose', `Set CODE_SIGN_STYLE Build Property to ${value}.`);
    project.xcode.updateBuildProperty('CODE_SIGN_STYLE', value);
    events.emit('verbose', `Set ProvisioningStyle Target Attribute to ${value}.`);
    project.xcode.addTargetAttribute('ProvisioningStyle', value);

    project.write();
}

if (buildOpts.provisioningProfile) {
    events.emit('verbose', 'ProvisioningProfile build option set, changing project settings to Manual.');
    writeCodeSignStyle('Manual');
} else if (buildOpts.automaticProvisioning) {
    events.emit('verbose', 'ProvisioningProfile build option NOT set, changing project settings to Automatic.');
    writeCodeSignStyle('Automatic');
}

When I execute prepare and compile phases separately, each phase gets correct and 'up-to-date' project file version and everything goes fine. Though my case might be quite unique, I believe the problem itself is much wider. I've not found any limitations of actions which can be performed within hooks in documentation. So, xcodeproj modification on before_compile hook looks more or less OK. It seems more like a bug to me that project file is cached along all of the build phases, while any custom actions on hooks are allowed.

Version information

Cordova: 10.0.0, Cordova Platforms: iOS, Cordova Plugins: cordova-plugin-bbd-base, Ionic Framework: 5.3.2, Ionic CLI: 6.15.0, Operating System: macOS 10.15.6, XCode: 12.4

Checklist

  • [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

smishenk avatar May 12 '21 15:05 smishenk