react-native-nfc-manager 3.11.3 → 3.13.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
@@ -32,9 +32,9 @@ For Android, it should be properly auto-linked, so you don't need to do anything
32
32
 
33
33
  Please see [here](setup.md)
34
34
 
35
- ### Android 12
35
+ ### **Android 12**
36
36
 
37
- To support Android 12, you will need to update `compileSdkVersion` in your `android/build.gradle` like this:
37
+ We start to support Android 12 from `v3.11.1`, and you will need to update `compileSdkVersion` to `31`, otherwise the build will fail:
38
38
 
39
39
  ```
40
40
  buildscript {
@@ -47,17 +47,15 @@ buildscript {
47
47
  }
48
48
  ```
49
49
 
50
- The reason for this is because Android puts new limitation on [PendingIntent](https://developer.android.com/reference/android/app/PendingIntent#FLAG_MUTABLE):
50
+ The reason for this is because Android puts new limitation on [PendingIntent](https://developer.android.com/reference/android/app/PendingIntent#FLAG_MUTABLE) which says `Starting with Build.VERSION_CODES.S, it will be required to explicitly specify the mutability of PendingIntents`
51
51
 
52
- > Starting with Build.VERSION_CODES.S, it will be required to explicitly specify the mutability of PendingIntents
52
+ > The original issue is [here](https://github.com/revtel/react-native-nfc-manager/issues/469)
53
53
 
54
- The original issue is [here](https://github.com/revtel/react-native-nfc-manager/issues/469)
54
+ BTW, if you don't care about **Android 12** for now, you can use **`v3.11.0`** as a short term solution.
55
55
 
56
- ## Also See
56
+ ### **[Demo App] NfcOpenReWriter**
57
57
 
58
- ### [Demo App] NfcOpenReWriter
59
-
60
- We have a full featured NFC utility app available for download.
58
+ We have a full featured NFC utility app using this library available for download.
61
59
 
62
60
  <a href='https://apps.apple.com/tw/app/nfc-rewriter/id1551243964' target='_blank'>
63
61
  <img alt="react-native-nfc-rewriter" src="./images/Apple-App-Store-Icon.png" width="250">
@@ -71,19 +69,73 @@ We have a full featured NFC utility app available for download.
71
69
 
72
70
  It also open sourced in this repo: [React Native NFC ReWriter App](https://github.com/revtel/react-native-nfc-rewriter)
73
71
 
74
- ## Basic Usage
72
+ ## Usage
75
73
 
76
- If all you want to do is to read `NDEF` data, you can use this example:
74
+ The simplest (and most common) use case for this library is to read `NFC` tags containing `NDEF`, which can be achieved via the following codes:
77
75
 
78
76
  ```javascript
79
- import NfcManager, {NfcEvents} from 'react-native-nfc-manager';
77
+ import React from 'react';
78
+ import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
79
+ import NfcManager, {NfcTech} from 'react-native-nfc-manager';
80
80
 
81
81
  // Pre-step, call this before any NFC operations
82
- async function initNfc() {
83
- await NfcManager.start();
82
+ NfcManager.start();
83
+
84
+ function App() {
85
+ async function readNdef() {
86
+ try {
87
+ // register for the NFC tag with NDEF in it
88
+ await NfcManager.requestTechnology(NfcTech.Ndef);
89
+ // the resolved tag object will contain `ndefMessage` property
90
+ const tag = await NfcManager.getTag();
91
+ console.warn('Tag found', tag);
92
+ } catch (ex) {
93
+ console.warn('Oops!', ex);
94
+ } finally {
95
+ // stop the nfc scanning
96
+ NfcManager.cancelTechnologyRequest();
97
+ }
98
+ }
99
+
100
+ return (
101
+ <View style={styles.wrapper}>
102
+ <TouchableOpacity onPress={readNdef}>
103
+ <Text>Scan a Tag</Text>
104
+ </TouchableOpacity>
105
+ </View>
106
+ );
84
107
  }
85
108
 
86
- function readNdef() {
109
+ const styles = StyleSheet.create({
110
+ wrapper: {
111
+ flex: 1,
112
+ justifyContent: 'center',
113
+ alignItems: 'center',
114
+ },
115
+ });
116
+
117
+ export default App;
118
+ ```
119
+
120
+ Pleaes notice when running above codes, iOS and Android has different behaviors:
121
+
122
+ - iOS will pop up a system scanning UI
123
+ - Android provides **NO** system scanning UI
124
+
125
+ Regarding the system scannning UI, both platforms should be able to scan your NFC tags succesfully and print out its content.
126
+
127
+ ### Old Style (registerTagEvent) To Scan NFC Tags
128
+
129
+ There's an alterntaive style to scan NFC tags through `NfcManager.registerTagEvent`, like this:
130
+
131
+ ```javascript
132
+ import NfcManager, {NfcTech} from 'react-native-nfc-manager';
133
+
134
+ // The following function resolves to a NFC Tag object using old event listener approach.
135
+ // You can call it like this:
136
+ // `const nfcTag = await listenToNfcEventOnce()`
137
+
138
+ function listenToNfcEventOnce() {
87
139
  const cleanUp = () => {
88
140
  NfcManager.setEventListener(NfcEvents.DiscoverTag, null);
89
141
  NfcManager.setEventListener(NfcEvents.SessionClosed, null);
@@ -95,8 +147,7 @@ function readNdef() {
95
147
  NfcManager.setEventListener(NfcEvents.DiscoverTag, (tag) => {
96
148
  tagFound = tag;
97
149
  resolve(tagFound);
98
- NfcManager.setAlertMessageIOS('NDEF tag found');
99
- NfcManager.unregisterTagEvent().catch(() => 0);
150
+ NfcManager.unregisterTagEvent();
100
151
  });
101
152
 
102
153
  NfcManager.setEventListener(NfcEvents.SessionClosed, () => {
@@ -111,120 +162,102 @@ function readNdef() {
111
162
  }
112
163
  ```
113
164
 
114
- Anything else, ex: write NDEF, send custom command, please read next section.
165
+ As you can see, the above approach is more verbose and hard-to-read, so we recommend using `NfcManager.requestTechnology` instead of `NfcManager.registerTagEvent` in your application.
166
+
167
+ ## Advanced Usage Concept
168
+
169
+ In higher level, there're 4 steps to use this library:
170
+
171
+ 1. request your particular NFC technologies through `NfcManager.requestTechnology`, for example:
172
+
173
+ - `Ndef`
174
+ - `NfcA`
175
+ - `NfcB` (Android-only)
176
+ - `NfcF` (Android-only)
177
+ - `NfcV` (Android-only)
178
+ - `IsoDep`
179
+ - `MifareClassic` (Android-only)
180
+ - `MifareUltralight` (Android-only)
181
+ - `MifareIOS` (ios-only)
182
+ - `Iso15693IOS` (ios-only)
183
+ - `FelicaIOS` (ios-only)
184
+
185
+ 2. select the proper NFC technology handler, which is implemented as getter in main `NfcManager` object, for example:
115
186
 
116
- ## Advanced Usage
187
+ - `ndefHandler` (for `Ndef` tech)
188
+ - `nfcAHandler` (for `NfcA` tech)
189
+ - `isoDepHandler` (for `IsoDep` tech)
190
+ - `iso15693HandlerIOS` (for `Iso15693IOS` tech)
191
+ - `mifareClassicHandlerAndroid` (for `mifareClassic` tech)
192
+ - `mifareUltralightHandlerAndroid` (for `mifareUltralight` tech)
193
+ - ... and so on
117
194
 
118
- In high level, there're 3 steps to perform advanced NFC operations:
195
+ 3. call specific methods on the NFC technology handler (for example `NfcManager.ndefHandler.writeNdefMessage`). To view all available methods for some tech handler, check out the [API List](index.d.ts)
119
196
 
120
- 1. request your specific NFC technology
121
- 2. select the proper NFC technology handler, which is implemented as getter in main `NfcManager` object, including:
122
- - ndefHandler
123
- - nfcAHandler
124
- - isoDepHandler
125
- - iso15693HandlerIOS
126
- - mifareClassicHandlerAndroid
127
- - mifareUltralightHandlerAndroid
128
- 3. call specific methods on the NFC technology handler
129
- 4. clean up your tech registration
197
+ 4. clean up your tech registration through `NfcManager.cancelTechnology`
198
+
199
+ ## Advanced Usage Example: NDEF-Writing
130
200
 
131
201
  For example, here's an example to write NDEF:
132
202
 
133
203
  ```javascript
134
204
  import NfcManager, {NfcTech, Ndef} from 'react-native-nfc-manager';
135
205
 
136
- // Pre-step, call this before any NFC operations
137
- async function initNfc() {
138
- await NfcManager.start();
139
- }
140
-
141
206
  async function writeNdef({type, value}) {
142
207
  let result = false;
143
208
 
144
209
  try {
145
- // Step 1
146
- await NfcManager.requestTechnology(NfcTech.Ndef, {
147
- alertMessage: 'Ready to write some NDEF',
148
- });
210
+ // STEP 1
211
+ await NfcManager.requestTechnology(NfcTech.Ndef);
149
212
 
150
213
  const bytes = Ndef.encodeMessage([Ndef.textRecord('Hello NFC')]);
151
214
 
152
215
  if (bytes) {
153
- await NfcManager.ndefHandler // Step2
154
- .writeNdefMessage(bytes); // Step3
155
-
156
- if (Platform.OS === 'ios') {
157
- await NfcManager.setAlertMessageIOS('Successfully write NDEF');
158
- }
216
+ await NfcManager.ndefHandler // STEP 2
217
+ .writeNdefMessage(bytes); // STEP 3
218
+ result = true;
159
219
  }
160
-
161
- result = true;
162
220
  } catch (ex) {
163
221
  console.warn(ex);
222
+ } finally {
223
+ // STEP 4
224
+ NfcManager.cancelTechnologyRequest();
164
225
  }
165
226
 
166
- // Step 4
167
- NfcManager.cancelTechnologyRequest().catch(() => 0);
168
227
  return result;
169
228
  }
170
229
  ```
171
230
 
172
- ## Advanced: Mifare Ultralight usage
231
+ ## Advanced Usage Example: Mifare Ultralight
173
232
 
174
- Here's an example to read a Mifare Ultralight tag:
233
+ Here's another example to read a Mifare Ultralight tag:
175
234
 
176
235
  ```javascript
177
- import NfcManager, {NfcTech} from 'react-native-nfc-manager';
178
-
179
- // Pre-step, call this before any NFC operations
180
- async function initNfc() {
181
- await NfcManager.start();
182
- }
183
-
184
236
  async function readMifare() {
237
+ let mifarePages = [];
238
+
185
239
  try {
186
- // 0. Request Mifare technology
240
+ // STEP 1
187
241
  let reqMifare = await NfcManager.requestTechnology(
188
242
  NfcTech.MifareUltralight,
189
243
  );
190
- if (reqMifare !== 'MifareUltralight') {
191
- throw new Error(
192
- '[NFC Read] [ERR] Mifare technology could not be requested',
193
- );
194
- }
195
-
196
- // 1. Get NFC Tag information
197
- const nfcTag = await NfcManager.getTag();
198
- console.log('[NFC Read] [INFO] Tag: ', nfcTag);
199
244
 
200
- // 2. Read pages
201
245
  const readLength = 60;
202
- let mifarePages = [];
203
246
  const mifarePagesRead = await Promise.all(
204
247
  [...Array(readLength).keys()].map(async (_, i) => {
205
- const pageOffset = i * 4; // 4 Pages are read at once, so offset should be in steps with length 4
206
- let pages = await NfcManager.mifareUltralightHandlerAndroid.mifareUltralightReadPages(
207
- pageOffset,
208
- );
248
+ const pages = await NfcManager.mifareUltralightHandlerAndroid // STEP 2
249
+ .mifareUltralightReadPages(i * 4); // STEP 3
209
250
  mifarePages.push(pages);
210
- console.log(`[NFC Read] [INFO] Mifare Page: ${pageOffset}`, pages);
211
- //await wait(500); // If Mifare Chip is to slow
212
251
  }),
213
252
  );
214
-
215
- // 3. Success
216
- console.log('[NFC Read] [INFO] Success reading Mifare');
217
-
218
- // 4. Cleanup
219
- _cleanup();
220
253
  } catch (ex) {
221
- console.warn('[NFC Read] [ERR] Failed Reading Mifare: ', ex);
222
- _cleanup();
254
+ console.warn(ex);
255
+ } finally {
256
+ // STEP 4
257
+ NfcManager.cancelTechnologyRequest();
223
258
  }
224
- }
225
259
 
226
- function _cleanup() {
227
- NfcManager.cancelTechnologyRequest().catch(() => 0);
260
+ return mifarePages;
228
261
  }
229
262
  ```
230
263
 
@@ -254,6 +287,8 @@ After installing this npm package, add the [config plugin](https://docs.expo.io/
254
287
 
255
288
  Next, rebuild your app as described in the ["Adding custom native code"](https://docs.expo.io/workflow/customizing/) guide.
256
289
 
290
+ > Notice: This Config Plugin will ensure the minimum Android SDK version is 31.
291
+
257
292
  #### Props
258
293
 
259
294
  The plugin provides props for extra customization. Every time you change the props or plugins, you'll need to rebuild (and `prebuild`) the native app. If no extra properties are added, defaults will be used.
@@ -280,4 +315,3 @@ The plugin provides props for extra customization. Every time you change the pro
280
315
  }
281
316
  }
282
317
  ```
283
-
@@ -266,6 +266,36 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
266
266
  }
267
267
  }
268
268
 
269
+ @ReactMethod
270
+ public void formatNdef(ReadableArray rnArray, ReadableMap options, Callback callback) {
271
+ boolean readOnly = options.getBoolean("readOnly");
272
+
273
+ synchronized(this) {
274
+ if (techRequest != null) {
275
+ try {
276
+ NdefFormatable ndef = (NdefFormatable)techRequest.getTechHandle();
277
+ if (ndef == null) {
278
+ callback.invoke(ERR_API_NOT_SUPPORT);
279
+ } else {
280
+ byte[] bytes = rnArrayToBytes(rnArray);
281
+ NdefMessage msg = new NdefMessage(bytes);
282
+ if (readOnly) {
283
+ ndef.formatReadOnly(msg);
284
+ } else {
285
+ ndef.format(msg);
286
+ }
287
+ callback.invoke();
288
+ }
289
+ } catch (Exception ex) {
290
+ Log.d(LOG_TAG, ex.toString());
291
+ callback.invoke(ex.toString());
292
+ }
293
+ } else {
294
+ callback.invoke(ERR_NO_TECH_REQ);
295
+ }
296
+ }
297
+ }
298
+
269
299
  private void mifareClassicAuthenticate(char type, int sector, ReadableArray key, Callback callback) {
270
300
  if (techRequest != null) {
271
301
  try {
@@ -987,6 +1017,16 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
987
1017
  callback.invoke(null, isForegroundEnabled);
988
1018
  }
989
1019
 
1020
+ @ReactMethod
1021
+ public void addListener(String eventName) {
1022
+ // Keep: Required for RN built in Event Emitter Calls.
1023
+ }
1024
+
1025
+ @ReactMethod
1026
+ public void removeListeners(Integer count) {
1027
+ // Keep: Required for RN built in Event Emitter Calls.
1028
+ }
1029
+
990
1030
  @Override
991
1031
  public void onHostResume() {
992
1032
  Log.d(LOG_TAG, "onResume");
@@ -11,6 +11,7 @@ import android.nfc.tech.NfcV;
11
11
  import android.nfc.tech.NfcF;
12
12
  import android.nfc.tech.MifareClassic;
13
13
  import android.nfc.tech.MifareUltralight;
14
+ import android.nfc.tech.NdefFormatable;
14
15
  import android.nfc.tech.IsoDep;
15
16
  import android.util.Log;
16
17
  import com.facebook.react.bridge.*;
@@ -76,6 +77,8 @@ class TagTechnologyRequest {
76
77
  mTech = MifareClassic.get(tag);
77
78
  } else if (techType.equals("MifareUltralight")) {
78
79
  mTech = MifareUltralight.get(tag);
80
+ } else if (techType.equals("NdefFormatable")) {
81
+ mTech = NdefFormatable.get(tag);
79
82
  }
80
83
 
81
84
  if (mTech == null) {
package/app.plugin.js CHANGED
@@ -85,6 +85,14 @@ function withNfc(config, props = {}) {
85
85
  config = withIosNfcEntitlement(config);
86
86
  config = withIosNfcSelectIdentifiers(config, {selectIdentifiers});
87
87
  config = withIosNfcSystemCodes(config, {systemCodes});
88
+
89
+ // We start to support Android 12 from v3.11.1, and you will need to update compileSdkVersion to 31,
90
+ // otherwise the build will fail:
91
+ config = AndroidConfig.Version.withBuildScriptExtMinimumVersion(config, {
92
+ name: 'compileSdkVersion',
93
+ minVersion: 31,
94
+ });
95
+
88
96
  if (nfcPermission !== false) {
89
97
  config = withIosPermission(config, props);
90
98
  config = AndroidConfig.Permissions.withPermissions(config, [
package/index.d.ts CHANGED
@@ -22,6 +22,7 @@ declare module 'react-native-nfc-manager' {
22
22
  MifareIOS = 'mifare',
23
23
  Iso15693IOS = 'iso15693',
24
24
  FelicaIOS = 'felica',
25
+ NdefFormatable = 'NdefFormatable',
25
26
  }
26
27
 
27
28
  export enum NdefStatus {
@@ -47,6 +48,17 @@ declare module 'react-native-nfc-manager' {
47
48
  Select = 1 << 4,
48
49
  Address = 1 << 5,
49
50
  Option = 1 << 6,
51
+ CommandSpecificBit8 = 1 << 7,
52
+ }
53
+
54
+ export enum Nfc15693ResponseFlagIOS {
55
+ Error = 1 << 0,
56
+ ResponseBufferValid = 1 << 1,
57
+ FinalResponse = 1 << 2,
58
+ ProtocolExtension = 1 << 3,
59
+ BlockSecurityStatusBit5 = 1 << 4,
60
+ BlockSecurityStatusBit6 = 1 << 5,
61
+ WaitTimeExtension = 1 << 6,
50
62
  }
51
63
 
52
64
  type TNF = 0x0 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07;
@@ -93,6 +105,10 @@ declare module 'react-native-nfc-manager' {
93
105
  transceive: (bytes: number[]) => Promise<number[]>;
94
106
  }
95
107
 
108
+ interface NfcVHandler {
109
+ transceive: (bytes: number[]) => Promise<number[]>;
110
+ }
111
+
96
112
  interface IsoDepHandler {
97
113
  transceive: (bytes: number[]) => Promise<number[]>;
98
114
  }
@@ -121,6 +137,10 @@ declare module 'react-native-nfc-manager' {
121
137
  ) => Promise<void>;
122
138
  }
123
139
 
140
+ interface NdefFormatableHandlerAndroid {
141
+ formatNdef: (bytes: number[], options?: { readOnly: boolean }) => Promise<void>;
142
+ }
143
+
124
144
  /** [iOS ONLY] */
125
145
  interface Iso15693HandlerIOS {
126
146
  getSystemInfo: (
@@ -159,6 +179,11 @@ declare module 'react-native-nfc-manager' {
159
179
  customCommandCode: number;
160
180
  customRequestParameters: number[];
161
181
  }) => Promise<number[]>;
182
+ sendRequest: (params: {
183
+ flags: number;
184
+ commandCode: number;
185
+ data: number[];
186
+ }) => Promise<[number, number[]]>;
162
187
  extendedReadSingleBlock: (params: {
163
188
  flags: number;
164
189
  blockNumber: number;
@@ -201,6 +226,7 @@ declare module 'react-native-nfc-manager' {
201
226
  */
202
227
  ndefHandler: NdefHandler;
203
228
  nfcAHandler: NfcAHandler;
229
+ nfcVHandler: NfcVHandler;
204
230
  isoDepHandler: IsoDepHandler;
205
231
 
206
232
  /**
@@ -236,6 +262,7 @@ declare module 'react-native-nfc-manager' {
236
262
  setTimeout(timeout: number): Promise<void>;
237
263
  mifareClassicHandlerAndroid: MifareClassicHandlerAndroid;
238
264
  mifareUltralightHandlerAndroid: MifareUltralightHandlerAndroid;
265
+ ndefFormatableHandlerAndroid: NdefFormatableHandlerAndroid;
239
266
  }
240
267
 
241
268
  const nfcManager: NfcManager;
package/ios/NfcManager.m CHANGED
@@ -1174,6 +1174,39 @@ RCT_EXPORT_METHOD(iso15693_customCommand:(NSDictionary *)options callback:(nonnu
1174
1174
  }
1175
1175
  }
1176
1176
 
1177
+ RCT_EXPORT_METHOD(iso15693_sendRequest:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
1178
+ {
1179
+ if (@available(iOS 14.0, *)) {
1180
+ if (!tagSession || !tagSession.connectedTag) {
1181
+ callback(@[@"Not connected", [NSNull null]]);
1182
+ return;
1183
+ }
1184
+
1185
+ id<NFCISO15693Tag> tag = [tagSession.connectedTag asNFCISO15693Tag];
1186
+ if (!tag) {
1187
+ callback(@[@"incorrect tag type", [NSNull null]]);
1188
+ return;
1189
+ }
1190
+
1191
+ NSInteger flags = [[options objectForKey:@"flags"] integerValue];
1192
+ NSInteger commandCode = [[options objectForKey:@"commandCode"] integerValue];
1193
+ NSData *data = [self arrayToData:[options mutableArrayValueForKey:@"data"]];
1194
+
1195
+ [tag sendRequestWithFlag:flags
1196
+ commandCode:commandCode
1197
+ data:data
1198
+ completionHandler:^(NFCISO15693ResponseFlag responseFlag, NSData *resp, NSError *error) {
1199
+ if (error) {
1200
+ callback(@[getErrorMessage(error), [NSNull null]]);
1201
+ return;
1202
+ }
1203
+ callback(@[[NSNull null], [NSNumber numberWithLong:responseFlag], [NfcManager dataToArray:resp]]);
1204
+ }];
1205
+ } else {
1206
+ callback(@[@"Not support in this device", [NSNull null]]);
1207
+ }
1208
+ }
1209
+
1177
1210
  RCT_EXPORT_METHOD(iso15693_extendedReadSingleBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
1178
1211
  {
1179
1212
  if (@available(iOS 13.0, *)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nfc-manager",
3
- "version": "3.11.3",
3
+ "version": "3.13.0",
4
4
  "description": "A NFC module for react native.",
5
5
  "main": "src/index.js",
6
6
  "repository": {
@@ -62,7 +62,7 @@
62
62
  "typescript": "^4.1.3"
63
63
  },
64
64
  "dependencies": {
65
- "@expo/config-plugins": "^3.0.6"
65
+ "@expo/config-plugins": "^4.0.16"
66
66
  },
67
67
  "scripts": {
68
68
  "lint": "eslint .",
package/src/NfcManager.js CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  } from './NativeNfcManager';
8
8
  import {NdefHandler, NdefStatus} from './NfcTech/NdefHandler';
9
9
  import {NfcAHandler} from './NfcTech/NfcAHandler';
10
+ import {NfcVHandler} from './NfcTech/NfcVHandler';
10
11
  import {IsoDepHandler} from './NfcTech/IsoDepHandler';
11
12
  import {
12
13
  handleNativeException,
@@ -33,6 +34,7 @@ const NfcTech = {
33
34
  MifareIOS: 'mifare',
34
35
  Iso15693IOS: 'iso15693',
35
36
  FelicaIOS: 'felica',
37
+ NdefFormatable: 'NdefFormatable',
36
38
  };
37
39
 
38
40
  const DEFAULT_REGISTER_TAG_EVENT_OPTIONS = {
@@ -124,6 +126,13 @@ class NfcManagerBase {
124
126
  return this._nfcAHandler;
125
127
  }
126
128
 
129
+ get nfcVHandler() {
130
+ if (!this._nfcVHandler) {
131
+ this._nfcVHandler = new NfcVHandler();
132
+ }
133
+ return this._nfcVHandler;
134
+ }
135
+
127
136
  get isoDepHandler() {
128
137
  if (!this._isoDepHandler) {
129
138
  this._isoDepHandler = new IsoDepHandler();
@@ -2,6 +2,7 @@ import {callNative} from './NativeNfcManager';
2
2
  import {NfcManagerBase} from './NfcManager';
3
3
  import {MifareClassicHandlerAndroid} from './NfcTech/MifareClassicHandlerAndroid';
4
4
  import {MifareUltralightHandlerAndroid} from './NfcTech/MifareUltralightHandlerAndroid';
5
+ import {NdefFormatableHandlerAndroid} from './NfcTech/NdefFormatableHandlerAndroid';
5
6
  import {handleNativeException, buildNfcExceptionAndroid} from './NfcError';
6
7
 
7
8
  const NfcAdapter = {
@@ -111,6 +112,16 @@ class NfcManagerAndroid extends NfcManagerBase {
111
112
  return this._mifareUltralightHandlerAndroid;
112
113
  }
113
114
 
115
+ // -------------------------------------
116
+ // (android) NfcTech.NdefFormatable API
117
+ // -------------------------------------
118
+ get ndefFormatableHandlerAndroid() {
119
+ if (!this._ndefFormatableHandlerAndroid) {
120
+ this._ndefFormatableHandlerAndroid = new NdefFormatableHandlerAndroid(this);
121
+ }
122
+ return this._ndefFormatableHandlerAndroid;
123
+ }
124
+
114
125
  // -------------------------------------
115
126
  // Android private
116
127
  // -------------------------------------
@@ -8,6 +8,7 @@ import {
8
8
  } from './NfcManager';
9
9
  import {
10
10
  Nfc15693RequestFlagIOS,
11
+ Nfc15693ResponseFlagIOS,
11
12
  Iso15693HandlerIOS,
12
13
  } from './NfcTech/Iso15693HandlerIOS';
13
14
  import {handleNativeException} from './NfcError';
@@ -30,6 +31,8 @@ class NfcManagerIOS extends NfcManagerBase {
30
31
  for (const t of tech) {
31
32
  if (t === NfcTech.NfcA) {
32
33
  techList.push(NfcTech.MifareIOS);
34
+ } else if (t === NfcTech.NfcV) {
35
+ techList.push(NfcTech.Iso15693IOS);
33
36
  } else {
34
37
  techList.push(t);
35
38
  }
@@ -145,4 +148,4 @@ class NfcManagerIOS extends NfcManagerBase {
145
148
  }
146
149
  }
147
150
 
148
- export {NfcManagerIOS, Nfc15693RequestFlagIOS};
151
+ export {NfcManagerIOS, Nfc15693RequestFlagIOS, Nfc15693ResponseFlagIOS};
@@ -8,6 +8,17 @@ const Nfc15693RequestFlagIOS = {
8
8
  Select: 1 << 4,
9
9
  Address: 1 << 5,
10
10
  Option: 1 << 6,
11
+ CommandSpecificBit8: 1 << 7,
12
+ };
13
+
14
+ const Nfc15693ResponseFlagIOS = {
15
+ Error: 1 << 0,
16
+ ResponseBufferValid: 1 << 1,
17
+ FinalResponse: 1 << 2,
18
+ ProtocolExtension: 1 << 3,
19
+ BlockSecurityStatusBit5: 1 << 4,
20
+ BlockSecurityStatusBit6: 1 << 5,
21
+ WaitTimeExtension: 1 << 6
11
22
  };
12
23
 
13
24
  class Iso15693HandlerIOS {
@@ -87,6 +98,15 @@ class Iso15693HandlerIOS {
87
98
  );
88
99
  }
89
100
 
101
+ // https://developer.apple.com/documentation/corenfc/nfciso15693tag/3551933-sendrequestwithflag?language=objc
102
+ sendRequest({flags, commandCode, data}) {
103
+ return handleNativeException(
104
+ callNative('iso15693_sendRequest', [
105
+ {flags, commandCode, data},
106
+ ]),
107
+ );
108
+ }
109
+
90
110
  extendedReadSingleBlock({flags, blockNumber}) {
91
111
  return handleNativeException(
92
112
  callNative('iso15693_extendedReadSingleBlock', [{flags, blockNumber}]),
@@ -108,4 +128,4 @@ class Iso15693HandlerIOS {
108
128
  }
109
129
  }
110
130
 
111
- export {Nfc15693RequestFlagIOS, Iso15693HandlerIOS};
131
+ export {Nfc15693RequestFlagIOS, Nfc15693ResponseFlagIOS, Iso15693HandlerIOS};
@@ -0,0 +1,16 @@
1
+ import {callNative} from '../NativeNfcManager';
2
+ import {handleNativeException} from '../NfcError';
3
+
4
+ class NdefFormatableHandlerAndroid {
5
+ async formatNdef(bytes, options={}) {
6
+ const defaultOptions = { readOnly: false };
7
+ return handleNativeException(
8
+ callNative('formatNdef', [
9
+ bytes,
10
+ {...defaultOptions, ...options}
11
+ ])
12
+ );
13
+ }
14
+ }
15
+
16
+ export {NdefFormatableHandlerAndroid};
@@ -0,0 +1,39 @@
1
+ import {Platform} from 'react-native';
2
+ import {callNative, NativeNfcManager} from '../NativeNfcManager';
3
+ import {handleNativeException} from '../NfcError';
4
+
5
+ class NfcVHandler {
6
+ async transceive(bytes) {
7
+ if (!Array.isArray(bytes)) {
8
+ throw new Error(
9
+ 'IsoDepHandler.transceive only takes input as a byte array',
10
+ );
11
+ }
12
+
13
+ if (Platform.OS === 'ios') {
14
+ const [flags, commandCode, ...data] = bytes;
15
+ return handleNativeException(
16
+ new Promise((resolve, reject) => {
17
+ NativeNfcManager.iso15693_sendRequest(
18
+ {
19
+ flags,
20
+ commandCode,
21
+ data,
22
+ },
23
+ (err, responseFlag, response) => {
24
+ if (err) {
25
+ reject(err);
26
+ } else {
27
+ resolve([responseFlag, ...response]);
28
+ }
29
+ },
30
+ );
31
+ }),
32
+ );
33
+ }
34
+
35
+ return handleNativeException(callNative('transceive', [bytes]));
36
+ }
37
+ }
38
+
39
+ export {NfcVHandler};
package/src/index.js CHANGED
@@ -4,6 +4,7 @@ import {NfcEvents, NfcTech, NdefStatus} from './NfcManager';
4
4
  import {NfcAdapter, NfcManagerAndroid} from './NfcManagerAndroid';
5
5
  import {
6
6
  Nfc15693RequestFlagIOS,
7
+ Nfc15693ResponseFlagIOS,
7
8
  NfcManagerIOS,
8
9
  } from './NfcManagerIOS';
9
10
  import * as NfcError from './NfcError';
@@ -26,6 +27,7 @@ export {
26
27
  NfcEvents,
27
28
  NfcAdapter,
28
29
  Nfc15693RequestFlagIOS,
30
+ Nfc15693ResponseFlagIOS,
29
31
  Ndef,
30
32
  NdefStatus,
31
33
  NfcError,