サードパーティー製 Cordova プラグインを使用する場合、Cordova の Android プラットフォームや iOS プラットフォームに対して、開発者側が手動で設定を行う必要があるケースがあります。

Monaca では、開発者側がビルドの際に使用される Android プラットフォームや iOS プラットフォームを直接操作することができません。

そのため、Android プラットフォームや iOS プラットフォームに対し、何かしらの設定を行う必要がある場合は、Cordova の hook スクリプトを利用して操作する必要があります。

hook スクリプトの設定場所

hook スクリプトは、以下から利用することができます。

設定場所 備考
hooks ディレクトリ アプリ内で設定 ( Deprecated )
config.xml アプリ内で設定
plugin.xml Cordova プラグイン内で設定

現在、hooks ディレクトリからの hook スクリプトは、非推奨となっています。

Monaca プロジェクトでは、hooks ディレクトリは用意されていないため、hook スクリプトを利用する場合は、config.xml または plugin.xml から利用します。

サポートされている hook タイプ

hook スクリプトを実行するタイミングは、after_plugin_addbefore_prepare など、数多くあります。

詳しくは、Hooks を参照していください。

hook スクリプトの利用方法

config.xml や plugin.xml から hook スクリプトを利用する場合は、hook タグを使用します。

<hook type="before_prepare" src="scripts/beforePrepare.js" />

<platform name="android">
  <hook type="before_prepare" src="scripts/beforePrepare.js" />
</platform>

<platform name="ios">
  <hook type="before_prepare" src="scripts/beforePrepare.js" />
</platform>

hook スクリプトの作成方法

hook スクリプトは、Node.js 上で動作するため、次のモジュールを定義して作成する必要があります。

module.exports = function(context) {
  ...
}

このモジュール内に、必要な処理を追加していきます。

context からは、Android プラットフォームや iOS プラットフォームのルートパスや、プラットフォームの種類などの情報を取得することができます。

サンプル

iCloud を利用する Cordova プラグインでは、exportOptions.plistiCloudContainerEnvironment の設定を行う必要がある場合があります。

Monaca プロジェクトで iCloudContainerEnvironment の設定を行う場合は、ビルドの際に使用される build.json に設定を行う必要があります。

サンプルとして、build.json に iCloudContainerEnvironment の設定を追加する hook スクリプトを作成してみます。

このサンプルでは、config.xml から hook スクリプトを実行します。

<platform name="ios">
  <hook type="before_compile" src="/www/scripts/beforeCompile.js" />
</platform>

hook スクリプトは、Monacaプロジェクトの www フォルダー配下に scripts フォルダーを作成して、beforeCompile.js として保存しています。

今回の対象は ios のため、<platform name="ios"> 配下に hook タグを設定しています。

今回設定する build.json は、compile が実行される前に作成されるため、before_compile のタイミングで hook スクリプトを実行します。

// beforeCompile.js
module.exports = function (context) {
  console.log(context.opts.platforms);
  if (!context.opts.platforms.includes('ios')) return;

  var fs = require('fs');
  var path = require('path');

  try {
    fs.statSync('./build.json');
    console.log('exists build.json');
  } catch(err) {
    if(err.code === 'ENOENT') {
      var jsonData = '{"ios": {"debug": {},"release": {}}}';
      fs.writeFileSync('./build.json', jsonData, 'utf8');
      console.log('Create build.json');
    } else {
      console.log('error');
    }
  }

  var root = context.opts.projectRoot;
  var buildFile = path.resolve(root, 'build.json');
  var content = fs.readFileSync(buildFile, 'utf8');
  var jsonObjects = JSON.parse(content);

  console.log(jsonObjects);
  if ('debug' in jsonObjects.ios) {
    jsonObjects.ios.debug.iCloudContainerEnvironment = "Development";
  }

   if ('release' in jsonObjects.ios) {
      jsonObjects.ios.release.iCloudContainerEnvironment = "Production";
  }

  fs.writeFileSync(buildFile, JSON.stringify(jsonObjects), 'utf8');
};

context.opts.platforms から、プラットフォーム情報を取得することができます。

今回の対象は iOS のため、ontext.opts.platforms に ios が含まれていない場合は、そこで処理は終了します。

context.opts.projectRoot からは、ビルド時に使用されるプロジェクトのルートパスを取得することができます。

build.json は、プロジェクトのルートに作成されるため、このcontext.opts.projectRoot を取得後、build.json のパスを取得しています。

build.json の読み込みは、readFileSync を使用し、同期処理で行っています。

readFileSync で読み込んだ build.json を JSON.parse() で解析し、JavaScript のオブジェクトへ変換後、iCloudContainerEnvironment の設定を追加しています。

build.json は、下記のような構成になっています。

// build.json例
{
  "ios": {
    "debug": {
      "codeSignIdentity":"iPhone Developer: xxx",
      "provisioningProfile":"xxxxx-xxxx",
      "developmentTeam": "xxx",
      "packageType": "development"
    }
  }
}

build.json には、ビルドの際に選択したビルドタイプのみの情報が設定されるため、ビルドタイプが debugrelease かのチェックを行い、iCloudContainerEnvironment の設定を追加しています。

最後に、writeFileSync で追加した内容を同期処理で build.json に書き込んでいます。

おわりに

hook スクリプトを利用すると、ビルドの際に Monaca の設定画面からでは行えない設定を反映させることができる場合がありますので、機会があれば、一度 hook スクリプトにチャレンジしてみてはいかがでしょうか。