@capgo/capacitor-nfc 8.0.22 → 8.0.24
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.
|
@@ -4,7 +4,7 @@ import UIKit
|
|
|
4
4
|
|
|
5
5
|
@objc(NfcPlugin)
|
|
6
6
|
public class NfcPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
7
|
-
private let pluginVersion: String = "8.0.
|
|
7
|
+
private let pluginVersion: String = "8.0.24"
|
|
8
8
|
|
|
9
9
|
public let identifier = "NfcPlugin"
|
|
10
10
|
public let jsName = "CapacitorNfc"
|
|
@@ -28,6 +28,12 @@ public class NfcPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
28
28
|
private var currentTag: NFCNDEFTag?
|
|
29
29
|
private var invalidateAfterFirstRead = true
|
|
30
30
|
private var sessionType: String = "ndef"
|
|
31
|
+
private var pendingStartCall: CAPPluginCall?
|
|
32
|
+
private var pendingStartSession: NFCTagReaderSession?
|
|
33
|
+
private var pendingAlertMessage: String?
|
|
34
|
+
private var tagSessionActivated = false
|
|
35
|
+
private var tagSessionTriedFallback = false
|
|
36
|
+
private var tagSessionPollingOptions: NFCTagReaderSession.PollingOption = []
|
|
31
37
|
|
|
32
38
|
private func isSessionAvailable(for type: String) -> Bool {
|
|
33
39
|
if type == "tag" {
|
|
@@ -44,6 +50,9 @@ public class NfcPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
44
50
|
pollingOptions: NFCTagReaderSession.PollingOption,
|
|
45
51
|
alertMessage: String?
|
|
46
52
|
) -> NFCTagReaderSession? {
|
|
53
|
+
tagSessionActivated = false
|
|
54
|
+
tagSessionPollingOptions = pollingOptions
|
|
55
|
+
|
|
47
56
|
guard let session = NFCTagReaderSession(
|
|
48
57
|
pollingOption: pollingOptions,
|
|
49
58
|
delegate: self,
|
|
@@ -56,6 +65,7 @@ public class NfcPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
56
65
|
session.alertMessage = alertMessage
|
|
57
66
|
}
|
|
58
67
|
|
|
68
|
+
tagReaderSession = session
|
|
59
69
|
session.begin()
|
|
60
70
|
return session
|
|
61
71
|
}
|
|
@@ -69,7 +79,10 @@ public class NfcPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
69
79
|
sessionType = requestedSessionType == "tag" ? "tag" : "ndef"
|
|
70
80
|
|
|
71
81
|
guard isSessionAvailable(for: sessionType) else {
|
|
72
|
-
|
|
82
|
+
let message = sessionType == "tag"
|
|
83
|
+
? "NFC tag reading is not available on this device. Ensure the TAG reader entitlement is enabled."
|
|
84
|
+
: "NFC is not available on this device."
|
|
85
|
+
call.reject(message, "NO_NFC")
|
|
73
86
|
return
|
|
74
87
|
}
|
|
75
88
|
|
|
@@ -82,29 +95,37 @@ public class NfcPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
82
95
|
self.ndefReaderSession = nil
|
|
83
96
|
self.tagReaderSession?.invalidate()
|
|
84
97
|
self.tagReaderSession = nil
|
|
98
|
+
self.currentTag = nil
|
|
99
|
+
if let pendingStartCall = self.pendingStartCall, pendingStartCall !== call {
|
|
100
|
+
pendingStartCall.reject("NFC scan was superseded by a new startScanning call.", "CANCELLED")
|
|
101
|
+
}
|
|
102
|
+
self.pendingStartCall = nil
|
|
103
|
+
self.pendingStartSession = nil
|
|
104
|
+
self.pendingAlertMessage = nil
|
|
105
|
+
self.tagSessionTriedFallback = false
|
|
85
106
|
|
|
86
107
|
if self.sessionType == "tag" {
|
|
87
108
|
// Use NFCTagReaderSession for raw tag support
|
|
88
|
-
self.
|
|
109
|
+
self.pendingStartCall = call
|
|
110
|
+
self.pendingAlertMessage = alertMessage
|
|
111
|
+
|
|
112
|
+
let session = self.makeTagReaderSession(
|
|
89
113
|
pollingOptions: [.iso14443, .iso15693, .iso18092],
|
|
90
114
|
alertMessage: alertMessage
|
|
91
115
|
)
|
|
116
|
+
self.pendingStartSession = session
|
|
92
117
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
self.
|
|
96
|
-
pollingOptions: [.iso14443, .iso15693],
|
|
97
|
-
alertMessage: alertMessage
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
guard self.tagReaderSession != nil else {
|
|
118
|
+
guard session != nil else {
|
|
119
|
+
self.pendingStartCall = nil
|
|
120
|
+
self.pendingStartSession = nil
|
|
102
121
|
call.reject(
|
|
103
122
|
"Failed to create NFC tag reader session. Make sure the 'Near Field Communication Tag Reader Session Formats' entitlement includes the 'TAG' format in your app target.",
|
|
104
123
|
"NO_NFC"
|
|
105
124
|
)
|
|
106
125
|
return
|
|
107
126
|
}
|
|
127
|
+
|
|
128
|
+
return
|
|
108
129
|
} else {
|
|
109
130
|
// Use NFCNDEFReaderSession (default behavior)
|
|
110
131
|
self.ndefReaderSession = NFCNDEFReaderSession(
|
|
@@ -169,7 +190,7 @@ public class NfcPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
169
190
|
call.reject("No active NFC session or tag.")
|
|
170
191
|
return
|
|
171
192
|
}
|
|
172
|
-
|
|
193
|
+
|
|
173
194
|
if let ndefSession = ndefReaderSession {
|
|
174
195
|
// For NDEF session, we need to connect to the tag first
|
|
175
196
|
performWrite(message: message, on: tag, session: ndefSession, call: call)
|
|
@@ -513,13 +534,89 @@ extension NfcPlugin: NFCNDEFReaderSessionDelegate {
|
|
|
513
534
|
// MARK: - NFCTagReaderSessionDelegate
|
|
514
535
|
extension NfcPlugin: NFCTagReaderSessionDelegate {
|
|
515
536
|
public func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
|
|
516
|
-
|
|
537
|
+
guard session === tagReaderSession else {
|
|
538
|
+
return
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
tagSessionActivated = true
|
|
542
|
+
|
|
543
|
+
if session === pendingStartSession, let pendingCall = pendingStartCall {
|
|
544
|
+
pendingStartCall = nil
|
|
545
|
+
pendingStartSession = nil
|
|
546
|
+
pendingAlertMessage = nil
|
|
547
|
+
DispatchQueue.main.async {
|
|
548
|
+
pendingCall.resolve()
|
|
549
|
+
}
|
|
550
|
+
}
|
|
517
551
|
}
|
|
518
552
|
|
|
519
553
|
public func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
|
|
520
|
-
currentTag = nil
|
|
521
554
|
let nfcError = error as NSError
|
|
522
|
-
|
|
555
|
+
|
|
556
|
+
if let pendingCall = pendingStartCall {
|
|
557
|
+
guard session === pendingStartSession else {
|
|
558
|
+
return
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
currentTag = nil
|
|
562
|
+
|
|
563
|
+
let canRetryWithoutFeliCa = !tagSessionActivated &&
|
|
564
|
+
tagSessionPollingOptions.contains(.iso18092) &&
|
|
565
|
+
!tagSessionTriedFallback &&
|
|
566
|
+
(nfcError.code == NFCReaderError.readerErrorUnsupportedFeature.rawValue ||
|
|
567
|
+
nfcError.code == NFCReaderError.readerErrorSecurityViolation.rawValue)
|
|
568
|
+
|
|
569
|
+
if canRetryWithoutFeliCa {
|
|
570
|
+
let fallbackAlertMessage = pendingAlertMessage
|
|
571
|
+
tagSessionTriedFallback = true
|
|
572
|
+
tagReaderSession = nil
|
|
573
|
+
pendingStartSession = nil
|
|
574
|
+
|
|
575
|
+
DispatchQueue.main.async {
|
|
576
|
+
guard self.pendingStartCall === pendingCall, self.pendingStartSession == nil else {
|
|
577
|
+
return
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
let fallbackSession = self.makeTagReaderSession(
|
|
581
|
+
pollingOptions: [.iso14443, .iso15693],
|
|
582
|
+
alertMessage: fallbackAlertMessage
|
|
583
|
+
)
|
|
584
|
+
self.pendingStartSession = fallbackSession
|
|
585
|
+
|
|
586
|
+
if fallbackSession == nil {
|
|
587
|
+
self.pendingStartCall = nil
|
|
588
|
+
self.pendingStartSession = nil
|
|
589
|
+
self.pendingAlertMessage = nil
|
|
590
|
+
pendingCall.reject(
|
|
591
|
+
"Failed to start NFC tag session without FeliCa polling: \(error.localizedDescription)",
|
|
592
|
+
"NO_NFC",
|
|
593
|
+
error
|
|
594
|
+
)
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
pendingStartCall = nil
|
|
601
|
+
pendingStartSession = nil
|
|
602
|
+
pendingAlertMessage = nil
|
|
603
|
+
DispatchQueue.main.async {
|
|
604
|
+
pendingCall.reject(
|
|
605
|
+
"Failed to start NFC tag session: \(error.localizedDescription)",
|
|
606
|
+
"NO_NFC",
|
|
607
|
+
error
|
|
608
|
+
)
|
|
609
|
+
}
|
|
610
|
+
tagReaderSession = nil
|
|
611
|
+
return
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
guard session === tagReaderSession else {
|
|
615
|
+
return
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
currentTag = nil
|
|
619
|
+
|
|
523
620
|
// Don't emit state change for normal session completion (user canceled)
|
|
524
621
|
// Also check for successful read completion
|
|
525
622
|
if nfcError.code != NFCReaderError.readerSessionInvalidationErrorUserCanceled.rawValue {
|
|
@@ -540,7 +637,7 @@ extension NfcPlugin: NFCTagReaderSessionDelegate {
|
|
|
540
637
|
session.invalidate(errorMessage: "More than one tag detected. Please present only one tag.")
|
|
541
638
|
return
|
|
542
639
|
}
|
|
543
|
-
|
|
640
|
+
|
|
544
641
|
guard let firstTag = tags.first else {
|
|
545
642
|
return
|
|
546
643
|
}
|
|
@@ -580,7 +677,7 @@ extension NfcPlugin: NFCTagReaderSessionDelegate {
|
|
|
580
677
|
|
|
581
678
|
if error == nil && status != .notSupported {
|
|
582
679
|
// Tag supports NDEF, try to read it
|
|
583
|
-
tag.readNDEF { [weak self] message,
|
|
680
|
+
tag.readNDEF { [weak self] message, _ in
|
|
584
681
|
guard let self else {
|
|
585
682
|
return
|
|
586
683
|
}
|
|
@@ -613,15 +710,15 @@ extension NfcPlugin: NFCTagReaderSessionDelegate {
|
|
|
613
710
|
currentTag = tag
|
|
614
711
|
|
|
615
712
|
var tagInfo: [String: Any] = [:]
|
|
616
|
-
|
|
713
|
+
|
|
617
714
|
// Extract and add the tag ID (UID)
|
|
618
715
|
if let identifierData = extractIdentifier(from: tag) {
|
|
619
716
|
tagInfo["id"] = array(from: identifierData)
|
|
620
717
|
}
|
|
621
|
-
|
|
718
|
+
|
|
622
719
|
tagInfo["techTypes"] = detectTechTypes(for: tag)
|
|
623
720
|
tagInfo["type"] = translateType(for: tag)
|
|
624
|
-
|
|
721
|
+
|
|
625
722
|
// Include writability and capacity information
|
|
626
723
|
if status != .notSupported {
|
|
627
724
|
tagInfo["isWritable"] = status == .readWrite
|
|
@@ -643,9 +740,9 @@ extension NfcPlugin: NFCTagReaderSessionDelegate {
|
|
|
643
740
|
"type": message != nil ? "ndef" : "tag",
|
|
644
741
|
"tag": tagInfo
|
|
645
742
|
]
|
|
646
|
-
|
|
743
|
+
|
|
647
744
|
notify(event: event)
|
|
648
|
-
|
|
745
|
+
|
|
649
746
|
if invalidateAfterFirstRead {
|
|
650
747
|
session.invalidate()
|
|
651
748
|
}
|
package/package.json
CHANGED