EddyVerbruggen / nativescript-nfc

:pencil: NativeScript plugin to discover, read, and write NFC tags
MIT License
84 stars 37 forks source link

Callback not executed on iOS 14 and NS 8 #70

Open luffa99 opened 3 years ago

luffa99 commented 3 years ago

Problem: when a NDEF tag is read the callback function set with nfc.setOnNdefDiscoveredListener is not called Expected behaviour: the callback function is called after a tag is read Platform: not working with nativescript 8 on iOS 14 (not tested with other versions). On Android with nativescript 8 works fine.

I've tried to investigate deeper in the library and discovered the critical point: at line 57-58 of nfc.ios.js the callback function should be called. I've tested to print data here, and it works fine, but the callback is not called.

//execute on the main thread with this trick, so UI updates are not broken
Promise.resolve().then(function () { return callback(data); });

Thank you

luffa99 commented 3 years ago

I've fixed by using Utils.executeOnMainThread

So I've changed these lines (in Nfc.prototype.setOnNdefDiscoveredListener )

//execute on the main thread with this trick, so UI updates are not broken
Promise.resolve().then(function () { return callback(data); });

with

//execute on the main thread with this trick, so UI updates are not broken
Utils.executeOnMainThread(() => {
    return callback(data); 
})

Note that you need first to import Utils from nativescript core. Note also that you need to comment out entirely NFCNDEFReaderSessionDelegateImpl.prototype.readerSessionDidDetectTags as described in #67

b8ne commented 2 years ago

@luffa99 Are you able to post exactly how you did this? Was it directly in node_modules or did you pull the files out. I've applied this under node_modules, but getting Nfc is not a constructor errors now, Im assuming from the Utils import.

BenShelton commented 2 years ago

It looks like a PR was opened to fix this but was eventually closed: https://github.com/EddyVerbruggen/nativescript-nfc/pull/71

I'm using patch-package to fix this locally, see here for installation instructions, and then you can add the following patch file in patches/nativescript-nfc+5.0.0.patch:

diff --git a/node_modules/nativescript-nfc/nfc.ios.js b/node_modules/nativescript-nfc/nfc.ios.js
index c55b377..c300242 100644
--- a/node_modules/nativescript-nfc/nfc.ios.js
+++ b/node_modules/nativescript-nfc/nfc.ios.js
@@ -1,6 +1,7 @@
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.Nfc = void 0;
+var core_1 = require("@nativescript/core");
 var nfc_common_1 = require("./nfc.common");
 var Nfc = /** @class */ (function () {
     function Nfc() {
@@ -53,8 +54,9 @@ var Nfc = /** @class */ (function () {
                             JSON.stringify(data));
                     }
                     else {
+                        core_1.Utils.executeOnMainThread(() => callback(data))
                         // execute on the main thread with this trick, so UI updates are not broken
-                        Promise.resolve().then(function () { return callback(data); });
+                        // Promise.resolve().then(function () { return callback(data); });
                     }
                 }, options);
                 _this.session = NFCNDEFReaderSession.alloc().initWithDelegateQueueInvalidateAfterFirstRead(_this.delegate, null, options && options.stopAfterFirstRead);
@@ -125,7 +127,7 @@ var NFCNDEFReaderSessionDelegateImpl = /** @class */ (function (_super) {
         // execute on the main thread with this trick
         this.resultCallback(NFCNDEFReaderSessionDelegateImpl.ndefToJson(firstMessage));
     };
-    NFCNDEFReaderSessionDelegateImpl.prototype.readerSessionDidDetectTags = function (session, tags) {
+    // NFCNDEFReaderSessionDelegateImpl.prototype.readerSessionDidDetectTags = function (session, tags) {
         /*
         // TODO prolly remember the tags for when the app wants to write to it (also: check Android impl for possibly sth similar)
         const nfcNdefTag = tags[0];
@@ -146,7 +148,7 @@ var NFCNDEFReaderSessionDelegateImpl = /** @class */ (function (_super) {
           });
         }
        */
-    };
+    // };
     // Called when the reader session becomes invalid due to the specified error
     NFCNDEFReaderSessionDelegateImpl.prototype.readerSessionDidInvalidateWithError = function (session /* NFCNDEFReaderSession */, error) {
         this._owner.get().invalidateSession();