🕌
ReactNative + Expo + AppClip + NFC
react-native-app-clip
+ react-native-nfc-manager
を組み合わせて使った場合、react-native-app-clip
がAppClip側のentitlementsファイルを更新してくれないためAppClip側でNFCが有効にならない。
そのために以下のようにAppClipにもNFCの設定を行う。
scripts/add-nfc-entitlement-to-app-clip.js
/**
* ExpoにはiOSのentitlementsを設定する機能があるが、
* react-native-app-clipを使った場合AppClip側のentitlementsを設定できないので
* 直接ファイルを修正して追加する
*
* iOS capabilities - Expo Documentation https://docs.expo.dev/build-reference/ios-capabilities/
*/
if (process.env.EAS_BUILD_PLATFORM !== "ios") {
console.log("iOS ビルドではないため、スクリプトをスキップします。");
process.exit(0);
}
const fs = require("fs");
const path = require("path");
// エンタイトルメントファイルのパス
const entitlementsPath = path.join(
__dirname,
"../ios/xxxClip/xxxClip.entitlements",
);
// ファイルが存在するか確認
if (!fs.existsSync(entitlementsPath)) {
console.error(`エラー: ${entitlementsPath} が見つかりません。`);
process.exit(1);
}
// ファイルの内容を読み込む
let content = fs.readFileSync(entitlementsPath, "utf8");
// すでに NFC エンタイトルメントが含まれているか確認
if (content.includes("com.apple.developer.nfc.readersession.formats")) {
console.log("NFC エンタイトルメントはすでに追加されています。");
process.exit(0);
}
// </dict> の前に NFC エンタイトルメントを追加
const nfcEntitlement = ` <key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>`;
content = content.replace(" </dict>", `${nfcEntitlement}\n </dict>`);
// 変更を保存
fs.writeFileSync(entitlementsPath, content, "utf8");
console.log("NFC エンタイトルメントが正常に追加されました。");
上記jsを eas-build-post-install
経由で実行する。
package.json
{
"scripts": {
"eas-build-post-install": "node ./scripts/add-nfc-entitlement-to-app-clip.js"
},
"dependencies": {
"react-native-app-clip": "~0.5.1"
"react-native-nfc-manager": "~3.16.1"
}
}
ちなみにexpoは @expo/config-plugins
というpackageを提供していて、その中には withEntitlementsPlist
というfunctionも存在するが、 @expo/config-plugins
の提供するfunctionはいずれもAppClipに対応していないため使用できない。
Discussion