@spencerls/react-native-nfc 1.0.7 → 1.0.9

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
@@ -1,21 +1,45 @@
1
1
  # @spencerls/react-native-nfc
2
2
 
3
- A clean, React-friendly, cross-platform NFC layer built on top of
3
+ A clean, React-friendly, **cross-platform** NFC layer built on top of
4
4
  `react-native-nfc-manager`.
5
5
 
6
+ ## 🎯 Truly Cross-Platform
7
+
8
+ Write your NFC code once and it works on **both iOS and Android**.
9
+ The only platform-specific code is the optional Android reader mode configuration.
10
+ Everything else—reading, writing, and all NFC operations—uses the exact same API.
11
+
6
12
  This package provides:
7
13
 
8
14
  - A unified NFC service (`nfcService`)
9
- - High-level protocol namespaces (`nfc.v`, `nfc.a`, `nfc.ndef`)
15
+ - High-level protocol namespaces (`nfc.tag`, `nfc.v`, `nfc.ndef`)
16
+ - Low-level tag modules (`nfcTag`, `nfcVTag`, `nfcNdefTag`)
10
17
  - Automatic iOS reader restarts
11
18
  - Safe Android reader handling
12
19
  - Optional React hooks and provider
13
- - Technology sessions for NDEF/NfcV/NfcA and raw commands
20
+ - Technology sessions for NDEF/NfcV and raw commands
21
+ - Builder pattern for NDEF records
14
22
 
15
23
  The API is designed to be stable, predictable, and easy to use across iOS and Android.
16
24
 
17
25
  ---
18
26
 
27
+ ## Platform Support
28
+
29
+ | Feature | iOS | Android |
30
+ |---------|-----|---------|
31
+ | Reader Mode* | ❌ | ✅ |
32
+ | NDEF Read/Write | ✅ | ✅ |
33
+ | NFC-V (ISO15693) | ✅ | ✅ |
34
+ | Technology Sessions | ✅ | ✅ |
35
+ | React Hooks | ✅ | ✅ |
36
+
37
+ **\*Reader Mode** is Android's background NFC scanning API. iOS uses Technology Sessions instead.
38
+ **Platform-specific code:** Only `enableReaderMode_ANDROID()` is Android-specific (no-op on iOS).
39
+ All other APIs work identically on both platforms.
40
+
41
+ ---
42
+
19
43
  ## Installation
20
44
 
21
45
  ```bash
@@ -35,18 +59,23 @@ Works with:
35
59
  ## Basic Usage (Reader Mode)
36
60
 
37
61
  ```tsx
38
- import { useNfc, useNfcState } from "@spencerls/react-native-nfc";
62
+ import { useNfc, useNfcState, nfcService } from "@spencerls/react-native-nfc";
39
63
  import { NfcAdapter } from "react-native-nfc-manager";
40
64
 
