react-native-nfc-manager 4.0.0-beta.1 → 4.0.0-beta.11

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.
Files changed (109) hide show
  1. package/README.md +146 -49
  2. package/android/src/main/java/community/revteltech/nfc/MifareClassicHandler.java +419 -0
  3. package/android/src/main/java/community/revteltech/nfc/MifareUltralightHandler.java +84 -0
  4. package/android/src/main/java/community/revteltech/nfc/NdefHandler.java +397 -0
  5. package/android/src/main/java/community/revteltech/nfc/NfcAdapterStateChangedReceiver.java +48 -0
  6. package/android/src/main/java/community/revteltech/nfc/NfcErrorCodes.java +16 -0
  7. package/android/src/main/java/community/revteltech/nfc/NfcManager.java +348 -1087
  8. package/android/src/main/java/community/revteltech/nfc/NfcManagerIOSStubBase.java +130 -0
  9. package/android/src/main/java/community/revteltech/nfc/NfcTechIoRouter.java +258 -0
  10. package/android/src/main/java/community/revteltech/nfc/TagTechnologyRequest.java +19 -7
  11. package/android/src/main/java/community/revteltech/nfc/Util.java +275 -2
  12. package/app.plugin.js +8 -9
  13. package/dist/ndef-lib/constants.js +67 -0
  14. package/dist/ndef-lib/constants.js.map +1 -0
  15. package/dist/ndef-lib/index.js +79 -0
  16. package/dist/ndef-lib/index.js.map +1 -0
  17. package/dist/ndef-lib/ndef-text.js +29 -0
  18. package/dist/ndef-lib/ndef-text.js.map +1 -0
  19. package/dist/ndef-lib/ndef-uri.js +40 -0
  20. package/dist/ndef-lib/ndef-uri.js.map +1 -0
  21. package/dist/ndef-lib/ndef-wifi-simple.js +100 -0
  22. package/dist/ndef-lib/ndef-wifi-simple.js.map +1 -0
  23. package/dist/ndef-lib/ndef.js +152 -0
  24. package/dist/ndef-lib/ndef.js.map +1 -0
  25. package/dist/ndef-lib/stringifier.js +155 -0
  26. package/dist/ndef-lib/stringifier.js.map +1 -0
  27. package/dist/ndef-lib/util.js +134 -0
  28. package/dist/ndef-lib/util.js.map +1 -0
  29. package/dist/specs/NativeNfcManager.js +5 -0
  30. package/dist/specs/NativeNfcManager.js.map +1 -0
  31. package/dist/src/NativeNfcManager.js +55 -0
  32. package/dist/src/NativeNfcManager.js.map +1 -0
  33. package/dist/src/NfcError.js +220 -0
  34. package/dist/src/NfcError.js.map +1 -0
  35. package/dist/src/NfcManager.js +175 -0
  36. package/dist/src/NfcManager.js.map +1 -0
  37. package/dist/src/NfcManagerAndroid.js +112 -0
  38. package/dist/src/NfcManagerAndroid.js.map +1 -0
  39. package/dist/src/NfcManagerIOS.js +119 -0
  40. package/dist/src/NfcManagerIOS.js.map +1 -0
  41. package/dist/src/NfcTech/Iso15693HandlerIOS.js +99 -0
  42. package/dist/src/NfcTech/Iso15693HandlerIOS.js.map +1 -0
  43. package/dist/src/NfcTech/IsoDepHandler.js +29 -0
  44. package/dist/src/NfcTech/IsoDepHandler.js.map +1 -0
  45. package/dist/src/NfcTech/MifareClassicHandlerAndroid.js +68 -0
  46. package/dist/src/NfcTech/MifareClassicHandlerAndroid.js.map +1 -0
  47. package/dist/src/NfcTech/MifareUltralightHandlerAndroid.js +23 -0
  48. package/dist/src/NfcTech/MifareUltralightHandlerAndroid.js.map +1 -0
  49. package/dist/src/NfcTech/NdefFormatableHandlerAndroid.js +16 -0
  50. package/dist/src/NfcTech/NdefFormatableHandlerAndroid.js.map +1 -0
  51. package/dist/src/NfcTech/NdefHandler.js +54 -0
  52. package/dist/src/NfcTech/NdefHandler.js.map +1 -0
  53. package/dist/src/NfcTech/NfcAHandler.js +16 -0
  54. package/dist/src/NfcTech/NfcAHandler.js.map +1 -0
  55. package/dist/src/NfcTech/NfcVHandler.js +33 -0
  56. package/dist/src/NfcTech/NfcVHandler.js.map +1 -0
  57. package/dist/src/index.js +53 -0
  58. package/dist/src/index.js.map +1 -0
  59. package/index.d.ts +110 -46
  60. package/ios/NfcManager.h +2 -11
  61. package/ios/NfcManager.mm +264 -438
  62. package/ios/RNNfcBridgeUtil.h +28 -0
  63. package/ios/RNNfcBridgeUtil.mm +52 -0
  64. package/ios/RNNfcManager+Felica.swift +61 -0
  65. package/ios/RNNfcManager+Iso15693.swift +895 -0
  66. package/ios/RNNfcManager+IsoDep.swift +145 -0
  67. package/ios/RNNfcManager+Mifare.swift +61 -0
  68. package/ios/RNNfcManager+Ndef.swift +120 -0
  69. package/ios/RNNfcManager.h +251 -0
  70. package/ios/RNNfcManager.swift +648 -0
  71. package/ios/RNNfcSessionDelegateProxy.swift +104 -0
  72. package/ios/RNNfcSwiftUtil.swift +34 -0
  73. package/ndef-lib/{constants.js → constants.ts} +2 -0
  74. package/ndef-lib/{index.js → index.ts} +23 -12
  75. package/ndef-lib/{ndef-text.js → ndef-text.ts} +7 -2
  76. package/ndef-lib/{ndef-uri.js → ndef-uri.ts} +8 -3
  77. package/ndef-lib/{ndef-wifi-simple.js → ndef-wifi-simple.ts} +34 -11
  78. package/ndef-lib/{ndef.js → ndef.ts} +53 -25
  79. package/ndef-lib/{stringifier.js → stringifier.ts} +27 -10
  80. package/ndef-lib/{util.js → util.ts} +23 -9
  81. package/package.json +39 -21
  82. package/react-native-nfc-manager.podspec +3 -2
  83. package/specs/NativeNfcManager.ts +18 -4
  84. package/src/NativeNfcManager.ts +84 -0
  85. package/src/{NfcError.js → NfcError.ts} +6 -17
  86. package/src/{NfcManager.js → NfcManager.ts} +51 -34
  87. package/src/{NfcManagerAndroid.js → NfcManagerAndroid.ts} +27 -8
  88. package/src/{NfcManagerIOS.js → NfcManagerIOS.ts} +31 -10
  89. package/src/NfcTech/{Iso15693HandlerIOS.js → Iso15693HandlerIOS.ts} +64 -36
  90. package/src/NfcTech/{IsoDepHandler.js → IsoDepHandler.ts} +8 -5
  91. package/src/NfcTech/{MifareClassicHandlerAndroid.js → MifareClassicHandlerAndroid.ts} +33 -24
  92. package/src/NfcTech/{MifareUltralightHandlerAndroid.js → MifareUltralightHandlerAndroid.ts} +14 -5
  93. package/src/NfcTech/{NdefFormatableHandlerAndroid.js → NdefFormatableHandlerAndroid.ts} +9 -2
  94. package/src/NfcTech/{NdefHandler.js → NdefHandler.ts} +19 -6
  95. package/src/NfcTech/{NfcAHandler.js → NfcAHandler.ts} +6 -3
  96. package/src/NfcTech/{NfcVHandler.js → NfcVHandler.ts} +8 -5
  97. package/src/__mocks__/{NativeNfcManager.js → NativeNfcManager.ts} +4 -1
  98. package/src/{index.js → index.ts} +1 -1
  99. package/android/src/main/java/community/revteltech/nfc/JsonConvert.java +0 -141
  100. package/android/src/main/java/community/revteltech/nfc/MifareUtil.java +0 -84
  101. package/ios/NfcManager+Felica.mm +0 -43
  102. package/ios/NfcManager+Iso15693.mm +0 -600
  103. package/ios/NfcManager+IsoDep.mm +0 -83
  104. package/ios/NfcManager+Mifare.mm +0 -43
  105. package/ios/Util.mm +0 -55
  106. package/specs/NativeNfcManager.d.ts +0 -6
  107. package/specs/NativeNfcManager.js +0 -3
  108. package/specs/NativeNfcManager.js.map +0 -1
  109. package/src/NativeNfcManager.js +0 -37
