community-cordova-plugin-nfc 1.7.1 → 1.8.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/CHANGELOG.md CHANGED
@@ -3,6 +3,104 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.8.0](https://github.com/EYALIN/community-cordova-plugin-nfc/compare/v1.7.1...v1.8.0) (unreleased)
7
+
8
+ ### Fixes
9
+
10
+ * **Android: no more crashes from a stale or pulled tag.** Every background path (`makeReadOnly`, `connect`, `close`, `transceive`, the listener dispatch and the reader-mode callback) now reports an error instead of letting `SecurityException: Tag … is out of date`, `IllegalStateException` or an NPE kill the app.
11
+ * **Android: connections are always closed**, so a write after a failed write or after `makeReadOnly` no longer fails with "Close other technology first!", and `connect()` never silently reuses the previous tag's technology.
12
+ * **Android: errors have a code and a real message.** `transceive` / `connect` failures used to reach JS as `null`; they now say `TAG_LOST`, `IO_ERROR`, `NOT_CONNECTED`, … (see *Errors* in the README).
13
+ * **Android reader mode can write**: `write`, `erase` and `makeReadOnly` work on tags delivered by `readerMode`, and the newest tag always wins.
14
+ * **Android no longer captures every tag while no listener is registered** (behaviour introduced in 1.5.4 without a changelog entry: `enableForegroundDispatch(null, null)`), so a URL tag opens the browser again; deep-link / MAIN launch intents are no longer cleared.
15
+ * **NTAG helpers**: memory maps per IC from `GET_VERSION` (NTAG210/212/213/215/216, Ultralight EV1; NTAG I2C is no longer reported as NTAG216); `readMemoryPages` returns exactly the requested pages (in 1.5.x-1.7.1 every Android dump failed with a `RangeError`); `getPasswordProtectionStatus()` reads the right configuration page and computes write/read protection; `fullMemoryDump` reports read errors instead of relabelling the tag as "MIFARE Ultralight"; `transceive(Uint8Array)` sends only the view's bytes.
16
+ * **iOS: `keepSessionOpen: false` is honoured** (it was read as `true`), callbacks from a cancelled or replaced session can no longer reject the next scan, and a scan started right after `cancelScan` waits for the previous session to end.
17
+ * **iOS errors carry a code** (`200` user cancelled, `201` timeout, … see `nfc.IOS_ERROR`) next to the message.
18
+ * **iOS returns more tag data**: `maxSize` (NDEF capacity), MIFARE family, optional FeliCa polling (`scanTag({pollFeliCa: true})`), and record ids survive writes.
19
+ * **iOS: `NFCReaderUsageDescription` is written on cordova-ios 7 and older again** (1.5.3-1.7.1 only targeted cordova-ios 8's `App/App-Info.plist`).
20
+ * **iOS scan-sheet texts can be localized**: the keys are documented in the README.
21
+ * **Typings match the runtime**: `remove*Listener(callback, …)`, `readerMode`, `FLAG_*`, `isType(record, tnf, type)`, `connect()` result; `ndef.decodeTextRecord` / `decodeUriRecord` now exist.
22
+
23
+ ### Features
24
+
25
+ * `nfc.useErrorObjects(true)`: failure callbacks and rejections receive `NfcError {code, message}` objects. Off by default - the message strings are unchanged.
26
+ * Callback APIs (`write`, `erase`, `makeReadOnly`, `enabled`, `showSettings`, the `add*/remove*Listener`s, …) also return a Promise when called without callbacks.
27
+ * NTAG password: `ntagAuthenticate`, `ntagSetPassword`, `ntagRemovePassword` (Android).
28
+ * NXP originality signature: `verifyNtagSignature`, `checkNtagOriginality`.
29
+ * ISO 15693: `nfcvGetSystemInfo`, `nfcvReadBlocks` (Android).
30
+ * MIFARE Classic: `mifareClassicAuthenticate`, `mifareClassicReadBlock`, `mifareClassicInfo` (Android).
31
+ * NFC on/off events: `addStateChangeListener` / `removeStateChangeListener` (Android).
32
+ * `readerMode(flags, onTag, onError, { presenceCheckDelay })` (Android).
33
+ * `showSettings()` opens the NFC settings panel on Android 10+.
34
+ * Background tag reading on Android: plugin variable `NFC_INTENT_FILTERS` (`ndef`, `tech`, `tag`) + `NFC_NDEF_MIME_TYPES`; the tag that launched the app reaches the first matching listener. README section on iOS background reading via Universal Links.
35
+
36
+ ### Behaviour changes
37
+
38
+ * Android Beam (`share`, `unshare`, `handover`, `stopHandover`) now fails with `NOT_SUPPORTED`; since 1.4.0 it silently reported success without doing anything (Beam was removed in Android 10).
39
+ * `write`, `erase` and `makeReadOnly` close an open `connect()` session on the same tag first (Android allows one connected technology per tag).
40
+ * Removed the dead `multiCallbackTest` function and the Windows Phone 8, Windows and BlackBerry 10 platforms (and their sources).
41
+
42
+ ### Tooling
43
+
44
+ * `npm test`: eslint 9, `tsc` type-test of the typings, Node unit tests (runtime/typings parity, NTAG helpers against a byte-accurate tag model, launch-tag replay, intent-filter hook), a JVM harness for `NfcPlugin.java` (`tests/android/run.sh`) and an iPhoneOS SDK compile of `NfcPlugin.m` (`npm run test:ios`, macOS). GitHub Actions workflow in `.github/workflows/ci.yml`.
45
+
46
+ ---
47
+
48
+ ## [1.7.1](https://github.com/EYALIN/community-cordova-plugin-nfc/compare/v1.7.0...v1.7.1) (2026-08-13)
49
+
50
+ ### Fixes
51
+
52
+ * Android: catch-all error handling in `writeNdefMessage` and `startNfc`, so a stale-tag `SecurityException` or a null `IntentFilter` no longer crashes the app.
53
+
54
+ ## [1.7.0](https://github.com/EYALIN/community-cordova-plugin-nfc/compare/v1.6.2...v1.7.0) (2026-05-31)
55
+
56
+ ### Features
57
+
58
+ * iOS `nfc.transceive` for ISO 7816 tags (after `scanTag({keepSessionOpen: true})`), resolving with the response data plus SW1/SW2 like Android's IsoDep ([#6](https://github.com/EYALIN/community-cordova-plugin-nfc/issues/6)).
59
+
60
+ ## [1.6.2](https://github.com/EYALIN/community-cordova-plugin-nfc/compare/v1.6.1...v1.6.2) (2026-05-25)
61
+
62
+ ### Fixes
63
+
64
+ * Removed an invalid `cordova >100` engine constraint from `package.json` ([#11](https://github.com/EYALIN/community-cordova-plugin-nfc/issues/11)).
65
+
66
+ ## 1.6.1 (2026-05-23)
67
+
68
+ ### Fixes
69
+
70
+ * Restored the `window.nfc`, `window.ndef` and `window.util` legacy globals next to the `NfcPlugin` export ([#11](https://github.com/EYALIN/community-cordova-plugin-nfc/issues/11)).
71
+
72
+ ## 1.6.0 (2026-01-23)
73
+
74
+ ### Changes
75
+
76
+ * The JS module is exported as `NfcPlugin` (`<clobbers target="NfcPlugin" />`), with `NfcPlugin.NdefPlugin` (ndef helpers) and `NfcPlugin.NfcUtil` (util); typings updated.
77
+
78
+ ## 1.5.5 (2026-01-20)
79
+
80
+ ### Fixes
81
+
82
+ * iOS: removed the deprecated `NDEF` reader-session format from the entitlements (only `TAG`), fixing App Store validation with the iOS 26.1 SDK.
83
+
84
+ ## 1.5.4 (2026-01-20)
85
+
86
+ ### Fixes
87
+
88
+ * Android: handle `SecurityException` for stale tag references when writing and in `Util.ndefToJSON`; validate intent filters before `enableForegroundDispatch`.
89
+
90
+ ### Behaviour change (not announced at the time)
91
+
92
+ * With no listener registered, foreground dispatch was enabled with `null` filters, so the app captured every tag while in the foreground. Reverted in 1.8.0.
93
+
94
+ ## 1.5.3 (2026-01-19)
95
+
96
+ ### Changes
97
+
98
+ * iOS: `NFCReaderUsageDescription` was targeted at `App/App-Info.plist` (cordova-ios 8 layout only). Reverted in 1.8.0.
99
+
100
+ ## 1.5.2 (2026-01-17)
101
+
102
+ * First npm release of the 1.5 line (the advanced tag analysis methods and typings listed under 1.5.0 below; 1.5.0 and 1.5.1 were not published).
103
+
6
104
  ## [1.5.0](https://github.com/EYALIN/community-cordova-plugin-nfc/compare/v1.4.0...v1.5.0) (2026-01-17)
7
105
 
8
106
  ### Features
@@ -41,6 +139,10 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
41
139
 
42
140
  ---
43
141
 
142
+ ## 1.3.0 (2023-05-29)
143
+
144
+ * First release as `community-cordova-plugin-nfc` (forked from `phonegap-nfc` 1.2.x): package / plugin id, repository and funding links; iOS header import fix.
145
+
44
146
  ## Previous Versions
45
147
 
46
148
  See the [original phonegap-nfc changelog](https://github.com/chariotsolutions/phonegap-nfc) for earlier version history.
package/README.md CHANGED
@@ -20,7 +20,14 @@ or if you're asking for new features or priority bug fixes. Thank you!
20
20
  - **Advanced Tag Analysis** (v1.5.0+) - Read raw memory, get NTAG version, counter, signature
21
21
  - **TypeScript Support** - Full TypeScript definitions included
22
22
 
23
- ## What's New in v1.5.0
23
+ ## What's New in 1.8.0
24
+
25
+ Crash and connection fixes on Android, coded errors on both platforms, correct NTAG helpers, iOS
26
+ session and localization fixes, and new capabilities: NTAG password protection, NXP originality
27
+ signature verification, ISO 15693 and MIFARE Classic helpers, NFC on/off events and background tag
28
+ reading on Android. See the [CHANGELOG](CHANGELOG.md) for the full list and the behaviour changes.
29
+
30
+ ## What's New in v1.5.0 (advanced tag analysis)
24
31
 
25
32
  ### Advanced Tag Analysis Methods
26
33
 
@@ -40,7 +47,8 @@ New methods for premium NFC tag analysis:
40
47
  - ✅ Android (API 16+)
41
48
  - ✅ iOS 11+ (CoreNFC)
42
49
 
43
- > Note: Legacy platforms (Windows, BlackBerry) are no longer actively maintained but may still work.
50
+ > Windows Phone 8, Windows and BlackBerry 10 were removed in 1.8.0. Android Beam (`share`, `handover`) no
51
+ > longer exists on Android 10+ and fails with `NOT_SUPPORTED`.
44
52
 
45
53
  ## Contents
46
54
 
@@ -237,6 +245,72 @@ await nfc.close();
237
245
 
238
246
  ---
239
247
 
248
+ ## Password protection, originality, ISO 15693, MIFARE Classic (1.8.0)
249
+
250
+ All Android-only (iOS can only transceive ISO 7816 APDUs), after `nfc.connect(tech)` on a scanned tag.
251
+ Bytes can be given as a hex string, a byte array or a `Uint8Array`.
252
+
253
+ ```js
254
+ await nfc.connect('android.nfc.tech.NfcA');
255
+
256
+ // NTAG21x / Ultralight EV1 password (PWD_AUTH 0x1B). AUTH0 is written last, so protection starts only
257
+ // once the password is in place; the other configuration bits are preserved.
258
+ await nfc.ntagSetPassword('12345678', { pack: 'ABCD', startPage: 4, protectReads: false, authLimit: 0 });
259
+ const { pack, packMatches } = await nfc.ntagAuthenticate('12345678', 'ABCD'); // AUTH_FAILED on a wrong password
260
+ await nfc.ntagRemovePassword('12345678');
261
+ const status = await nfc.getPasswordProtectionStatus(); // AUTH0 / PROT for this IC
262
+
263
+ // NXP originality signature: ECDSA on secp128r1 over the raw UID (NXP AN11350 / AN11341),
264
+ // verified against NXP's NTAG21x and MIFARE Ultralight EV1 public keys. Needs BigInt.
265
+ const { valid, keyName, uid } = await nfc.checkNtagOriginality();
266
+ nfc.verifyNtagSignature(uid, signatureBytes); // synchronous
267
+
268
+ // ISO 15693 (NfcV)
269
+ await nfc.connect('android.nfc.tech.NfcV');
270
+ const info = await nfc.nfcvGetSystemInfo(); // uid, dsfid, afi, blockCount, blockSize, icReference
271
+ const blocks = await nfc.nfcvReadBlocks(0, info.blockCount, info.uid);
272
+
273
+ // MIFARE Classic (phones with an NXP NFC controller)
274
+ await nfc.connect('android.nfc.tech.MifareClassic');
275
+ await nfc.mifareClassicAuthenticate(1, 'FFFFFFFFFFFF', 'A');
276
+ const block4 = await nfc.mifareClassicReadBlock(4); // ArrayBuffer, 16 bytes
277
+
278
+ // reader mode: time between presence checks
279
+ nfc.readerMode(nfc.FLAG_READER_NFC_A, onTag, onError, { presenceCheckDelay: 250 });
280
+
281
+ // NFC switched on/off (also while it is off), current state first
282
+ nfc.addStateChangeListener(({ state, enabled }) => console.log(state, enabled));
283
+ nfc.removeStateChangeListener();
284
+
285
+ // Android 10+: opens the NFC settings panel over the app (falls back to the settings screen)
286
+ nfc.showSettings();
287
+ ```
288
+
289
+ A password is sent in plain text over the air and the originality signature can be copied to a clone,
290
+ so treat both as deterrents, not strong security (see NXP AN13089).
291
+
292
+ ## Errors (1.8.0)
293
+
294
+ Native errors carry a code. By default failure callbacks and rejections still receive the message string
295
+ (as in 1.7.x); call `nfc.useErrorObjects(true)` once to receive `NfcError` objects instead:
296
+
297
+ ```js
298
+ nfc.useErrorObjects(true);
299
+ try {
300
+ await nfc.transceive('3000');
301
+ } catch (e) {
302
+ if (e.code === 'TAG_LOST') { /* ask the user to hold the tag still */ }
303
+ if (e.code === nfc.IOS_ERROR.USER_CANCELED) { /* iOS sheet cancelled */ }
304
+ }
305
+ ```
306
+
307
+ Android codes: `TAG_LOST`, `TAG_STALE`, `IO_ERROR`, `FORMAT_ERROR`, `ILLEGAL_STATE`, `NO_TAG`, `NOT_CONNECTED`,
308
+ `UNSUPPORTED_TECH`, `READ_ONLY`, `CAPACITY_EXCEEDED`, `NOT_NDEF`, `INVALID_ARGUMENT`, `NOT_SUPPORTED`,
309
+ `AUTH_FAILED`, `NO_NFC`, `NFC_DISABLED`, `UNKNOWN`. iOS reader-session errors carry the numeric
310
+ `NFCReaderError` code (`nfc.IOS_ERROR`), plugin-level iOS errors the same string codes as Android.
311
+
312
+ ---
313
+
240
314
  ## iOS Notes
241
315
 
242
316
  Reading NFC NDEF tags is supported on iPhone 7 (and newer) since iOS 11. iOS 13 added support for writing NDEF messages to NFC tags. iOS 13 also adds the ability to get the UID from some NFC tags. On iOS, the user must start a NFC session to scan for a tag. This is different from Android which can constantly scan for NFC tags. The [nfc.scanNdef](#nfcscanndef) and [nfc.scanTag](#nfcscantag) functions start a NFC scanning session. The NFC tag is returned to the caller via a Promise. If your existing code uses the deprecated [nfc.beginSession](#nfcbeginsession), update it to use `nfc.scanNdef`.
@@ -247,6 +321,38 @@ You must call [nfc.scanNdef](#nfcscanndef) and [nfc.scanTag](#nfcscantag) before
247
321
 
248
322
  Writing NFC tags on iOS uses the same [nfc.write](#nfcwrite) function as other platforms. Although it's the same function, the behavior is different on iOS. Calling `nfc.write` on an iOS device will start a new scanning session and write data to the scanned tag.
249
323
 
324
+ ### Localizing the iOS NFC sheet
325
+
326
+ The texts the plugin shows on the iOS scan sheet (and the `message` of the matching errors) are looked
327
+ up in the app's `Localizable.strings` first and fall back to English. To translate them, add these keys
328
+ to `<language>.lproj/Localizable.strings` in the iOS app (for example with a Cordova `resource-file`
329
+ or a hook):
330
+
331
+ | Key | English default | Shown when |
332
+ |-----|-----------------|------------|
333
+ | `NFCHoldNearTag` | Hold near NFC tag to scan. | `scanNdef` / `scanTag` starts |
334
+ | `NFCHoldNearWritableTag` | Hold near writable NFC tag to update. | `write` starts a session |
335
+ | `NFCTagRead` | Tag successfully read. | a tag was read |
336
+ | `NFCDataWrote` | Wrote data to NFC tag. | a write succeeded |
337
+ | `NFCMoreThanOneTag` | More than 1 tag detected. Please remove all tags and try again. | several tags in the field |
338
+ | `NFCErrorTagConnection` | Error connecting to tag. | connecting to the tag failed |
339
+ | `NFCErrorTagStatus` | Error getting tag status. | reading the NDEF status failed |
340
+ | `NFCDataReadFailed` | Read Failed. | reading the NDEF message failed |
341
+ | `NFCNotNdefCompliant` | Tag is not NDEF compliant. | writing to a non-NDEF tag |
342
+ | `NFCReadOnlyTag` | Tag is read only. | writing to a locked tag |
343
+ | `NFCDataWriteFailed` | Write failed. | the write failed |
344
+ | `NFCUnknownNdefTag` | Unknown NDEF tag status. | unexpected NDEF status |
345
+
346
+ Example `he.lproj/Localizable.strings`:
347
+
348
+ ```
349
+ "NFCHoldNearTag" = "קרבו את המכשיר לתג NFC כדי לסרוק.";
350
+ "NFCTagRead" = "התג נקרא בהצלחה.";
351
+ ```
352
+
353
+ Once the error texts are translated, match errors on their `code` (see `nfc.useErrorObjects`), not on the
354
+ English message.
355
+
250
356
  # NFC
251
357
 
252
358
  > The nfc object provides access to the device's NFC sensor.
@@ -302,7 +408,6 @@ Function `nfc.addNdefListener` registers the callback for ndef events.
302
408
 
303
409
  A ndef event is fired when a NDEF tag is read.
304
410
 
305
- For BlackBerry 10, you must configure the type of tags your application will read with an [invoke-target in config.xml](#blackberry-10-invoke-target).
306
411
 
307
412
  On Android registered [mimeTypeListeners](#nfcaddmimetypelistener) takes precedence over this more generic NDEF listener.
308
413
 
@@ -312,11 +417,6 @@ On iOS you must call [beingSession](#nfcbeginsession) before scanning a tag.
312
417
 
313
418
  - Android
314
419
  - iOS
315
- - Windows
316
- - BlackBerry 7
317
- - BlackBerry 10
318
- - Windows Phone 8
319
-
320
420
  ## nfc.removeNdefListener
321
421
 
322
422
  Removes the previously registered event listener for NDEF tags added via `nfc.addNdefListener`.
@@ -335,9 +435,6 @@ Removing listeners is not recommended. Instead, consider that your callback can
335
435
 
336
436
  - Android
337
437
  - iOS
338
- - Windows
339
- - BlackBerry 7
340
-
341
438
  ## nfc.addTagDiscoveredListener
342
439
 
343
440
  Registers an event listener for tags matching any tag type.
@@ -359,10 +456,6 @@ This event occurs when any tag is detected by the phone.
359
456
  ### Supported Platforms
360
457
 
361
458
  - Android
362
- - Windows
363
- - BlackBerry 7
364
-
365
- Note that Windows Phones need the newere NXP PN427 chipset to read non-NDEF tags. That tag will be read, but no tag meta-data is available.
366
459
 
367
460
  ## nfc.removeTagDiscoveredListener
368
461
 
@@ -381,9 +474,6 @@ Removing listeners is not recommended. Instead, consider that your callback can
381
474
  ### Supported Platforms
382
475
 
383
476
  - Android
384
- - Windows
385
- - BlackBerry 7
386
-
387
477
  ## nfc.addMimeTypeListener
388
478
 
389
479
  Registers an event listener for NDEF tags matching a specified MIME type.
@@ -413,8 +503,6 @@ On Android, MIME types for filtering should always be lower case. (See [IntentFi
413
503
  ### Supported Platforms
414
504
 
415
505
  - Android
416
- - BlackBerry 7
417
-
418
506
  ## nfc.removeMimeTypeListener
419
507
 
420
508
  Removes the previously registered event listener added via `nfc.addMimeTypeListener`.
@@ -433,8 +521,6 @@ Removing listeners is not recommended. Instead, consider that your callback can
433
521
  ### Supported Platforms
434
522
 
435
523
  - Android
436
- - BlackBerry 7
437
-
438
524
  ## nfc.addNdefFormatableListener
439
525
 
440
526
  Registers an event listener for formatable NDEF tags.
@@ -484,9 +570,7 @@ On **Android** this method *must* be called from within an NDEF Event Handler.
484
570
 
485
571
  On **iOS** this method can be called outside the NDEF Event Handler, it will start a new scanning session. Optionally you can reuse the read session to write data. See example below.
486
572
 
487
- On **Windows** this method *may* be called from within the NDEF Event Handler.
488
573
 
489
- On **Windows Phone 8.1** this method should be called outside the NDEF Event Handler, otherwise Windows tries to read the tag contents as you are writing to the tag.
490
574
 
491
575
  ### Examples
492
576
 
@@ -554,10 +638,6 @@ On iOS you can optionally write to NFC tag using the read session
554
638
 
555
639
  - Android
556
640
  - iOS
557
- - Windows
558
- - BlackBerry 7
559
- - Windows Phone 8
560
-
561
641
  ## nfc.makeReadOnly
562
642
 
563
643
  Makes a NFC tag read only. **Warning this is permanent.**
@@ -628,16 +708,9 @@ Function `nfc.share` writes an NdefMessage via peer-to-peer. This should appear
628
708
  ### Supported Platforms
629
709
 
630
710
  - Android
631
- - Windows
632
- - BlackBerry 7
633
- - BlackBerry 10
634
- - Windows Phone 8
635
-
636
711
  ### Platform differences
637
712
 
638
- Android - shares message until unshare is called
639
- Blackberry 10 - shares the message one time or until unshare is called
640
- Windows Phone 8 - must be called from within a NFC event handler like nfc.write
713
+ Android Beam was removed in Android 10; since 1.8.0 this fails with NOT_SUPPORTED.
641
714
 
642
715
  ## nfc.unshare
643
716
 
@@ -657,10 +730,6 @@ Function `nfc.unshare` stops sharing data via peer-to-peer.
657
730
  ### Supported Platforms
658
731
 
659
732
  - Android
660
- - Windows
661
- - BlackBerry 7
662
- - BlackBerry 10
663
-
664
733
  ## nfc.erase
665
734
 
666
735
  Erase a NDEF tag
@@ -681,8 +750,6 @@ This method *must* be called from within an NDEF Event Handler.
681
750
  ### Supported Platforms
682
751
 
683
752
  - Android
684
- - BlackBerry 7
685
-
686
753
  ## nfc.handover
687
754
 
688
755
  Send a file to another device via NFC handover.
@@ -756,9 +823,6 @@ Function `showSettings` opens the NFC settings for the operating system.
756
823
  ### Supported Platforms
757
824
 
758
825
  - Android
759
- - Windows
760
- - BlackBerry 10
761
-
762
826
  ## nfc.enabled
763
827
 
764
828
  Check if NFC is available and enabled on this device.
@@ -780,14 +844,11 @@ The reason will be **NO_NFC** if the device doesn't support NFC and **NFC_DISABL
780
844
 
781
845
  Note: that on Android the NFC status is checked before every API call **NO_NFC** or **NFC_DISABLED** can be returned in **any** failure function.
782
846
 
783
- Windows will return **NO_NFC_OR_NFC_DISABLED** when NFC is not present or disabled. If the user disabled NFC after the application started, Windows may return **NFC_DISABLED**. Windows checks the NFC status before most API calls, but there are some cases when the NFC state can not be determined.
784
847
 
785
848
  ### Supported Platforms
786
849
 
787
850
  - Android
788
851
  - iOS
789
- - Windows
790
-
791
852
  ## nfc.beginSession
792
853
 
793
854
  **`beginSession` is deprecated. Use `scanNdef` or `scanTag`**
@@ -1259,11 +1320,7 @@ Events are fired when NFC tags are read. Listeners are added by registering cal
1259
1320
 
1260
1321
  The tag contents are platform dependent.
1261
1322
 
1262
- `id` and `techTypes` may be included when scanning a tag on Android. `serialNumber` may be included on BlackBerry 7.
1263
-
1264
- `id` and `serialNumber` are different names for the same value. `id` is typically displayed as a hex string `nfc.bytesToHexString(tag.id)`.
1265
-
1266
- Windows, Windows Phone 8, and BlackBerry 10 read the NDEF information from a tag, but do not have access to the tag id or other meta data like capacity, read-only status or tag technologies.
1323
+ `id` and `techTypes` are included when scanning a tag on Android; iOS includes `id` for tags scanned with `nfc.scanTag`. `id` is typically displayed as a hex string `nfc.bytesToHexString(tag.id)`.
1267
1324
 
1268
1325
  Assuming the following NDEF message is written to a tag, it will produce the following events when read.
1269
1326
 
@@ -1291,60 +1348,31 @@ Assuming the following NDEF message is written to a tag, it will produce the fol
1291
1348
  }
1292
1349
  }
1293
1350
 
1294
- #### Sample Event on BlackBerry 7
1295
-
1296
- {
1297
- type: 'ndef',
1298
- tag: {
1299
- "tagType": "4",
1300
- "isLocked": false,
1301
- "isLockable": false,
1302
- "freeSpaceSize": "2022",
1303
- "serialNumberLength": "7",
1304
- "serialNumber": [4, 96, 117, 74, -17, 34, -128],
1305
- "name": "Desfire EV1 2K",
1306
- "ndefMessage": [{
1307
- "tnf": 2,
1308
- "type": [116, 101, 120, 116, 47, 112, 103],
1309
- "id": [],
1310
- "payload": [72, 101, 108, 108, 111, 32, 80, 104, 111, 110, 101, 71, 97, 112]
1311
- }]
1312
- }
1313
- }
1314
-
1315
- #### Sample Event on Windows, BlackBerry 10, or Windows Phone 8
1316
-
1317
- {
1318
- type: 'ndef',
1319
- tag: {
1320
- "ndefMessage": [{
1321
- "tnf": 2,
1322
- "type": [116, 101, 120, 116, 47, 112, 103],
1323
- "id": [],
1324
- "payload": [72, 101, 108, 108, 111, 32, 80, 104, 111, 110, 101, 71, 97, 112]
1325
- }]
1326
- }
1327
- }
1328
-
1329
1351
  ## Getting Details about Events
1330
1352
 
1331
- The raw contents of the scanned tags are written to the log before the event is fired. Use `adb logcat` on Android and Event Log (hold alt + lglg) on BlackBerry.
1353
+ The raw contents of the scanned tags are written to the log before the event is fired. Use `adb logcat` on Android and the Xcode console on iOS.
1332
1354
 
1333
1355
  You can also log the tag contents in your event handlers. `console.log(JSON.stringify(nfcEvent.tag))` Note that you want to stringify the tag not the event to avoid a circular reference.
1334
1356
 
1335
1357
  # Platform Differences
1336
1358
 
1359
+ The plugin supports Android and iOS (Windows Phone 8, Windows and BlackBerry 10 were removed in 1.8.0).
1360
+
1337
1361
  ## Non-NDEF Tags
1338
1362
 
1339
- Only Android and BlackBerry 7 can read data from non-NDEF NFC tags. Newer Windows Phones with NXP PN427 chipset can read non-NDEF tags, but can not get any tag meta data.
1363
+ Android reads data from non-NDEF tags (`addTagDiscoveredListener`, `connect` / `transceive`). On iOS,
1364
+ `nfc.scanTag` detects ISO 15693, FeliCa (with `pollFeliCa`) and MIFARE tags and returns their type and
1365
+ UID; raw commands are limited to ISO 7816 APDUs.
1340
1366
 
1341
1367
  ## Mifare Classic Tags
1342
1368
 
1343
- BlackBerry 7, BlackBerry 10 and many newer Android phones will not read Mifare Classic tags. Mifare Ultralight tags will work since they are NFC Forum Type 2 tags. Newer Windows 8.1 phones (Lumia 640) can read Mifare Classic tags.
1369
+ Only Android phones with an NXP NFC controller read MIFARE Classic tags (see `nfc.mifareClassicAuthenticate`).
1370
+ iOS has no MIFARE Classic API. MIFARE Ultralight tags work everywhere since they are NFC Forum Type 2 tags.
1344
1371
 
1345
1372
  ## Tag Id and Meta Data
1346
1373
 
1347
- Windows Phone 8, BlackBerry 10, and Windows read the NDEF information from a tag, but do not have access to the tag id or other meta data like capacity, read-only status or tag technologies.
1374
+ Android returns the tag id, technologies, capacity and read-only status. iOS returns the id and type for
1375
+ tags scanned with `nfc.scanTag`, and the NDEF capacity (`maxSize`) and writability for NDEF tags.
1348
1376
 
1349
1377
  ## Multiple Listeners
1350
1378
 
@@ -1352,18 +1380,10 @@ Multiple listeners can be registered in JavaScript. e.g. addNdefListener, addTag
1352
1380
 
1353
1381
  On Android, only the most specific event will fire. If a Mime Media Tag is scanned, only the addMimeTypeListener callback is called and not the callback defined in addNdefListener. You can use the same event handler for multiple listeners.
1354
1382
 
1355
- For Windows, this plugin mimics the Android behavior. If an ndef event is fired, a tag event will not be fired. You should receive one event per tag.
1356
-
1357
- On BlackBerry 7, all the events fire if a Mime Media Tag is scanned.
1358
-
1359
1383
  ## addTagDiscoveredListener
1360
1384
 
1361
1385
  On Android, addTagDiscoveredListener scans non-NDEF tags and NDEF tags. The tag event does NOT contain an ndefMessage even if there are NDEF messages on the tag. Use addNdefListener or addMimeTypeListener to get the NDEF information.
1362
1386
 
1363
- Windows can scan non-NDEF (unformatted) tags using addTagDiscoveredListener. The tag event will not include any data.
1364
-
1365
- On BlackBerry 7, addTagDiscoveredListener does NOT scan non-NDEF tags. Webworks returns the ndefMessage in the event.
1366
-
1367
1387
  ### Non-NDEF tag scanned with addTagDiscoveredListener on *Android*
1368
1388
 
1369
1389
  {
@@ -1385,63 +1405,35 @@ On BlackBerry 7, addTagDiscoveredListener does NOT scan non-NDEF tags. Webworks
1385
1405
  }
1386
1406
  }
1387
1407
 
1388
- ### Non-NDEF tag scanned with addTagDiscoveredListener on *Windows*
1389
-
1390
- {
1391
- type: 'tag',
1392
- tag: {
1393
- }
1394
- }
1395
-
1396
- # BlackBerry 10 Invoke Target
1397
-
1398
- This plugin uses the [BlackBerry Invocation Framework](http://developer.blackberry.com/native/documentation/cascades/device_platform/invocation/receiving_invocation.html) to read NFC tags on BlackBerry 10. This means that you need to register an invoke target in the config.xml.
1399
-
1400
- If your project supports multiple platforms, copy www/config.xml to merges/config.xml and add a `rim:invoke-target` tag. The invoke-target determines which tags your app will scan when it is running. If your application is not running, BlackBerry will launch it when a matching tag is scanned.
1401
-
1402
- This sample configuration attempts to open any NDEF tag.
1403
-
1404
- <rim:invoke-target id="your.unique.id.here">
1405
- <type>APPLICATION</type>
1406
- <filter>
1407
- <action>bb.action.OPEN</action>
1408
- <mime-type>application/vnd.rim.nfc.ndef</mime-type>
1409
- <!-- any TNF Empty(0), Well Known(1), MIME Media(2), Absolute URI(3), External(4) -->
1410
- <property var="uris" value="ndef://0,ndef://1,ndef://2,ndef://3,ndef://4" />
1411
- </filter>
1412
- </rim:invoke-target>
1413
-
1414
- You can configure you application to handle only certain tags.
1408
+ # Launching your Android Application when Scanning a Tag
1415
1409
 
1416
- For example to scan only MIME Media tags of type "text/pg" use
1410
+ ## Android: `NFC_INTENT_FILTERS` (1.8.0)
1417
1411
 
1418
- <rim:invoke-target id="your.unique.id.here">
1419
- <type>APPLICATION</type>
1420
- <filter>
1421
- <action>bb.action.OPEN</action>
1422
- <mime-type>application/vnd.rim.nfc.ndef</mime-type>
1423
- <!-- TNF MIME Media(2) with type "text/pg" -->
1424
- <property var="uris" value="ndef://2/text/pg" />
1425
- </filter>
1426
- </rim:invoke-target>
1412
+ Android can start (or bring forward) your app when a tag is tapped while the app is closed or in the
1413
+ background. Turn it on with a plugin variable; the plugin's `after_prepare` hook writes the intent
1414
+ filters onto the launcher activity and `res/xml/cdv_nfc_plugin_tech_filter.xml` for you (marked with the plugin's own label, so filters you wrote yourself are never touched):
1427
1415
 
1428
- Or to scan only Plain Text tags use
1416
+ cordova plugin add community-cordova-plugin-nfc --variable NFC_INTENT_FILTERS=ndef,tech
1429
1417
 
1430
- <rim:invoke-target id="your.unique.id.here">
1431
- <type>APPLICATION</type>
1432
- <filter>
1433
- <action>bb.action.OPEN</action>
1434
- <mime-type>application/vnd.rim.nfc.ndef</mime-type>
1435
- <!-- TNF Well Known(1), RTD T -->
1436
- <property var="uris" value="ndef://1/T" />
1437
- </filter>
1438
- </rim:invoke-target>
1418
+ | Value | What is added |
1419
+ |-------|---------------|
1420
+ | `none` (default) | nothing - behaviour of 1.7.x |
1421
+ | `ndef` | `NDEF_DISCOVERED` for each MIME type in `NFC_NDEF_MIME_TYPES` (default `*/*`; NFC Forum Text records count as `text/plain`) |
1422
+ | `tech` | `TECH_DISCOVERED` with a tech list matching any NFC technology (NfcA/B/F/V, IsoDep, Ndef, NdefFormatable, MifareClassic, MifareUltralight) |
1423
+ | `tag` | `TAG_DISCOVERED` (last-resort dispatch) |
1439
1424
 
1440
- See the [BlackBerry documentation](http://developer.blackberry.com/native/documentation/cascades/device_comm/nfc/receiving_content.html) for more info.
1425
+ Combine them with commas. Changing the variable back to `none` and running `cordova prepare` removes
1426
+ everything the hook added. A URL tag keeps opening the browser: Android matches the browser's
1427
+ `NDEF_DISCOVERED` filter first, and `TECH_DISCOVERED` only applies when no app claimed the NDEF intent.
1441
1428
 
1442
- # Launching your Android Application when Scanning a Tag
1429
+ The tag that launched the app is delivered through the normal listeners. It arrives right after
1430
+ `deviceready`, usually before your code has registered its listener, so the plugin keeps it for 30
1431
+ seconds and hands it to the first matching `nfc.addNdefListener` (NDEF tags, including ones matched by
1432
+ `ndef`), `nfc.addTagDiscoveredListener` (non-NDEF tags), `nfc.addMimeTypeListener` or
1433
+ `nfc.addNdefFormatableListener`. The event has `launch: true`.
1443
1434
 
1444
- On Android, intents can be used to launch your application when a NFC tag is read. This is optional and configured in AndroidManifest.xml.
1435
+ To write the filters by hand instead, add them to the activity in `config.xml` with
1436
+ `<edit-config>` / `<config-file>`, for example:
1445
1437
 
1446
1438
  <intent-filter>
1447
1439
  <action android:name="android.nfc.action.NDEF_DISCOVERED" />
@@ -1449,35 +1441,36 @@ On Android, intents can be used to launch your application when a NFC tag is rea
1449
1441
  <category android:name="android.intent.category.DEFAULT" />
1450
1442
  </intent-filter>
1451
1443
 
1452
- Note: `data android:mimeType="text/pg"` should match the data type you specified in JavaScript
1453
-
1454
- We have found it necessary to add `android:noHistory="true"` to the activity element so that scanning a tag launches the application after the user has pressed the home button.
1455
-
1456
- See the Android documentation for more information about [filtering for NFC intents](http://developer.android.com/guide/topics/connectivity/nfc/nfc.html#ndef-disc).
1457
-
1458
- Testing
1459
- =======
1460
-
1461
- Tests require the [Cordova Plugin Test Framework](https://github.com/apache/cordova-plugin-test-framework)
1444
+ See the Android documentation on [filtering for NFC intents](https://developer.android.com/develop/connectivity/nfc/nfc#ndef-disc).
1462
1445
 
1463
- Create a new project
1446
+ ## iOS: background tag reading
1464
1447
 
1465
- git clone https://github.com/chariotsolutions/phonegap-nfc
1466
- cordova create nfc-test com.example.nfc.test NfcTest
1467
- cd nfc-test
1468
- cordova platform add android
1469
- cordova plugin add ../phonegap-nfc
1470
- cordova plugin add ../phonegap-nfc/tests
1471
- cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
1448
+ iOS reads NDEF tags in the background by itself on iPhone XS and newer: a tag carrying a URL record
1449
+ for a domain your app handles as a **Universal Link** opens the app (or shows a notification) without
1450
+ any plugin involvement. To use it:
1472
1451
 
1473
- Change the start page in `config.xml`
1452
+ 1. Set up Universal Links for the domain (Associated Domains entitlement `applinks:example.com` and an
1453
+ `apple-app-site-association` file) - for example with a deep-link plugin.
1454
+ 2. Write the tag with `ndef.uriRecord("https://example.com/...")`.
1455
+ 3. Handle the link in the app like any other Universal Link. The URL is the tag content; the raw NDEF
1456
+ message is available natively as `NSUserActivity.ndefMessagePayload`, which this plugin does not read.
1474
1457
 
1475
- <content src="cdvtests/index.html" />
1458
+ Background reading is not possible while an NFC session is active, while Apple Pay / Wallet is in use,
1459
+ or before the first unlock after a restart. Non-URL records and non-NDEF tags can only be read in the
1460
+ foreground with `nfc.scanNdef` / `nfc.scanTag`.
1476
1461
 
1477
- Run the app on your phone
1462
+ Testing
1463
+ =======
1478
1464
 
1479
- cordova run
1465
+ npm install
1466
+ npm test # eslint, typings type-test, Node unit tests, Android JVM harness (needs a JDK)
1467
+ npm run test:ios # macOS + Xcode: compiles NfcPlugin.m against the iPhoneOS SDK
1480
1468
 
1469
+ `tests/android` runs `NfcPlugin.java` on a plain JVM against fakes of the Android NFC classes that
1470
+ reproduce the framework rules the plugin depends on (one connected technology per tag, stale-tag
1471
+ `SecurityException`, `TagLostException`). `tests/unit` loads `www/phonegap-nfc.js` in Node with a fake
1472
+ Cordova bridge and a byte-accurate NTAG / Ultralight model. None of this replaces a test on a phone with
1473
+ real tags. The old `tests/` Cordova test-framework suite is kept for manual on-device runs.
1481
1474
 
1482
1475
  Sample Projects
1483
1476
  ================