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 +122 -88
- package/android/src/main/java/community/revteltech/nfc/NfcManager.java +40 -0
- package/android/src/main/java/community/revteltech/nfc/TagTechnologyRequest.java +3 -0
- package/app.plugin.js +8 -0
- package/index.d.ts +27 -0
- package/ios/NfcManager.m +33 -0
- package/package.json +2 -2
- package/src/NfcManager.js +9 -0
- package/src/NfcManagerAndroid.js +11 -0
- package/src/NfcManagerIOS.js +4 -1
- package/src/NfcTech/Iso15693HandlerIOS.js +21 -1
- package/src/NfcTech/NdefFormatableHandlerAndroid.js +16 -0
- package/src/NfcTech/NfcVHandler.js +39 -0
- package/src/index.js +2 -0
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
|
-
|
|
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
|
-
>
|
|
52
|
+
> The original issue is [here](https://github.com/revtel/react-native-nfc-manager/issues/469)
|
|
53
53
|
|
|
54
|
-
|
|
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
|
-
|
|
56
|
+
### **[Demo App] NfcOpenReWriter**
|
|
57
57
|
|
|
58
|
-
|
|
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
|
-
##
|
|
72
|
+
## Usage
|
|
75
73
|
|
|
76
|
-
|
|
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
|
|
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
|
-
|
|
83
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
//
|
|
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 //
|
|
154
|
-
.writeNdefMessage(bytes); //
|
|
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
|
|
231
|
+
## Advanced Usage Example: Mifare Ultralight
|
|
173
232
|
|
|
174
|
-
Here's
|
|
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
|
-
//
|
|
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
|
|
206
|
-
|
|
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(
|
|
222
|
-
|
|
254
|
+
console.warn(ex);
|
|
255
|
+
} finally {
|
|
256
|
+
// STEP 4
|
|
257
|
+
NfcManager.cancelTechnologyRequest();
|
|
223
258
|
}
|
|
224
|
-
}
|
|
225
259
|
|
|
226
|
-
|
|
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.
|
|
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": "^
|
|
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();
|
package/src/NfcManagerAndroid.js
CHANGED
|
@@ -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
|
// -------------------------------------
|
package/src/NfcManagerIOS.js
CHANGED
|
@@ -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,
|