From c4bdd25c4a829973ee5833f605902ece82c5116a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Leszczy=C5=84ski?= Date: Wed, 24 Sep 2025 05:47:59 +0200 Subject: [PATCH 1/6] Update README.md --- packages/host-card-emulation/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/host-card-emulation/README.md b/packages/host-card-emulation/README.md index facd435..3459b3f 100644 --- a/packages/host-card-emulation/README.md +++ b/packages/host-card-emulation/README.md @@ -121,7 +121,7 @@ This module provides a uniform low-level HCE API for both mobile platforms. > Check it out in order to understand what methods you can call against the module and what are the expected parameters/return values. > [!NOTE] -> See [Source Code for Demo Application: NDEF NFC Type 4 Tag Emulator (for iOS/Android)](https://github.com/icedevml/react-native-host-card-emulation/tree/master/packages/demo-ndef-app) example for more insignt about the library's API. +> See [Source Code for Demo Application: NDEF NFC Type 4 Tag Emulator (for iOS/Android)](https://github.com/icedevml/react-native-host-card-emulation/tree/master/packages/demo-ndef-app) example for more insights about the library's API. ### Quick start guide @@ -140,7 +140,7 @@ This module provides a uniform low-level HCE API for both mobile platforms. } }, []); ``` -2. When user indicates that he/she wants to perform the HCE action, call the following function from the button's onClick routine: +2. When the user indicates that he/she wants to perform the HCE action, call the following function from the button's onClick routine: ```typescript await NativeHCEModule.beginSession(); ``` @@ -163,8 +163,8 @@ This module provides a uniform low-level HCE API for both mobile platforms. break; case 'readerDeselected': - NativeHCEModule.setSessionAlertMessage('Lost reader'); // only for iOS, no-op in Android - break; + NativeHCEModule.setSessionAlertMessage('Lost reader'); // only for iOS, no-op in Android + break; ``` For those events, trigger mechanisms are platform dependent: * iOS: The `readerDetected` event will be emitted as soon as the NFC reader's field presence is observed. The `readerDeselected` event will be emitted if the reader is physically disconnected or a non-matching AID is selected by the reader. @@ -191,7 +191,7 @@ If you need to utilize `NFCPresentmentIntentAssertion` for enhanced user experie ```typescript await NativeHCEModule.acquireExclusiveNFC(); ``` -This function will acquire an exclusive NFC access for 15 seconds. On system services or other applications will be able to interfere with NFC during that period. For example, the NFC background tag reading will be disabled so it would not generate any distracting notifications. +This function will acquire an exclusive NFC access for 15 seconds. No system services or other applications will be able to interfere with NFC during that period. For example, the NFC background tag reading will be disabled so it would not generate any distracting notifications. While both session and exclusive NFC access are active, you will receive `readerDetected` events even when the HCE emulation is not started at the time (without any explicit UI being displayed by the system). You can then make a call to `startHCE` to initiate the interaction automatically, without needing the user to click anything beforehand. @@ -240,7 +240,7 @@ for instance - your app may emulate an NDEF tag even when it's not launched on t } }); ``` -2. Register onBackgroundEvent listener in your `runBackground()` function and call to `await NativeHCEModule.initBackgroundHCE()` at the very end, after the event listener is fully set up. +2. Implement your background HCE handler by passing an event callback to `processBackgroundHCE()`: ```typescript import { Buffer } from 'buffer/'; import { @@ -255,7 +255,7 @@ for instance - your app may emulate an NDEF tag even when it's not launched on t }); } ``` -3. Cleanup your event listener in `readerDeselected` -- this is obligatory because lack of proper cleanup will result in bugs and unexpected behavior. +3. Whenever you receive `readerDeselected` event, cleanup any side effects (deallocate resources, reset the state back to initial) -- this is obligatory because lack of proper cleanup will result in bugs and unexpected behavior. ```typescript // inside processBackgroundHCE handler's switch case 'readerDeselected': From a7875f21dc1198557ede03f697fbea95776fba69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Leszczy=C5=84ski?= Date: Wed, 24 Sep 2025 06:10:06 +0200 Subject: [PATCH 2/6] Update README.md --- packages/host-card-emulation/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/host-card-emulation/README.md b/packages/host-card-emulation/README.md index 3459b3f..60bca96 100644 --- a/packages/host-card-emulation/README.md +++ b/packages/host-card-emulation/README.md @@ -248,6 +248,8 @@ for instance - your app may emulate an NDEF tag even when it's not launched on t } from '@icedevml/react-native-host-card-emulation/js/hceBackground'; export default async function runBackgroundHCETask(processBackgroundHCE: ProcessBackgroundHCEFunc) { + // ... initialize any state keeping variables here ... + processBackgroundHCE(async (event, respondAPDU) => { switch (event.type) { /* ... background HCE event handler here ... */ @@ -276,6 +278,12 @@ for instance - your app may emulate an NDEF tag even when it's not launched on t break; ``` +> [!WARNING] +> Please note that under some circumstances you might find that your `runBackgroundHCETask()` is running in a few instances concurrently. +> An example of such situation could be when you receive a C-APDU and the reader rapidly restarts the NFC field and reselects your application +> before you manage to respond to the original command. Thus, you should not use any global variables to track the state of your app. +> Calls to `await respondAPDU()` from stale tasks will throw an error to avoid glitching the communications. + ### More resources * [Module's API specification](https://github.com/icedevml/react-native-host-card-emulation/tree/master/packages/host-card-emulation/js) From 857eb41f594970864cd4edfb44230e2a662152a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Leszczy=C5=84ski?= Date: Wed, 24 Sep 2025 06:15:07 +0200 Subject: [PATCH 3/6] Update README.md --- packages/host-card-emulation/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/host-card-emulation/README.md b/packages/host-card-emulation/README.md index 60bca96..d1f93b7 100644 --- a/packages/host-card-emulation/README.md +++ b/packages/host-card-emulation/README.md @@ -282,7 +282,9 @@ for instance - your app may emulate an NDEF tag even when it's not launched on t > Please note that under some circumstances you might find that your `runBackgroundHCETask()` is running in a few instances concurrently. > An example of such situation could be when you receive a C-APDU and the reader rapidly restarts the NFC field and reselects your application > before you manage to respond to the original command. Thus, you should not use any global variables to track the state of your app. -> Calls to `await respondAPDU()` from stale tasks will throw an error to avoid glitching the communications. +> +> The library automatically identifies stale (deselected) background tasks. For such stale tasks, any subsequent calls to `await respondAPDU()` +> will throw an error to prevent communication glitches. ### More resources From f334b282ca070a723d18e3a7b79974b605a4568c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Leszczy=C5=84ski?= Date: Wed, 24 Sep 2025 06:16:19 +0200 Subject: [PATCH 4/6] Update README.md --- packages/host-card-emulation/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/host-card-emulation/README.md b/packages/host-card-emulation/README.md index d1f93b7..77baa31 100644 --- a/packages/host-card-emulation/README.md +++ b/packages/host-card-emulation/README.md @@ -3,7 +3,7 @@ Host Card Emulation Module for React Native on iOS and Android platforms. > [!NOTE] -> Pull requests are welcome! Please [report an issue](https://github.com/icedevml/react-native-host-card-emulation/issues) if you are running into any difficulties. +> Pull requests are welcome! Please [report an issue](https://github.com/icedevml/react-native-host-card-emulation/issues) if you encounter any difficulties. > [!IMPORTANT] > As per Apple's policy, **Host Card Emulation feature is only available for users based in the European From 4c4d5c4fb3b8d64d0bd33ca13355fa975cc4fc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Leszczy=C5=84ski?= Date: Wed, 24 Sep 2025 06:25:29 +0200 Subject: [PATCH 5/6] Update README.md --- packages/demo-ndef-app/README.md | 36 +++++++++++++++++--------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/demo-ndef-app/README.md b/packages/demo-ndef-app/README.md index 1ebde20..42a411f 100644 --- a/packages/demo-ndef-app/README.md +++ b/packages/demo-ndef-app/README.md @@ -3,30 +3,32 @@ Demo React Native application using `@icedevml/react-native-host-card-emulation` in order to emulate NFC Forum Type 4 Tag with an example URL NDEF. > [!NOTE] -> Make sure you have completed the [Set Up Your Environment](https://reactnative.dev/docs/set-up-your-environment) guide before proceeding. +> Make sure you have completed the [React Native's Set Up Your Environment](https://reactnative.dev/docs/set-up-your-environment) guide before proceeding. + +> [!NOTE] +> For iOS, you will first need to [request the HCE entitlement](https://developer.apple.com/contact/request/hce-entitlement/) for using ISO7816 AID `D2760000850101` (i.e. NFC Forum Type 4 Tag - NDEF) before you can run this app. ## Prerequisites 1. Clone the repository. 2. Run `yarn` to install dependencies. -3. (iOS) Make sure to set up your Signing Team and Bundle Identifier in "Signing & Capabilities" settings section of the project. -4. (iOS) Ensure that Host Card Emulation (HCE) entitlement is added to the project with proper ISO7816 AIDs enabled. +3. (iOS) Install Pods: `cd ios/ && bundle install && bundle exec pod install`. Then, open the project in XCode through the `ios/.xcworkspace` file. +4. (iOS) Make sure to set up your Signing Team and Bundle Identifier in "Signing & Capabilities" settings section of the project. +5. (iOS) Ensure that Host Card Emulation (HCE) entitlement with the ISO7816 AID `D2760000850101` is added to the app. ## Launching the app +### Android +1. Start Metro dev server: + ```sh + yarn start + ``` +2. Build and run the app: + ``` + npx react-native run-android + ``` + +### iOS 1. Start Metro dev server: ```sh yarn start ``` -2. (iOS) Install Pods: - ```sh - cd ios/ - bundle install - bundle exec pod install - ``` -3. (iOS) Build and run application: - ```sh - yarn ios - ``` - (Android) Build and run application: - ```sh - yarn android - ``` +2. (iOS) Press the "Run" button in XCode. From cf2ed7bc886c8aa7d2135f9bdb1275e8d2e7fffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Leszczy=C5=84ski?= Date: Wed, 24 Sep 2025 06:26:14 +0200 Subject: [PATCH 6/6] Update README.md --- packages/demo-ndef-app/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/demo-ndef-app/README.md b/packages/demo-ndef-app/README.md index 42a411f..09fd630 100644 --- a/packages/demo-ndef-app/README.md +++ b/packages/demo-ndef-app/README.md @@ -10,7 +10,7 @@ Demo React Native application using `@icedevml/react-native-host-card-emulation` ## Prerequisites 1. Clone the repository. -2. Run `yarn` to install dependencies. +2. Run `yarn` inside the project's directory to install dependencies. 3. (iOS) Install Pods: `cd ios/ && bundle install && bundle exec pod install`. Then, open the project in XCode through the `ios/.xcworkspace` file. 4. (iOS) Make sure to set up your Signing Team and Bundle Identifier in "Signing & Capabilities" settings section of the project. 5. (iOS) Ensure that Host Card Emulation (HCE) entitlement with the ISO7816 AID `D2760000850101` is added to the app.