Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cordova plugin.xml add "Header Search Paths" entry

I would like a new entry to be added under "Header Search Paths" once my Cordova plugin is added to an Xcode project.

How can I config it in my Cordova plugin.xml file?

Thanks.

like image 530
Alon Amir Avatar asked Aug 17 '14 11:08

Alon Amir


3 Answers

As far as I know, there's no way to do this on a project-wide basis.

However, there is a way to add to the search path for each of your source files, which accomplishes the same thing. The source-file element in plugin.xml supports a compiler-flags attribute. To this attribute, you may add any flags that the compiler (in this case the clang command) supports. The compiler flag to add to the header search path is -I<path>. Note that if you include a space (eg -I <path>), Cordova will produce a misformatted .xcodeproj folder, and you will not be able to open the project in Xcode, nor build the Cordova project from the command line. Note also that <path> in this case is relative to your .xcodeproj folder that Cordova generates.

So, for example, if you have these files in your plugin folder (let's call it ~/com.MyPlugin/):

myAngleHeader.h
mySource.m
mySource.h

where mySource.h contains the line #include <myAngleHeader.h> and mySource.m contains the line #include "mySource.h"

You would then want to put into your plugin.xml (~/com.MyPlugin/plugin.xml):

<source-file src="myAngleHeader.h" />
<source-file src="mySource.h" />
<source-file src="mySource.m" compiler-flags="-ImyApp/Plugins/com.MyPlugin/" />

where "myApp" is the name of your Cordova project. Note again that there must be no space after the -I flag.

This method unfortunately requires that the developer control both the plugin and the Cordova project. It won't be very useful if you want to publish a plugin for all to use. There is probably a better way to do this; I'd love to hear other solutions.

Hope that helps!

like image 95
John Walthour Avatar answered Nov 15 '22 18:11

John Walthour


@JohnWalthour

I needed to do this for a cordova plugin I am creating and with the "after plugin install" hook it is possible. I realized I could run a node.js script after install and modify the HEADER_SEARCH_PATHS in ${project}/platforms/ios/cordova/build.xcconfig.

It required getting dirty but it works great. One crucial part of this working is that the Bundle name is assigned to ${PRODUCT_NAME} in the info.plist so you can use ${PRODUCT_NAME} in your build.xcconfig and it will interpolate with your project/app name. Cordova already has the ${PRODUCT_NAME} variable set for you.

Here is the relevant code -

plugin.xml (shortened for brevity and the important stuff)

<platform name="ios">
  .....
  <hook type="after_plugin_install" src="hooks/AfterPluginInstall.js" />
  <hook type="before_plugin_uninstall" src="hooks/BeforePluginUninstall.js" />
  .....
</platform>

AfterPluginInstall.js

#!/usr/bin/env node
'use strict';

let cwd = process.cwd();
let fs = require('fs');
let path = require('path');

console.log('InstagramAssetsPicker AfterPluginInstall.js, attempting to modify build.xcconfig');

let xcConfigBuildFilePath = path.join(cwd, 'platforms', 'ios', 'cordova', 'build.xcconfig');
console.log('xcConfigBuildFilePath: ', xcConfigBuildFilePath);
let lines = fs.readFileSync(xcConfigBuildFilePath, 'utf8').split('\n');

let headerSearchPathLineNumber;
lines.forEach((l, i) => {
  if (l.indexOf('HEADER_SEARCH_PATHS') > -1) {
    headerSearchPathLineNumber = i;
  }
});

if (lines[headerSearchPathLineNumber].indexOf('InstagramAssetsPicker') > -1) {
  console.log('build.xcconfig already setup for InstagramAssetsPicker');
  return;
}

lines[headerSearchPathLineNumber] += ' "$(SRCROOT)/$(PRODUCT_NAME)/cordova-plugin-InstagramAssetsPicker/GPUImageHeaders"';

let newConfig = lines.join('\n');

fs.writeFile(xcConfigBuildFilePath, newConfig, function (err) {
  if (err) {
    console.log('error updating build.xcconfig, err: ', err);
    return;
  }
  console.log('successfully updated HEADER_SEARCH_PATHS in build.xcconfig');
});

BeforePluginUninstall.js

#!/usr/bin/env node
'use strict';

let cwd = process.cwd();
let fs = require('fs');
let path = require('path');

console.log('InstagramAssetsPicker BeforePluginInstall.js, attempting to modify build.xcconfig');

let xcConfigBuildFilePath = path.join(cwd, 'platforms', 'ios', 'cordova', 'build.xcconfig');
console.log('xcConfigBuildFilePath: ', xcConfigBuildFilePath);
let lines = fs.readFileSync(xcConfigBuildFilePath, 'utf8').split('\n');

let headerSearchPathLineNumber;
lines.forEach((l, i) => {
  if (l.indexOf('HEADER_SEARCH_PATHS') > -1) {
    headerSearchPathLineNumber = i;
  }
});

if (lines[headerSearchPathLineNumber].indexOf('InstagramAssetsPicker') === -1) {
  console.log('build.xcconfig does not have header path for InstagramAssetsPicker.');
  return;
}

let line = lines[headerSearchPathLineNumber];
lines[headerSearchPathLineNumber] = line.replace(/\ "\$\(SRCROOT\)\/\$\(PRODUCT_NAME\)\/cordova-plugin-InstagramAssetsPicker\/GPUImageHeaders\"/i, '');

let newConfig = lines.join('\n');

fs.writeFile(xcConfigBuildFilePath, newConfig, function (err) {
  if (err) {
    console.log('error updating build.xcconfig, err: ', err);
    return;
  }
  console.log('successfully updated HEADER_SEARCH_PATHS in build.xcconfig');
});
like image 2
Ross Avatar answered Nov 15 '22 16:11

Ross


I wanted to update my header search paths via the config as it was always a manual task setting it on build day. I have since added this plugin:

Cordova-Custom-Plugin

I was then able to add these to my config and didn't have to worry about it again.

<platform name="ios">
   <!-- Set orientation on iPhone -->
   <config-file platform="ios" target="*-Info.plist" parent="UISupportedInterfaceOrientations">
     <array>
       <string>UIInterfaceOrientationPortrait</string>
       <string>UIInterfaceOrientationPortraitUpsideDown</string>
     </array>
   </config-file>
   <!-- Set orientation on iPad -->
   <config-file platform="ios" target="*-Info.plist" parent="UISupportedInterfaceOrientations~ipad">
     <array>
       <string>UIInterfaceOrientationLandscapeLeft</string>
       <string>UIInterfaceOrientationLandscapeRight</string>
     </array>
   </config-file>
   <!-- Set Header Search Paths-->
   <preference name="ios-XCBuildConfiguration-HEADER\_SEARCH\_PATHS" value="'$(TARGET_BUILD_DIR)/usr/local/lib/include' '$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include' '$(BUILT_PRODUCTS_DIR)'" buildType="release" xcconfigEnforce="true" />

like image 2
tyler_mitchell Avatar answered Nov 15 '22 17:11

tyler_mitchell