@icedevml/react-native-host-card-emulation 0.6.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -200,6 +200,11 @@ This function will throw an exception if:
200
200
  * you are in the cooldown period where you are not allowed to acquire the presentment intent assertion (cooldown is 15 seconds after the previous assertion had expired);
201
201
  * the feature is not supported or the device is not eligible for whatever reason;
202
202
 
203
+ Whenever you don't need the exclusive NFC access anymore, call the following function to release the `NFCPresentmentIntentAssertion` object:
204
+ ```typescript
205
+ await NativeHCEModule.releaseExclusiveNFC();
206
+ ```
207
+
203
208
  Call `NativeHCEModule.isExclusiveNFC()` to check if exclusive NFC access is still active.
204
209
 
205
210
  ### Android: Handle HCE calls when the app is not running
@@ -119,6 +119,12 @@ public class RTNHCEAndroidModule extends NativeHCEModuleSpec {
119
119
  promise.reject("err_platform_unsupported", "acquireExclusiveNFC() is not supported on Android.");
120
120
  }
121
121
 
122
+ @Override
123
+ public void releaseExclusiveNFC() {
124
+ Log.d(TAG, "RTNHCEAndroidModule:releaseExclusiveNFC");
125
+ // unsupported on Android, no-op
126
+ }
127
+
122
128
  @Override
123
129
  public boolean isExclusiveNFC() {
124
130
  Log.d(TAG, "RTNHCEAndroidModule:isExclusiveNFC");
@@ -50,6 +50,12 @@
50
50
  }
51
51
  }
52
52
 
53
+ - (void)releaseExclusiveNFC {
54
+ if (@available(iOS 17.4, *)) {
55
+ [hcemoduleios releaseExclusiveNFC];
56
+ }
57
+ }
58
+
53
59
  - (nonnull NSNumber *)isExclusiveNFC {
54
60
  if (@available(iOS 17.4, *)) {
55
61
  return [hcemoduleios isExclusiveNFC] ? @1 : @0;
@@ -90,6 +96,10 @@
90
96
  return @0;
91
97
  }
92
98
 
99
+ - (nonnull NSNumber *)finishBackgroundHCE:(nonnull NSString *)handle {
100
+ return @0;
101
+ }
102
+
93
103
  - (void)startHCE:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
94
104
  if (@available(iOS 17.4, *)) {
95
105
  return [hcemoduleios startHCEWithResolve:resolve reject:reject];
@@ -34,6 +34,21 @@ extension Data {
34
34
 
35
35
  @objc public func acquireExclusiveNFC(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
36
36
  Task.init {
37
+ guard NFCReaderSession.readingAvailable else {
38
+ reject("err_nfc_reader_not_available", "Preflight check failed: NFCReaderSession.readingAvailable is false", nil)
39
+ return
40
+ }
41
+
42
+ guard CardSession.isSupported else {
43
+ reject("err_card_session_unsupported", "Preflight check failed: CardSession.isSupported is false", nil)
44
+ return
45
+ }
46
+
47
+ guard await CardSession.isEligible else {
48
+ reject("err_card_session_not_eligible", "Preflight check failed: CardSession.isEligible is false", nil)
49
+ return
50
+ }
51
+
37
52
  if self.presentmentIntent != nil && self.presentmentIntent!.isValid {
38
53
  reject("err_already_exists", "NFCPresentmentIntentAssertion already exists and is valid.", nil)
39
54
  return
@@ -44,8 +59,7 @@ extension Data {
44
59
  do {
45
60
  self.presentmentIntent = try await NFCPresentmentIntentAssertion.acquire()
46
61
  } catch (let error) {
47
- // TODO exact error details here and in other places as well
48
- reject("err_create_presentment", "Failed to create NFCPresentmentIntentAssertion: \(error)", nil)
62
+ reject("err_create_presentment_\(error)", "Failed to acquire NFCPresentmentIntentAssertion: \(error)", nil)
49
63
  return
50
64
  }
51
65
 
@@ -53,6 +67,10 @@ extension Data {
53
67
  }
54
68
  }
55
69
 
70
+ @objc public func releaseExclusiveNFC() {
71
+ self.presentmentIntent = nil
72
+ }
73
+
56
74
  @objc public func isExclusiveNFC() -> Bool {
57
75
  return self.presentmentIntent != nil && self.presentmentIntent!.isValid
58
76
  }
@@ -82,10 +100,11 @@ extension Data {
82
100
  do {
83
101
  self.cardSession = try await CardSession()
84
102
  } catch (let error) {
85
- reject("err_create_card_session", "Failed to create CardSession(): \(error)", nil)
103
+ reject("err_create_card_session_\(error)", "Failed to create CardSession: \(error)", nil)
86
104
  return
87
105
  }
88
106
 
107
+ self.cardSessionInvalidated = false
89
108
  resolve(nil)
90
109
 
91
110
  do {
@@ -151,7 +170,7 @@ extension Data {
151
170
  reject("err_illegal_state", "The provided handle is invalid.", nil)
152
171
  return
153
172
  }
154
-
173
+
155
174
  guard let capdu = self.receivedCardAPDU else {
156
175
  reject("err_no_apdu_received", "There is no received APDU to respond to.", nil)
157
176
  return
@@ -47,6 +47,11 @@ export interface Spec extends TurboModule {
47
47
  * Android: Not supported (throws an exception).
48
48
  */
49
49
  acquireExclusiveNFC(): Promise<void>;
50
+ /**
51
+ * iOS: Release NFCPresentmentIntentAssertion object.
52
+ * Android: Not supported (no-op).
53
+ */
54
+ releaseExclusiveNFC(): void;
50
55
  /**
51
56
  * iOS: Whether the NFCPresentmentIntentAssertion is acquired and still valid.
52
57
  * Android: Always false.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icedevml/react-native-host-card-emulation",
3
- "version": "0.6.3",
3
+ "version": "0.7.0",
4
4
  "description": "Host Card Emulation (HCE) React Native Turbo Module for iOS and Android platforms.",
5
5
  "react-native": "js/index",
6
6
  "source": "js/index",