41
65
  export default function ScannerScreen() {
42
66
  const { mode } = useNfcState();
43
67
 
68
+ // Platform-specific: Configure Android reader mode (no-op on iOS)
69
+ // Call once, typically at app startup or in useEffect
70
+ nfcService.enableReaderMode_ANDROID(
71
+ NfcAdapter.FLAG_READER_NFC_V |
72
+ NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS
73
+ );
74
+
75
+ // Cross-platform: Works identically on iOS and Android
44
76
  useNfc((tagId) => {
45
77
  console.log("Scanned:", tagId);
46
78
  }, {
47
- flags:
48
- NfcAdapter.FLAG_READER_NFC_V |
49
- NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,
50
79
  cooldownMs: 800
51
80
  });
52
81
 
@@ -63,19 +92,22 @@ export default function ScannerScreen() {
63
92
  ## Manual Reader Control
64
93
 
65
94
  ```tsx
66
- import { useNfcReader } from "@spencerls/react-native-nfc";
95
+ import { useNfcReader, nfcService } from "@spencerls/react-native-nfc";
67
96
  import { NfcAdapter } from "react-native-nfc-manager";
68
97
 
69
98
  export default function Screen() {
70
99
  const { start, stop } = useNfcReader();
71
100
 
101
+ // Platform-specific: Configure Android reader mode (no-op on iOS)
102
+ nfcService.enableReaderMode_ANDROID(NfcAdapter.FLAG_READER_NFC_V);
103
+
72
104
  const begin = () => {
105
+ // Cross-platform: Works identically on iOS and Android
73
106
  start(
74
- NfcAdapter.FLAG_READER_NFC_V,
75
107
  (tag) => {
76
108
  console.log("Tag:", tag.id);
77
109
  },
78
- 1200
110
+ { cooldownMs: 1200 }
79
111
  );
80
112
  };
81
113
 
@@ -85,70 +117,186 @@ export default function Screen() {
85
117
 
86
118
  ---
87
119
 
88
- ## Technology Sessions (NfcTech.*)
120
+ ## Get Basic Tag Information
89
121
 
90
- Always use `NfcTech` enums.
91
- Do not pass raw strings.
122
+ **Cross-platform:** Works identically on iOS and Android.
92
123
 
93
124
  ```tsx
94
125
  import { nfc } from "@spencerls/react-native-nfc";
95
- import { useNfcTechnology } from "@spencerls/react-native-nfc";
96
126
  import { NfcTech } from "react-native-nfc-manager";
97
127
 
98
- export function ReadSystemInfo() {
99
- const { runWithTech } = useNfcTechnology();
128
+ export default function ScanTagButton() {
129
+ const scanTag = async () => {
130
+ const tag = await nfc.tag.getTag([
131
+ NfcTech.NfcA,
132
+ NfcTech.NfcV,
133
+ NfcTech.Ndef,
134
+ ]);
135
+ console.log("Tag ID:", tag.id);
136
+ console.log("Tag Type:", tag.type);
137
+ };
100
138
 
101
- const readInfo = async () => {
102
- await runWithTech([NfcTech.NfcV], async () => {
103
- const info = await nfc.v.getSystemInfoNfcV();
104
- console.log(info);
105
- });
139
+ return <Button title="Scan Tag" onPress={scanTag} />;
140
+ }
141
+ ```
142
+
143
+ ---
144
+
145
+ ## NDEF Write with Builder
146
+
147
+ **Cross-platform:** Works identically on iOS and Android.
148
+
149
+ ```tsx
150
+ import { nfc } from "@spencerls/react-native-nfc";
151
+
152
+ export default function WriteNdefButton() {
153
+ const writeNdef = async () => {
154
+ await nfc.ndef.write(
155
+ nfc.ndef.Builder.records((B) => [
156
+ B.textRecord("Hello, world!"),
157
+ B.uriRecord("https://www.google.com"),
158
+ B.jsonRecord(
159
+ JSON.stringify({
160
+ name: "John Doe",
161
+ age: 30,
162
+ email: "john.doe@example.com",
163
+ })
164
+ ),
165
+ ])
166
+ );
167
+ };
168
+
169
+ return <Button title="Write NDEF" onPress={writeNdef} />;
170
+ }
171
+ ```
172
+
173
+ ---
174
+
175
+ ## NDEF Read
176
+
177
+ **Cross-platform:** Works identically on iOS and Android.
178
+
179
+ ```tsx
180
+ import { nfc } from "@spencerls/react-native-nfc";
181
+
182
+ export default function ReadNdefButton() {
183
+ const readNdef = async () => {
184
+ const { message, tag } = await nfc.ndef.readFull();
185
+ console.log("Tag ID:", tag.id);
186
+ console.log("Records:", message.ndefMessage);
106
187
  };
107
188
 
108
- return <Button title="Read NFC-V Info" onPress={readInfo} />;
189
+ return <Button title="Read NDEF" onPress={readNdef} />;
109
190
  }
110
191
  ```
111
192
 
112
193
  ---
113
194
 
114
- ## NDEF Read/Write
195
+ ## Custom NFC-V Operations
196
+
197
+ **Cross-platform:** Works identically on iOS and Android.
115
198
 
116
199
  ```tsx
117
- import { useNfcTechnology } from "@spencerls/react-native-nfc";
118
- import { NfcTech, Ndef, NfcManager } from "react-native-nfc-manager";
119
-
120
- export default function WriteScreen() {
121
- const { runWithTech } = useNfcTechnology();
122
-
123
- const writeHello = async () => {
124
- await runWithTech([NfcTech.Ndef], async () => {
125
- const bytes = Ndef.encodeMessage([
126
- Ndef.textRecord("Hello NFC!")
127
- ]);
128
- await NfcManager.ndefHandler.writeNdefMessage(bytes);
200
+ import { nfc, nfcTag, nfcVTag } from "@spencerls/react-native-nfc";
201
+
202
+ export default function ReadNfcVButton() {
203
+ const readCustom = async () => {
204
+ const data = await nfc.service.withTechnology(nfcVTag.tech, async () => {
205
+ const tag = await nfcTag.getTag();
206
+ if (!tag?.id) throw new Error("No NFC-V tag detected");
207
+
208
+ const buffer = new Uint8Array();
209
+ let offset = 0;
210
+
211
+ // Read blocks 0, 2, 4, 6
212
+ for (let i = 0; i < 8; i += 2) {
213
+ const block = await nfcVTag.readBlock(tag.id, i);
214
+ buffer.set(block, offset);
215
+ offset += block.length;
216
+ }
217
+
218
+ return buffer;
129
219
  });
220
+
221
+ console.log("Data:", data);
130
222
  };
131
223
 
132
- return <Button title="Write NDEF" onPress={writeHello} />;
224
+ return <Button title="Read NFC-V" onPress={readCustom} />;
133
225
  }
134
226
  ```
135
227
 
136
228
  ---
137
229
 
138
- ## Namespace API
230
+ ## High-Level NFC-V Operations
139
231
 
140
- ```ts
232
+ **Cross-platform:** Works identically on iOS and Android.
233
+
234
+ ```tsx
141
235
  import { nfc } from "@spencerls/react-native-nfc";
142
236
 
143
- await nfc.v.getSystemInfoNfcV();
144
- await nfc.v.readSingleBlock(uid, 0);
237
+ export default function NfcVScreen() {
238
+ const readBlock = async () => {
239
+ const data = await nfc.v.readBlock(0);
240
+ console.log("Block 0:", data);
241
+ };
145
242
 
146
- await nfc.a.transceive(rawBytes);
243
+ const writeBlock = async () => {
244
+ const data = new Uint8Array([0x01, 0x02, 0x03, 0x04]);
245
+ await nfc.v.writeBlock(0, data);
246
+ };
147
247
 
148
- await nfc.ndef.parse(ndefBytes);
248
+ const getInfo = async () => {
249
+ const info = await nfc.v.getSystemInfo();
250
+ console.log("System Info:", info);
251
+ };
149
252
 
150
- nfc.service.startReader(...);
151
- nfc.service.withTechnology(...);
253
+ return (
254
+ <View>
255
+ <Button title="Read Block" onPress={readBlock} />
256
+ <Button title="Write Block" onPress={writeBlock} />
257
+ <Button title="Get Info" onPress={getInfo} />
258
+ </View>
259
+ );
260
+ }
261
+ ```
262
+
263
+ ---
264
+
265
+ ## API Overview
266
+
267
+ **Cross-platform:** All APIs below work identically on iOS and Android.
268
+
269
+ ```ts
270
+ import { nfc, nfcTag, nfcVTag, nfcNdefTag } from "@spencerls/react-native-nfc";
271
+
272
+ // High-level namespace operations (auto-manages technology sessions)
273
+ await nfc.tag.getTag([NfcTech.NfcV]);
274
+ await nfc.v.readBlock(0);
275
+ await nfc.v.writeBlock(0, data);
276
+ await nfc.v.getSystemInfo();
277
+ await nfc.ndef.write(records);
278
+ await nfc.ndef.readMessage();
279
+ await nfc.ndef.readFull();
280
+
281
+ // Low-level tag modules (use inside withTechnology)
282
+ await nfc.service.withTechnology(nfcVTag.tech, async () => {
283
+ const tag = await nfcTag.getTag();
284
+ const block = await nfcVTag.readBlock(tag.id, 0);
285
+ });
286
+
287
+ // NDEF Builder
288
+ const records = nfc.ndef.Builder.records((B) => [
289
+ B.textRecord("Hello"),
290
+ B.uriRecord("https://example.com"),
291
+ B.jsonRecord(JSON.stringify({ key: "value" })),
292
+ B.mimeRecord("text/plain", "data"),
293
+ B.externalRecord("example.com", "type", "payload"),
294
+ ]);
295
+
296
+ // Service control
297
+ nfc.service.enableReaderMode_ANDROID(flags); // Android-only (no-op on iOS)
298
+ await nfc.service.startReader(onTag, options); // Cross-platform
299
+ await nfc.service.stopReader(); // Cross-platform
152
300
  ```
153
301
 
154
302
  ---