9#include <QtCore/qscopeguard.h>
10#include <QtCore/qbytearray.h>
11#include <QtCore/qstring.h>
12#include <QtCore/qdebug.h>
18dispatch_queue_t qt_Nfc_Queue()
20 static dispatch_queue_t nfcQueue = []{
21 auto queue = dispatch_queue_create(
"qt-NFC-queue", DISPATCH_QUEUE_SERIAL);
23 qCWarning(QT_IOS_NFC,
"Failed to create the QtNfc's dispatch queue");
26 static const auto queueGuard = qScopeGuard([]{
28 dispatch_release(nfcQueue);
37@implementation QIosNfcNdefSessionDelegate
39 std::unique_ptr<QNfcNdefNotifier> notifier;
41 NFCNDEFStatus tagStatus;
43 QNearFieldTarget::RequestId requestId;
46-(instancetype)initWithNotifier:(QNfcNdefNotifier *)aNotifier
50 if (self = [super init]) {
51 auto queue = qt_Nfc_Queue();
55 tagStatus = NFCNDEFStatusNotSupported;
57 notifier.reset(aNotifier);
69-(QNfcNdefNotifier *)ndefNotifier
71 return notifier.get();
76 notifier.reset(
nullptr);
85 auto queue = qt_Nfc_Queue();
87 self.session = [[NFCNDEFReaderSession alloc] initWithDelegate:self queue:queue invalidateAfterFirstRead:NO];
88 if (alertMessage.size())
89 self.session.alertMessage = alertMessage.toNSString();
94 qCDebug(QT_IOS_NFC,
"Starting NFC NDEF reader session");
95 [self.session beginSession];
104 tagStatus = NFCNDEFStatusNotSupported;
108-(
void)stopSession:(
const QString &)message
113 if (self.ndefTag && notifier.get())
114 emit notifier->tagLost(self.ndefTag);
117 [self.session invalidateSessionWithErrorMessage:message.toNSString()];
119 [self.session invalidateSession];
124-(
void)setAlertMessage:(
const QString &)message
126 alertMessage = message;
129-(
void)readerSession:(NFCNDEFReaderSession *)session
130 didInvalidateWithError:(NSError *)error
132 if (session != self.session)
138 NSLog(@
"session did invalidate with error %@", error);
140 if (error.code != NFCReaderSessionInvalidationErrorUserCanceled && error.code != NFCReaderErrorUnsupportedFeature) {
142 emit notifier->tagError(QNearFieldTarget::TimeoutError, {});
144 emit notifier->invalidateWithError(
true);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
192-(
void)readerSession:(NFCNDEFReaderSession *)session
193 didDetectNDEFs:(NSArray<NFCNDEFMessage *> *)messages
207 auto queue = qt_Nfc_Queue();
210 dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
211 int64_t(100./1000. * NSEC_PER_SEC)),
214 [self.session restartPolling];
218-(
void)tag:(id<NFCNDEFTag>)tag didUpdateNDEFStatus:(NFCNDEFStatus)status
219 capacity:(NSUInteger)aCapacity error:(NSError *)error
224 if (tag != self.ndefTag)
228 NSLog(@
"Querying NDEF tag's status failed: %@, restarting polling ...", error);
230 return [self restartPolling];
234 capacity = aCapacity;
236 if (status == NFCNDEFStatusNotSupported) {
237 qCDebug(QT_IOS_NFC,
"The discovered tag does not support NDEF.");
238 return [self restartPolling];
241 if (status == NFCNDEFStatusReadWrite)
242 qCDebug(QT_IOS_NFC,
"NDEF read/write capable tag found");
244 if (status == NFCNDEFStatusReadOnly)
245 qCDebug(QT_IOS_NFC,
"The discovered tag is read only");
247 qCInfo(QT_IOS_NFC) <<
"The max message size for the tag is:" << capacity;
249 [self.session connectToTag:self.ndefTag completionHandler:^(NSError *
_Nullable error) {
252 emit notifier->tagDetected(self.ndefTag);
254 NSLog(@
"Failed to connect to NDEF-capable tag, error: %@", error);
255 [self restartPolling];
261-(
void)readerSession:(NFCNDEFReaderSession *)session
262 didDetectTags:(NSArray<__kindof id<NFCNDEFTag>> *)tags
267 if (session != self.session)
270 if (tags.count != 1) {
271 qCWarning(QT_IOS_NFC,
"Unexpected number of NDEF tags, restarting ...");
272 [self restartPolling];
276 NSLog(@
"detected a tag! %@", tags[0]);
278 id<NFCNDEFTag> tag = tags[0];
280 tagStatus = NFCNDEFStatusNotSupported;
283 [self.ndefTag queryNDEFStatusWithCompletionHandler:
284 ^(NFCNDEFStatus status, NSUInteger aCapacity, NSError *
_Nullable error) {
285 [self tag:tag didUpdateNDEFStatus:status capacity:aCapacity error:error];
289-(
void)readerSessionDidBecomeActive:(NFCNDEFReaderSession *)session
291 if (session != self.session)
292 return [session invalidateSession];
294 qCInfo(QT_IOS_NFC,
"session is active now");