@@ -2,8 +2,11 @@
2
2
  // Copyright 2013 Don Coleman
3
3
  //
4
4
 
5
+ type Byte = number;
6
+ type ByteArray = Byte[];
7
+
5
8
  // https://weblog.rogueamoeba.com/2017/02/27/javascript-correctly-converting-a-byte-array-to-a-utf-8-string/
6
- function _utf8ArrayToStr(data) {
9
+ function _utf8ArrayToStr(data: ByteArray): string | null {
7
10
  const extraByteMap = [1, 1, 1, 1, 2, 2, 3, 0];
8
11
  var count = data.length;
9
12
  var str = '';
@@ -25,16 +28,25 @@ function _utf8ArrayToStr(data) {
25
28
 
26
29
  ch = (ch << 6) | (chx & 0x3f);
27
30
  }
31
+
32
+ // A four-byte sequence can decode above the Unicode maximum, which is
33
+ // not a valid code point. Reject it like the other malformed cases
34
+ // rather than letting String.fromCodePoint throw a RangeError.
35
+ if (ch > 0x10ffff) {
36
+ return null;
37
+ }
28
38
  }
29
39
 
30
- str += String.fromCharCode(ch);
40
+ // fromCharCode truncates to 16 bits, which silently corrupts anything
41
+ // outside the BMP: U+1F4A9 would come back as U+F4A9.
42
+ str += String.fromCodePoint(ch);
31
43
  }
32
44
 
33
45
  return str;
34
46
  }
35
47
 
