@exxili/capacitor-nfc 0.0.10 → 0.0.12
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 +190 -102
- package/android/src/main/kotlin/com/exxili/capacitornfc/NFCPlugin.kt +136 -15
- package/dist/esm/definitions.d.ts +43 -7
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.js +205 -42
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +2 -6
- package/dist/esm/web.js +10 -22
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +215 -64
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +215 -64
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/NFCPlugin/NFCPlugin.swift +40 -13
- package/ios/Sources/NFCPlugin/NFCReader.swift +183 -42
- package/ios/Sources/NFCPlugin/NFCWriter.swift +7 -14
- package/package.json +4 -3
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import CoreNFC
|
|
3
3
|
|
|
4
|
-
@objc public class NFCReader: NSObject,
|
|
5
|
-
private var readerSession:
|
|
4
|
+
@objc public class NFCReader: NSObject, NFCTagReaderSessionDelegate {
|
|
5
|
+
private var readerSession: NFCTagReaderSession?
|
|
6
6
|
|
|
7
|
-
public var onNDEFMessageReceived: (([NFCNDEFMessage]) -> Void)?
|
|
7
|
+
public var onNDEFMessageReceived: (([NFCNDEFMessage], [String: Any]?) -> Void)?
|
|
8
8
|
public var onError: ((Error) -> Void)?
|
|
9
9
|
|
|
10
10
|
@objc public func startScanning() {
|
|
@@ -14,29 +14,30 @@ import CoreNFC
|
|
|
14
14
|
print("NFC scanning not supported on this device")
|
|
15
15
|
return
|
|
16
16
|
}
|
|
17
|
-
readerSession =
|
|
17
|
+
readerSession = NFCTagReaderSession(pollingOption: [.iso14443, .iso15693, .iso18092], delegate: self, queue: nil)
|
|
18
18
|
readerSession?.alertMessage = "Hold your iPhone near the NFC tag."
|
|
19
19
|
readerSession?.begin()
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
@objc public func cancelScanning() {
|
|
23
|
+
if let session = readerSession {
|
|
24
|
+
session.invalidate()
|
|
25
|
+
}
|
|
26
|
+
readerSession = nil
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
// NFCTagReaderSessionDelegate methods
|
|
30
|
+
public func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
|
|
31
|
+
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
public func
|
|
33
|
-
|
|
34
|
+
public func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
|
|
35
|
+
print("NFC reader session error: \(error.localizedDescription)")
|
|
36
|
+
onError?(error)
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
public func readerSession(_ session: NFCNDEFReaderSession, didDetect tags: [NFCNDEFTag]) {
|
|
39
|
+
public func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
|
|
38
40
|
if tags.count > 1 {
|
|
39
|
-
// Restart polling in 500ms
|
|
40
41
|
let retryInterval = DispatchTimeInterval.milliseconds(500)
|
|
41
42
|
session.alertMessage = "More than one tag detected. Please remove extra tags and try again."
|
|
42
43
|
DispatchQueue.global().asyncAfter(deadline: .now() + retryInterval) {
|
|
@@ -45,51 +46,191 @@ import CoreNFC
|
|
|
45
46
|
return
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
// Connect to the found tag and perform NDEF message reading
|
|
49
49
|
let tag = tags.first!
|
|
50
50
|
session.connect(to: tag) { (error: Error?) in
|
|
51
51
|
if let error = error {
|
|
52
|
-
session.
|
|
52
|
+
session.invalidate(errorMessage: "Unable to connect to tag.")
|
|
53
|
+
self.onError?(error)
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Extract tag information
|
|
58
|
+
let tagInfo = self.extractTagInfo(from: tag)
|
|
59
|
+
|
|
60
|
+
// Try to read NDEF if the tag supports it
|
|
61
|
+
if case let .iso7816(iso7816Tag) = tag {
|
|
62
|
+
self.handleISO7816Tag(iso7816Tag, session: session, tagInfo: tagInfo)
|
|
63
|
+
} else if case let .miFare(miFareTag) = tag {
|
|
64
|
+
self.handleMiFareTag(miFareTag, session: session, tagInfo: tagInfo)
|
|
65
|
+
} else if case let .feliCa(feliCaTag) = tag {
|
|
66
|
+
self.handleFeliCaTag(feliCaTag, session: session, tagInfo: tagInfo)
|
|
67
|
+
} else if case let .iso15693(iso15693Tag) = tag {
|
|
68
|
+
self.handleISO15693Tag(iso15693Tag, session: session, tagInfo: tagInfo)
|
|
69
|
+
} else {
|
|
70
|
+
// Unknown tag type, still return tag info
|
|
71
|
+
session.alertMessage = "Tag detected but no NDEF message found."
|
|
53
72
|
session.invalidate()
|
|
73
|
+
self.onNDEFMessageReceived?([], tagInfo)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private func extractTagInfo(from tag: NFCTag) -> [String: Any] {
|
|
79
|
+
var tagInfo: [String: Any] = [:]
|
|
80
|
+
var techTypes: [String] = []
|
|
81
|
+
var uid: String = ""
|
|
82
|
+
|
|
83
|
+
switch tag {
|
|
84
|
+
case .iso7816(let iso7816Tag):
|
|
85
|
+
uid = iso7816Tag.identifier.map { String(format: "%02X", $0) }.joined()
|
|
86
|
+
techTypes.append("ISO7816")
|
|
87
|
+
tagInfo["type"] = "ISO7816"
|
|
88
|
+
|
|
89
|
+
case .miFare(let miFareTag):
|
|
90
|
+
uid = miFareTag.identifier.map { String(format: "%02X", $0) }.joined()
|
|
91
|
+
techTypes.append("MiFare")
|
|
92
|
+
tagInfo["type"] = "MiFare"
|
|
93
|
+
|
|
94
|
+
case .feliCa(let feliCaTag):
|
|
95
|
+
uid = feliCaTag.currentIDm.map { String(format: "%02X", $0) }.joined()
|
|
96
|
+
techTypes.append("FeliCa")
|
|
97
|
+
tagInfo["type"] = "FeliCa"
|
|
98
|
+
|
|
99
|
+
case .iso15693(let iso15693Tag):
|
|
100
|
+
uid = iso15693Tag.identifier.map { String(format: "%02X", $0) }.joined()
|
|
101
|
+
techTypes.append("ISO15693")
|
|
102
|
+
tagInfo["type"] = "ISO15693"
|
|
103
|
+
|
|
104
|
+
@unknown default:
|
|
105
|
+
techTypes.append("Unknown")
|
|
106
|
+
tagInfo["type"] = "Unknown"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
tagInfo["uid"] = uid
|
|
110
|
+
tagInfo["techTypes"] = techTypes
|
|
111
|
+
|
|
112
|
+
return tagInfo
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private func handleMiFareTag(_ miFareTag: NFCMiFareTag, session: NFCTagReaderSession, tagInfo: [String: Any]) {
|
|
116
|
+
miFareTag.queryNDEFStatus { (ndefStatus: NFCNDEFStatus, capacity: Int, error: Error?) in
|
|
117
|
+
if let error = error {
|
|
118
|
+
session.invalidate(errorMessage: "Unable to query NDEF status of tag.")
|
|
54
119
|
self.onError?(error)
|
|
55
120
|
return
|
|
56
121
|
}
|
|
57
122
|
|
|
58
|
-
|
|
123
|
+
if ndefStatus == .notSupported {
|
|
124
|
+
session.alertMessage = "Tag detected but no NDEF message found."
|
|
125
|
+
session.invalidate()
|
|
126
|
+
self.onNDEFMessageReceived?([], tagInfo)
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
var updatedTagInfo = tagInfo
|
|
131
|
+
updatedTagInfo["maxSize"] = capacity
|
|
132
|
+
updatedTagInfo["isWritable"] = ndefStatus == .readWrite
|
|
133
|
+
|
|
134
|
+
miFareTag.readNDEF { (message: NFCNDEFMessage?, error: Error?) in
|
|
59
135
|
if let error = error {
|
|
60
|
-
session.
|
|
136
|
+
session.invalidate(errorMessage: "Failed to read NDEF from tag.")
|
|
137
|
+
self.onError?(error)
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if let message = message {
|
|
142
|
+
session.alertMessage = "Found 1 NDEF message."
|
|
143
|
+
session.invalidate()
|
|
144
|
+
self.onNDEFMessageReceived?([message], updatedTagInfo)
|
|
145
|
+
} else {
|
|
146
|
+
session.alertMessage = "Tag detected but no NDEF message found."
|
|
61
147
|
session.invalidate()
|
|
148
|
+
self.onNDEFMessageReceived?([], updatedTagInfo)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private func handleISO7816Tag(_ iso7816Tag: NFCISO7816Tag, session: NFCTagReaderSession, tagInfo: [String: Any]) {
|
|
155
|
+
// ISO7816 tags don't typically support NDEF directly
|
|
156
|
+
session.alertMessage = "Tag detected but no NDEF message found."
|
|
157
|
+
session.invalidate()
|
|
158
|
+
self.onNDEFMessageReceived?([], tagInfo)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private func handleFeliCaTag(_ feliCaTag: NFCFeliCaTag, session: NFCTagReaderSession, tagInfo: [String: Any]) {
|
|
162
|
+
feliCaTag.queryNDEFStatus { (ndefStatus: NFCNDEFStatus, capacity: Int, error: Error?) in
|
|
163
|
+
if let error = error {
|
|
164
|
+
session.invalidate(errorMessage: "Unable to query NDEF status of tag.")
|
|
165
|
+
self.onError?(error)
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if ndefStatus == .notSupported {
|
|
170
|
+
session.alertMessage = "Tag detected but no NDEF message found."
|
|
171
|
+
session.invalidate()
|
|
172
|
+
self.onNDEFMessageReceived?([], tagInfo)
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
var updatedTagInfo = tagInfo
|
|
177
|
+
updatedTagInfo["maxSize"] = capacity
|
|
178
|
+
updatedTagInfo["isWritable"] = ndefStatus == .readWrite
|
|
179
|
+
|
|
180
|
+
feliCaTag.readNDEF { (message: NFCNDEFMessage?, error: Error?) in
|
|
181
|
+
if let error = error {
|
|
182
|
+
session.invalidate(errorMessage: "Failed to read NDEF from tag.")
|
|
62
183
|
self.onError?(error)
|
|
63
184
|
return
|
|
64
185
|
}
|
|
65
186
|
|
|
66
|
-
if
|
|
67
|
-
session.alertMessage = "
|
|
187
|
+
if let message = message {
|
|
188
|
+
session.alertMessage = "Found 1 NDEF message."
|
|
68
189
|
session.invalidate()
|
|
190
|
+
self.onNDEFMessageReceived?([message], updatedTagInfo)
|
|
191
|
+
} else {
|
|
192
|
+
session.alertMessage = "Tag detected but no NDEF message found."
|
|
193
|
+
session.invalidate()
|
|
194
|
+
self.onNDEFMessageReceived?([], updatedTagInfo)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private func handleISO15693Tag(_ iso15693Tag: NFCISO15693Tag, session: NFCTagReaderSession, tagInfo: [String: Any]) {
|
|
201
|
+
iso15693Tag.queryNDEFStatus { (ndefStatus: NFCNDEFStatus, capacity: Int, error: Error?) in
|
|
202
|
+
if let error = error {
|
|
203
|
+
session.invalidate(errorMessage: "Unable to query NDEF status of tag.")
|
|
204
|
+
self.onError?(error)
|
|
205
|
+
return
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if ndefStatus == .notSupported {
|
|
209
|
+
session.alertMessage = "Tag detected but no NDEF message found."
|
|
210
|
+
session.invalidate()
|
|
211
|
+
self.onNDEFMessageReceived?([], tagInfo)
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
var updatedTagInfo = tagInfo
|
|
216
|
+
updatedTagInfo["maxSize"] = capacity
|
|
217
|
+
updatedTagInfo["isWritable"] = ndefStatus == .readWrite
|
|
218
|
+
|
|
219
|
+
iso15693Tag.readNDEF { (message: NFCNDEFMessage?, error: Error?) in
|
|
220
|
+
if let error = error {
|
|
221
|
+
session.invalidate(errorMessage: "Failed to read NDEF from tag.")
|
|
222
|
+
self.onError?(error)
|
|
69
223
|
return
|
|
70
224
|
}
|
|
71
225
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if let message = message {
|
|
83
|
-
print("NDEF message read: \(message)")
|
|
84
|
-
statusMessage = "Found 1 NDEF message."
|
|
85
|
-
session.alertMessage = statusMessage
|
|
86
|
-
session.invalidate()
|
|
87
|
-
self.onNDEFMessageReceived?([message])
|
|
88
|
-
} else {
|
|
89
|
-
statusMessage = "No NDEF message found."
|
|
90
|
-
session.alertMessage = statusMessage
|
|
91
|
-
session.invalidate()
|
|
92
|
-
}
|
|
226
|
+
if let message = message {
|
|
227
|
+
session.alertMessage = "Found 1 NDEF message."
|
|
228
|
+
session.invalidate()
|
|
229
|
+
self.onNDEFMessageReceived?([message], updatedTagInfo)
|
|
230
|
+
} else {
|
|
231
|
+
session.alertMessage = "Tag detected but no NDEF message found."
|
|
232
|
+
session.invalidate()
|
|
233
|
+
self.onNDEFMessageReceived?([], updatedTagInfo)
|
|
93
234
|
}
|
|
94
235
|
}
|
|
95
236
|
}
|
|
@@ -48,33 +48,28 @@ import CoreNFC
|
|
|
48
48
|
|
|
49
49
|
session.connect(to: tag) { (error) in
|
|
50
50
|
if let error = error {
|
|
51
|
-
session.
|
|
52
|
-
session.invalidate()
|
|
51
|
+
session.invalidate(errorMessage: "Unable to connect to tag.")
|
|
53
52
|
self.onError?(error)
|
|
54
53
|
return
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
tag.queryNDEFStatus { (ndefStatus, capacity, error) in
|
|
58
57
|
if let error = error {
|
|
59
|
-
session.
|
|
60
|
-
session.invalidate()
|
|
58
|
+
session.invalidate(errorMessage: "Unable to query the NDEF status of tag.")
|
|
61
59
|
self.onError?(error)
|
|
62
60
|
return
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
switch ndefStatus {
|
|
66
64
|
case .notSupported:
|
|
67
|
-
session.
|
|
68
|
-
session.invalidate()
|
|
65
|
+
session.invalidate(errorMessage: "Tag is not NDEF compliant.")
|
|
69
66
|
case .readOnly:
|
|
70
|
-
session.
|
|
71
|
-
session.invalidate()
|
|
67
|
+
session.invalidate(errorMessage: "Tag is read-only.")
|
|
72
68
|
case .readWrite:
|
|
73
69
|
if let message = self.messageToWrite {
|
|
74
70
|
tag.writeNDEF(message) { (error) in
|
|
75
71
|
if let error = error {
|
|
76
|
-
session.
|
|
77
|
-
session.invalidate()
|
|
72
|
+
session.invalidate(errorMessage: "Failed to write NDEF message.")
|
|
78
73
|
self.onError?(error)
|
|
79
74
|
return
|
|
80
75
|
}
|
|
@@ -83,12 +78,10 @@ import CoreNFC
|
|
|
83
78
|
self.onWriteSuccess?()
|
|
84
79
|
}
|
|
85
80
|
} else {
|
|
86
|
-
session.
|
|
87
|
-
session.invalidate()
|
|
81
|
+
session.invalidate(errorMessage: "No message to write.")
|
|
88
82
|
}
|
|
89
83
|
@unknown default:
|
|
90
|
-
session.
|
|
91
|
-
session.invalidate()
|
|
84
|
+
session.invalidate(errorMessage: "Unknown NDEF tag status.")
|
|
92
85
|
}
|
|
93
86
|
}
|
|
94
87
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exxili/capacitor-nfc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "A Capacitor plugin for reading and writing NFC NDEFtags.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -53,13 +53,14 @@
|
|
|
53
53
|
"@ionic/eslint-config": "^0.4.0",
|
|
54
54
|
"@ionic/prettier-config": "^4.0.0",
|
|
55
55
|
"@ionic/swiftlint-config": "^1.1.2",
|
|
56
|
+
"@types/node": "^22.18.8",
|
|
56
57
|
"eslint": "^8.57.0",
|
|
57
58
|
"prettier": "^3.3.3",
|
|
58
59
|
"prettier-plugin-java": "^2.6.4",
|
|
59
60
|
"rimraf": "^3.0.2",
|
|
60
61
|
"rollup": "^2.32.0",
|
|
61
62
|
"swiftlint": "^1.0.1",
|
|
62
|
-
"typescript": "
|
|
63
|
+
"typescript": "^5.9.3"
|
|
63
64
|
},
|
|
64
65
|
"peerDependencies": {
|
|
65
66
|
"@capacitor/core": ">=6.0.0 <9.0.0"
|
|
@@ -78,4 +79,4 @@
|
|
|
78
79
|
"src": "android"
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
|
-
}
|
|
82
|
+
}
|