36
48
  // https://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
37
- function _toUTF8Array(str) {
49
+ function _toUTF8Array(str: string): ByteArray {
38
50
  var out = [],
39
51
  p = 0;
40
52
  for (var i = 0; i < str.length; i++) {
@@ -64,7 +76,7 @@ function _toUTF8Array(str) {
64
76
  return out;
65
77
  }
66
78
 
67
- function stringToBytes(string) {
79
+ function stringToBytes(string: string): ByteArray {
68
80
  return _toUTF8Array(string);
69
81
  // var bytes = Buffer(string).toJSON();
70
82
  // if (bytes.hasOwnProperty('data')) {
@@ -76,7 +88,7 @@ function stringToBytes(string) {
76
88
  // }
77
89
  }
78
90
 
79
- function bytesToString(bytes) {
91
+ function bytesToString(bytes: string | ByteArray): string | null {
80
92
  if (typeof bytes === 'string') {
81
93
  return bytes;
82
94
  }
@@ -86,7 +98,7 @@ function bytesToString(bytes) {
86
98
  }
87
99
 
88
100
  // useful for readable version of Tag UID
89
- function bytesToHexString(bytes) {
101
+ function bytesToHexString(bytes: ByteArray): string {
90
102
  var dec,
91
103
  hexstring,
92
104
  bytesAsHexString = '';
@@ -107,7 +119,7 @@ function bytesToHexString(bytes) {
107
119
  }
108
120
 
109
121
  // i must be <= 256
110
- function toHex(i) {
122
+ function toHex(i: number): string {
111
123
  var hex;
112
124
 
113
125
  if (i < 0) {
@@ -122,8 +134,8 @@ function toHex(i) {
122
134
  return hex;
123
135
  }
124
136
 
125
- function toPrintable(i) {
126
- if ((i >= 0x20) & (i <= 0x7f)) {
137
+ function toPrintable(i: number): string {
138
+ if (i >= 0x20 && i <= 0x7f) {
127
139
  return String.fromCharCode(i);
128
140
  } else {
129
141
  return '.';
@@ -137,3 +149,5 @@ module.exports = {
137
149
  toHex: toHex,
138
150
  toPrintable: toPrintable,
139
151
  };
152
+
153
+ export {};
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "react-native-nfc-manager",
3
- "version": "4.0.0-beta.1",
3
+ "version": "4.0.0-beta.11",
4
4
  "description": "A NFC module for react native.",
5
- "main": "src/index.js",
5
+ "main": "dist/src/index.js",
6
+ "types": "index.d.ts",
6
7
  "repository": {
7
8
  "type": "git",
8
- "url": "https://github.com/whitedogg13/react-native-nfc-manager.git"
9
+ "url": "https://github.com/revtel/react-native-nfc-manager.git"
9
10
  },
10
11
  "bugs": {
11
- "url": "https://github.com/whitedogg13/react-native-nfc-manager/issues"
12
+ "url": "https://github.com/revtel/react-native-nfc-manager/issues"
12
13
  },
13
14
  "keywords": [
14
15
  "react-native",
@@ -17,6 +18,7 @@
17
18
  "nfc"
18
19
  ],
19
20
  "files": [
21
+ "dist",
20
22
  "src",
21
23
  "ndef-lib",
22
24
  "index.d.ts",
@@ -32,16 +34,9 @@
32
34
  "url": "https://github.com/whitedogg13"
33
35
  },
34
36
  "jest": {
35
- "testEnvironment": "node"
36
- },
37
- "babel": {
38
- "presets": [
39
- "@babel/preset-env",
40
- "@babel/preset-react"
41
- ],
42
- "plugins": [
43
- "@babel/plugin-proposal-class-properties",
44
- "@babel/plugin-transform-runtime"
37
+ "testEnvironment": "node",
38
+ "testPathIgnorePatterns": [
39
+ "<rootDir>/example/"
45
40
  ]
46
41
  },
47
42
  "devDependencies": {
@@ -50,6 +45,8 @@
50
45
  "@babel/plugin-transform-runtime": "^7.12.10",
51
46
  "@babel/preset-env": "^7.12.11",
52
47
  "@babel/preset-react": "^7.12.10",
48
+ "@babel/preset-typescript": "^7.27.1",
49
+ "@expo/config-plugins": "~10.0.0",
53
50
  "@react-native-community/eslint-config": "^3.2.0",
54
51
  "@release-it/conventional-changelog": "^8.0.1",
55
52
  "dotenv-cli": "^7.4.2",
@@ -57,14 +54,15 @@
57
54
  "jest": "^29.7.0",
58
55
  "jest-cli": "^29.7.0",
59
56
  "prettier": "^2.2.1",
60
- "react": "^16.13.1",
61
- "react-native": "^0.63.0",
57
+ "react": "^19.2.3",
58
+ "react-native": "^0.84.0",
62
59
  "release-it": "^17.5.0",
63
- "typescript": "^4.1.3",
64
- "@expo/config-plugins": "~9.0.0"
60
+ "typescript": "^4.1.3"
65
61
  },
66
62
  "peerDependencies": {
67
- "@expo/config-plugins": "8 || 9"
63
+ "@expo/config-plugins": "*",
64
+ "react": ">=18.2",
65
+ "react-native": ">=0.76"
68
66
  },
69
67
  "peerDependenciesMeta": {
70
68
  "@expo/config-plugins": {
@@ -72,11 +70,31 @@
72
70
  }
73
71
  },
74
72
  "scripts": {
73
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
74
+ "build": "npm run clean && tsc -p tsconfig.build.json",
75
75
  "lint": "eslint .",
76
76
  "lint:fix": "eslint --fix .",
77
77
  "test": "jest -i",
78
- "release": "dotenv -- release-it --",
79
- "release:beta": "release-it --preRelease=beta --increment=prerelease"
78
+ "typecheck": "tsc --noEmit -p tsconfig.typecheck.json",
79
+ "verify:package": "npm run build && node scripts/verify-package-contents.js",
80
+ "verify:codegen": "node scripts/verify-codegen-compatibility.js",
81
+ "verify:codegen:version": "node scripts/verify-codegen-compatibility.js --version",
82
+ "verify:codegen:regression": "node scripts/verify-codegen-compatibility.js --version=0.77.3 --assert-beta8-regression",
83
+ "verify:native:support-floor": "node scripts/verify-native-support-floor.js",
84
+ "verify:native:support-floor:android": "node scripts/verify-native-support-floor.js --platform=android",
85
+ "verify:native:support-floor:ios": "node scripts/verify-native-support-floor.js --platform=ios",
86
+ "verify:expo": "node scripts/verify-expo-consumer.js",
87
+ "verify:expo:config": "node scripts/verify-expo-consumer.js --platform=config",
88
+ "verify:expo:android": "node scripts/verify-expo-consumer.js --platform=android",
89
+ "verify:expo:ios": "node scripts/verify-expo-consumer.js --platform=ios",
90
+ "prepare:expo:smoke": "node scripts/prepare-expo-smoke.js",
91
+ "prepack": "npm run build",
92
+ "release": "dotenv -- node scripts/release.js stable",
93
+ "release:beta": "dotenv -- node scripts/release.js beta",
94
+ "test:example": "npm --prefix example test -- --runInBand --no-watchman",
95
+ "verify": "npm run build && npm run lint && npm run typecheck && npm test -- --runInBand --no-watchman && npm run test:example && node scripts/verify-package-contents.js",
96
+ "release:stable": "dotenv -- node scripts/release.js stable",
97
+ "test:publishing": "node --test scripts/trusted-publishing.test.cjs"
80
98
  },
81
99
  "codegenConfig": {
82
100
  "name": "NativeNfcManagerSpec",
@@ -13,7 +13,8 @@ Pod::Spec.new do |s|
13
13
  s.source = { git: package[:repository][:url] }
14
14
  # s.source_files = "ios/**/*.{h,m}"
15
15
  s.source_files = "ios/**/*.{h,m,mm,swift}"
16
- s.platform = :ios, "8.0"
16
+ s.swift_version = "5.7"
17
+ s.platform = :ios, "15.1"
17
18
 
18
19
  # s.dependency "React-Core"
19
20
 
@@ -22,4 +23,4 @@ Pod::Spec.new do |s|
22
23
  }
23
24
 
24
25
  install_modules_dependencies(s)
25
- end
26
+ end
@@ -1,8 +1,20 @@
1
1
  import type {TurboModule} from 'react-native';
2
+ import type {EventEmitter} from 'react-native/Libraries/Types/CodegenTypes';
2
3
  import {TurboModuleRegistry} from 'react-native';
3
4
 
5
+ export type SessionClosedEvent = {
6
+ error: string;
7
+ };
8
+
9
+ export type StateChangedEvent = {
10
+ state: string;
11
+ };
12
+
4
13
  export interface Spec extends TurboModule {
5
- echo(value: string, callback: (err?: string, resp?: string) => void): void;
14
+ readonly onDiscoverTag: EventEmitter<Object>;
15
+ readonly onDiscoverBackgroundTag: EventEmitter<Object>;
16
+ readonly onSessionClosed: EventEmitter<SessionClosedEvent>;
17
+ readonly onStateChanged: EventEmitter<StateChangedEvent>;
6
18
  isSupported(tech: string, callback: (err?: string, resp?: boolean) => void): void;
7
19
  isEnabled(callback: (err?: string, resp?: boolean) => void): void;
8
20
  start(callback: (err?: string) => void): void;
@@ -26,6 +38,7 @@ export interface Spec extends TurboModule {
26
38
  invalidateSession(callback: (err?: string) => void): void;
27
39
  invalidateSessionWithError(message: string, callback: (err?: string) => void): void;
28
40
  getNdefMessage(callback: (err?: string, tag?: Object) => void): void;
41
+ getCachedNdefMessage(callback: (err?: string, tag?: Object) => void): void;
29
42
  writeNdefMessage(bytes: number[], options: Object, callback: (err?: string) => void): void;
30
43
  makeReadOnly(callback: (err?: string) => void): void;
31
44
  setAlertMessage(message: string, callback: (err?: string) => void): void;
@@ -39,7 +52,7 @@ export interface Spec extends TurboModule {
39
52
  removeListeners: (count: number) => void;
40
53
  iso15693_getSystemInfo(requestFlag: number, callback: (err?: string, systemInfo?: Object) => void): void;
41
54
  iso15693_readSingleBlock(options: Object, callback: (err?: string, bytes?: number[]) => void): void;
42
- iso15693_readMultipleBlocks(options: Object, callback: (err?: string, bytes?: number[]) => void): void;
55
+ iso15693_readMultipleBlocks(options: Object, callback: (err?: string, blocks?: number[][]) => void): void;
43
56
  iso15693_writeSingleBlock(options: Object, callback: (err?: string) => void): void;
44
57
  iso15693_lockBlock(options: Object, callback: (err?: string) => void): void;
45
58
  iso15693_writeAFI(options: Object, callback: (err?: string) => void): void;
@@ -48,16 +61,17 @@ export interface Spec extends TurboModule {
48
61
  iso15693_lockDSFID(options: Object, callback: (err?: string) => void): void;
49
62
  iso15693_resetToReady(options: Object, callback: (err?: string) => void): void;
50
63
  iso15693_select(options: Object, callback: (err?: string) => void): void;
51
- iso15693_stayQuiet(options: Object, callback: (err?: string) => void): void;
64
+ iso15693_stayQuiet(callback: (err?: string) => void): void;
52
65
  iso15693_customCommand(options: Object, callback: (err?: string, bytes?: number[]) => void): void;
53
66
  iso15693_sendRequest(options: Object, callback: (err?: string, responseFlag?: number, bytes?: number[]) => void): void;
54
67
  iso15693_extendedReadSingleBlock(options: Object, callback: (err?: string, bytes?: number[]) => void): void;
55
- iso15693_extendedReadMultipleBlocks(options: Object, callback: (err?: string, bytes?: number[]) => void): void;
68
+ iso15693_extendedReadMultipleBlocks(options: Object, callback: (err?: string, blocks?: number[][]) => void): void;
56
69
  iso15693_extendedWriteSingleBlock(options: Object, callback: (err?: string) => void): void;
57
70
  iso15693_extendedLockBlock(options: Object, callback: (err?: string) => void): void;
58
71
  goToNfcSetting(callback: (err?: string) => void): void;
59
72
  getLaunchTagEvent(callback: (err?: string, tag?: Object) => void): void;
60
73
  setTimeout(timeout: number, callback: (err?: string, tag?: Object) => void): void;
74
+ getTimeout(callback: (err?: string, timeout?: number) => void): void;
61
75
  connect(techs: string[], callback: (err?: string) => void): void;
62
76
  close(callback: (err?: string) => void): void;
63
77
  transceive(bytes: number[], callback: (err?: string, bytes?: number[]) => void): void;
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+ import {NativeModules, NativeEventEmitter} from 'react-native';
3
+
4
+ type NativeMethod = (...args: unknown[]) => void;
5
+ type NativeEventSubscription = {remove: () => void};
6
+ type CodegenEventEmitter = (
7
+ listener: (payload: unknown) => void,
8
+ ) => NativeEventSubscription;
9
+ type NativeModule = Record<string, NativeMethod> & Record<string, unknown> & {
10
+ addListener: (eventType: string) => void;
11
+ removeListeners: (count: number) => void;
12
+ onDiscoverTag?: CodegenEventEmitter;
13
+ onDiscoverBackgroundTag?: CodegenEventEmitter;
14
+ onSessionClosed?: CodegenEventEmitter;
15
+ onStateChanged?: CodegenEventEmitter;
16
+ };
17
+ type NativeEmitterLike = {
18
+ addListener: (eventName: string, listener: (payload: unknown) => void) => NativeEventSubscription;
19
+ };
20
+
21
+ const reactNativeGlobal = global as typeof global & {
22
+ 'RN$Bridgeless'?: boolean;
23
+ __turboModuleProxy?: unknown;
24
+ };
25
+ const isTurboModuleEnabled =
26
+ reactNativeGlobal['RN$Bridgeless'] === true ||
27
+ reactNativeGlobal.__turboModuleProxy != null;
28
+ const nativeModules = NativeModules || {};
29
+ const NativeNfcManager = (isTurboModuleEnabled
30
+ ? require('../specs/NativeNfcManager').default
31
+ : nativeModules.NfcManager) as NativeModule;
32
+
33
+ const legacyNfcManagerEmitter: NativeEmitterLike =
34
+ typeof NativeEventEmitter === 'function'
35
+ ? new NativeEventEmitter(NativeNfcManager)
36
+ : {addListener: () => ({remove: () => {}})};
37
+
38
+ const codegenEventEmitters: Record<string, CodegenEventEmitter | undefined> = {
39
+ NfcManagerDiscoverTag: NativeNfcManager.onDiscoverTag,
40
+ NfcManagerDiscoverBackgroundTag: NativeNfcManager.onDiscoverBackgroundTag,
41
+ NfcManagerSessionClosed: NativeNfcManager.onSessionClosed,
42
+ NfcManagerStateChanged: NativeNfcManager.onStateChanged,
43
+ };
44
+
45
+ const NfcManagerEmitter: NativeEmitterLike = {
46
+ addListener: (eventName, listener) => {
47
+ const codegenEmitter = codegenEventEmitters[eventName];
48
+ if (isTurboModuleEnabled && codegenEmitter) {
49
+ return codegenEmitter(listener);
50
+ }
51
+ return legacyNfcManagerEmitter.addListener(eventName, listener);
52
+ },
53
+ };
54
+
55
+ function callNative<T = unknown>(name: string, params: unknown[] = []): Promise<T> {
56
+ const nativeMethod = NativeNfcManager[name] as NativeMethod | undefined;
57
+
58
+ if (!nativeMethod) {
59
+ throw new Error(`no such native method: "${name}"`);
60
+ }
61
+
62
+ if (!Array.isArray(params)) {
63
+ throw new Error('params must be an array');
64
+ }
65
+
66
+ const createCallback = (
67
+ resolve: (value: T | PromiseLike<T>) => void,
68
+ reject: (reason?: unknown) => void,
69
+ ) => (err: unknown, result: T) => {
70
+ if (err) {
71
+ reject(err);
72
+ } else {
73
+ resolve(result);
74
+ }
75
+ };
76
+
77
+ return new Promise((resolve, reject) => {
78
+ const callback = createCallback(resolve, reject);
79
+ const inputParams = [...params, callback];
80
+ nativeMethod(...inputParams);
81
+ });
82
+ }
83
+
84
+ export {NativeNfcManager, NfcManagerEmitter, callNative};
@@ -7,22 +7,18 @@ export class InvalidParameter extends NfcErrorBase {}
7
7
  export class InvalidParameterLength extends NfcErrorBase {}
8
8
  export class ParameterOutOfBound extends NfcErrorBase {}
9
9
  export class RadioDisabled extends NfcErrorBase {}
10
- // transceive errors
11
10
  export class TagConnectionLost extends NfcErrorBase {}
12
11
  export class RetryExceeded extends NfcErrorBase {}
13
12
  export class TagResponseError extends NfcErrorBase {}
14
13
  export class SessionInvalidated extends NfcErrorBase {}
15
14
  export class TagNotConnected extends NfcErrorBase {}
16
15
  export class PacketTooLong extends NfcErrorBase {}
17
- // reader session errors
18
16
  export class UserCancel extends NfcErrorBase {}
19
17
  export class Timeout extends NfcErrorBase {}
20
18
  export class Unexpected extends NfcErrorBase {}
21
19
  export class SystemBusy extends NfcErrorBase {}
22
20
  export class FirstNdefInvalid extends NfcErrorBase {}
23
- // tag command configuration errors
24
21
  export class InvalidConfiguration extends NfcErrorBase {}
25
- // ndef reader session error
26
22
  export class TagNotWritable extends NfcErrorBase {}
27
23
  export class TagUpdateFailure extends NfcErrorBase {}
28
24
  export class TagSizeTooSmall extends NfcErrorBase {}
@@ -37,29 +33,25 @@ export const NfcErrorIOS = {
37
33
  invalidParameterLength: 4,
38
34
  parameterOutOfBound: 5,
39
35
  radioDisabled: 6,
40
- // transceive errors
41
36
  tagConnectionLost: 100,
42
37
  retryExceeded: 101,
43
38
  tagResponseError: 102,
44
39
  sessionInvalidated: 103,
45
40
  tagNotConnected: 104,
46
41
  packetTooLong: 105,
47
- // reader session errors
48
42
  userCancel: 200,
49
43
  timeout: 201,
50
44
  unexpected: 202,
51
45
  systemBusy: 203,
52
46
  firstNdefInvalid: 204,
53
- // tag command configuration errors
54
47
  invalidConfiguration: 300,
55
- // ndef reader session error
56
48
  tagNotWritable: 400,
57
49
  tagUpdateFailure: 401,
58
50
  tagSizeTooSmall: 402,
59
51
  zeroLengthMessage: 403,
60
52
  },
61
53
 
62
- parse: (error) => {
54
+ parse: (error: string | UserCancel | unknown) => {
63
55
  if (typeof error === 'string') {
64
56
  const [domainError] = error.split(',');
65
57
 
@@ -70,7 +62,6 @@ export const NfcErrorIOS = {
70
62
  }
71
63
  }
72
64
  } else if (error instanceof UserCancel) {
73
- // this is for backward capability only
74
65
  console.warn('API Deprecated: please use NfcError.UserCancel instead');
75
66
  return NfcErrorIOS.errCodes.userCancel;
76
67
  }
@@ -78,7 +69,7 @@ export const NfcErrorIOS = {
78
69
  },
79
70
  };
80
71
 
81
- export function buildNfcExceptionIOS(error) {
72
+ export function buildNfcExceptionIOS(error: string) {
82
73
  const [domainError] = error.split(',');
83
74
 
84
75
  if (domainError) {
@@ -136,7 +127,7 @@ export function buildNfcExceptionIOS(error) {
136
127
  return new NfcErrorBase(error);
137
128
  }
138
129
 
139
- export function buildNfcExceptionAndroid(error) {
130
+ export function buildNfcExceptionAndroid(error: string) {
140
131
  if (error === 'cancelled') {
141
132
  return new UserCancel();
142
133
  }
@@ -144,15 +135,14 @@ export function buildNfcExceptionAndroid(error) {
144
135
  return new NfcErrorBase(error);
145
136
  }
146
137
 
147
- export async function handleNativeException(
148
- callNativePromise,
138
+ export async function handleNativeException<T>(
139
+ callNativePromise: Promise<T>,
149
140
  ignoreError = false,
150
- ) {
141
+ ): Promise<T | undefined> {
151
142
  try {
152
143
  return await callNativePromise;
153
144
  } catch (err) {
154
145
  if (!ignoreError) {
155
- // the error from the native side will always be a string
156
146
  if (typeof err === 'string') {
157
147
  if (Platform.OS === 'ios') {
158
148
  throw buildNfcExceptionIOS(err);
@@ -161,7 +151,6 @@ export async function handleNativeException(
161
151
  }
162
152
  }
163
153
 
164
- // unexpected condition, simply throws them out without conversion
165
154
  throw err;
166
155
  }
167
156
  }
@@ -20,7 +20,7 @@ const NfcEvents = {
20
20
  DiscoverBackgroundTag: 'NfcManagerDiscoverBackgroundTag',
21
21
  SessionClosed: 'NfcManagerSessionClosed',
22
22
  StateChanged: 'NfcManagerStateChanged',
23
- };
23
+ } as const;
24
24
 
25
25
  const NfcTech = {
26
26
  Ndef: 'Ndef',
@@ -35,37 +35,50 @@ const NfcTech = {
35
35
  Iso15693IOS: 'iso15693',
36
36
  FelicaIOS: 'felica',
37
37
  NdefFormatable: 'NdefFormatable',
38
- };
38
+ } as const;
39
39
 
40
40
  const DEFAULT_REGISTER_TAG_EVENT_OPTIONS = {
41
41
  alertMessage: 'Please tap NFC tags',
42
42
  invalidateAfterFirstRead: false,
43
43
  isReaderModeEnabled: false,
44
44
  readerModeFlags: 0,
45
- readerModeDelay: 10,
46
- };
45
+ readerModeDelay: 250,
46
+ } as const;
47
+
48
+ type NfcEventName = (typeof NfcEvents)[keyof typeof NfcEvents];
49
+ type RegisterTagEventOptions = Partial<typeof DEFAULT_REGISTER_TAG_EVENT_OPTIONS>;
50
+ type WriteNdefOptions = {reconnectAfterWrite?: boolean};
51
+ type ClientEventCallback = ((payload: unknown) => void) | null;
52
+ type NativeSubscriptionMap = Partial<Record<NfcEventName, {remove: () => void}>>;
53
+ type ClientListenerMap = Partial<Record<NfcEventName, ClientEventCallback>>;
54
+ type AsyncMethod = (...args: unknown[]) => Promise<unknown>;
47
55
 
48
56
  function NotImpl() {
49
57
  throw new Error('not implemented');
50
58
  }
51
59
 
52
- async function DoNothing() {
60
+ async function DoNothing(..._args: unknown[]) {
53
61
  // allow derived class to not implment it
54
62
  }
55
63
 
56
64
  class NfcManagerBase {
65
+ _subscriptions: NativeSubscriptionMap;
66
+ _clientListeners: ClientListenerMap;
67
+ _ndefHandler: NdefHandler | null;
68
+ _nfcAHandler: NfcAHandler | null;
69
+ _nfcVHandler: NfcVHandler | null;
70
+ _isoDepHandler: IsoDepHandler | null;
71
+
57
72
  constructor() {
73
+ this._subscriptions = {};
74
+ this._clientListeners = {};
75
+ this._ndefHandler = null;
76
+ this._nfcAHandler = null;
77
+ this._nfcVHandler = null;
78
+ this._isoDepHandler = null;
58
79
  this._subscribeNativeEvents();
59
80
  }
60
81
 
61
- hello(str) {
62
- return NativeNfcManager.hello(str);
63
- }
64
-
65
- async echo(msg) {
66
- return handleNativeException(callNative('echo', [msg]));
67
- }
68
-
69
82
  async start() {
70
83
  return handleNativeException(callNative('start'));
71
84
  }
@@ -74,7 +87,7 @@ class NfcManagerBase {
74
87
  return handleNativeException(callNative('isSupported', [tech]));
75
88
  }
76
89
 
77
- async registerTagEvent(options = {}) {
90
+ async registerTagEvent(options: RegisterTagEventOptions = {}) {
78
91
  const optionsWithDefault = {
79
92
  ...DEFAULT_REGISTER_TAG_EVENT_OPTIONS,
80
93
  ...options,
@@ -93,8 +106,10 @@ class NfcManagerBase {
93
106
  return handleNativeException(callNative('getTag'));
94
107
  }
95
108
 
96
- setEventListener(name, callback) {
97
- const allNfcEvents = Object.keys(NfcEvents).map((k) => NfcEvents[k]);
109
+ setEventListener(name: NfcEventName, callback: ClientEventCallback) {
110
+ const allNfcEvents = Object.keys(NfcEvents).map(
111
+ (k) => NfcEvents[k as keyof typeof NfcEvents],
112
+ );
98
113
  if (allNfcEvents.indexOf(name) === -1) {
99
114
  throw new Error('no such event');
100
115
  }
@@ -102,24 +117,26 @@ class NfcManagerBase {
102
117
  this._clientListeners[name] = callback;
103
118
  }
104
119
 
105
- requestTechnology = NotImpl;
120
+ requestTechnology: AsyncMethod = async (..._args: unknown[]) => NotImpl();
121
+
122
+ restartTechnologyRequestIOS: AsyncMethod = async (..._args: unknown[]) => NotImpl();
106
123
 
107
- restartTechnologyRequestIOS = NotImpl;
124
+ cancelTechnologyRequest: AsyncMethod = async (..._args: unknown[]) => NotImpl();
108
125
 
109
- cancelTechnologyRequest = NotImpl;
126
+ getBackgroundTag: AsyncMethod = async (..._args: unknown[]) => NotImpl();
110
127
 
111
- getBackgroundTag = NotImpl;
128
+ clearBackgroundTag: AsyncMethod = async (..._args: unknown[]) => NotImpl();
112
129
 
113
- clearBackgroundTag = NotImpl;
130
+ setAlertMessage: AsyncMethod = DoNothing;
114
131
 
115
- setAlertMessage = DoNothing;
132
+ getTimeout: AsyncMethod = DoNothing;
116
133
 
117
- async writeNdefMessage(bytes, options = {}) {
118
- return handleNativeException(callNative('writeNdefMessage', [bytes, options]));
134
+ async writeNdefMessage(bytes: number[], options: WriteNdefOptions = {}) {
135
+ return this.ndefHandler.writeNdefMessage(bytes, options);
119
136
  }
120
137
 
121
138
  async getNdefMessage() {
122
- return handleNativeException(callNative('getNdefMessage'));
139
+ return this.ndefHandler.getNdefMessage();
123
140
  }
124
141
 
125
142
  get ndefHandler() {
@@ -151,36 +168,36 @@ class NfcManagerBase {
151
168
  }
152
169
 
153
170
  get MIFARE_BLOCK_SIZE() {
154
- return NativeNfcManager.MIFARE_BLOCK_SIZE;
171
+ return NativeNfcManager.MIFARE_BLOCK_SIZE as unknown as number;
155
172
  }
156
173
  get MIFARE_ULTRALIGHT_PAGE_SIZE() {
157
- return NativeNfcManager.MIFARE_ULTRALIGHT_PAGE_SIZE;
174
+ return NativeNfcManager.MIFARE_ULTRALIGHT_PAGE_SIZE as unknown as number;
158
175
  }
159
176
  get MIFARE_ULTRALIGHT_TYPE() {
160
- return NativeNfcManager.MIFARE_ULTRALIGHT_TYPE;
177
+ return NativeNfcManager.MIFARE_ULTRALIGHT_TYPE as unknown as number;
161
178
  }
162
179
  get MIFARE_ULTRALIGHT_TYPE_C() {
163
- return NativeNfcManager.MIFARE_ULTRALIGHT_TYPE_C;
180
+ return NativeNfcManager.MIFARE_ULTRALIGHT_TYPE_C as unknown as number;
164
181
  }
165
182
  get MIFARE_ULTRALIGHT_TYPE_UNKNOWN() {
166
- return NativeNfcManager.MIFARE_ULTRALIGHT_TYPE_UNKNOWN;
183
+ return NativeNfcManager.MIFARE_ULTRALIGHT_TYPE_UNKNOWN as unknown as number;
167
184
  }
168
185
 
169
- _onDiscoverTag = (tag) => {
186
+ _onDiscoverTag = (tag: unknown) => {
170
187
  const callback = this._clientListeners[NfcEvents.DiscoverTag];
171
188
  if (callback) {
172
189
  callback(tag);
173
190
  }
174
191
  };
175
192
 
176
- _onDiscoverBackgroundTag = (tag) => {
193
+ _onDiscoverBackgroundTag = (tag: unknown) => {
177
194
  const callback = this._clientListeners[NfcEvents.DiscoverBackgroundTag];
178
195
  if (callback) {
179
196
  callback(tag);
180
197
  }
181
198
  };
182
199
 
183
- _onSessionClosedIOS = (resp) => {
200
+ _onSessionClosedIOS = (resp: {error: string}) => {
184
201
  const callback = this._clientListeners[NfcEvents.SessionClosed];
185
202
  if (callback) {
186
203
  const error = buildNfcExceptionIOS(resp.error);
@@ -188,7 +205,7 @@ class NfcManagerBase {
188
205
  }
189
206
  };
190
207
 
191
- _onStateChangedAndroid = (state) => {
208
+ _onStateChangedAndroid = (state: unknown) => {
192
209
  const callback = this._clientListeners[NfcEvents.StateChanged];
193
210
  if (callback) {
194
211
  callback(state);