EddyVerbruggen / nativescript-nfc

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

iOS app crashes - hexToDec / hex.toLowerCase - HEX data issue? #32

Closed sylwesterdigital closed 5 years ago

sylwesterdigital commented 5 years ago

Hi! My iOS app built with nativescript vuejs template crashes, this is last bit of log:

CONSOLE LOG file:///app/bundle.js:185:18: 'listenNFC()'
CONSOLE LOG 'lastNdefDiscovered' 'Listening...'
***** Fatal JavaScript exception - application has been terminated. *****
Native stack trace:
1   0x10553bf84 NativeScript::reportFatalErrorBeforeShutdown(JSC::ExecState*, JSC::Exception*, bool, bool)
2   0x105568fdc NativeScript::FFICallback<NativeScript::ObjCMethodCallback>::ffiClosureCallback(ffi_cif*, void*, void**, void*)
3   0x106041578 ffi_closure_SYSV_inner
4   0x1060441b4 .Ldo_closure
5   0x182690b24 <redacted>
6   0x182690ae4 <redacted>
7   0x18269aa38 <redacted>
8   0x18269b380 <redacted>
9   0x18269bd4c <redacted>
10  0x1826a411c <redacted>
11  0x1829c3e70 _pthread_wqthread
12  0x1829c3b08 start_wqthread
JavaScript stack trace:
1   hexToDec@file:///app/vendor.js:6715:14
2   recordToJSON@file:///app/vendor.js:6686:36
3   messageToJSON@file:///app/vendor.js:6675:36
4   ndefToJson@file:///app/vendor.js:6667:34
5   readerSessionDidDetectNDEFs@file:///app/vendor.js:6651:40
6   UIApplicationMain@[native code]
7   _start@file:///app/vendor.js:21621:22
8   run@file:///app/vendor.js:21663:9
9   $start@file:///app/vendor.js:20923:18
10  $start@file:///app/vendor.js:7411:25
11  @file:///app/bundle.js:470:10
12  ./main.js@file:///app/bundle.js:474:34
13  __webpack_require__@file:///app/bundle.js:76:34
14  checkDeferredModules@file:///app/bundle.js:45:42
15  @file:///app/bundle.js:149:38
16  anonymous@file:///app/bundle.js:150:12
17  evaluate@[native code]
18  moduleEvaluation@[native code]
19  promiseReactionJob@[native code]
20  require@[native code]
21  anonymous@file:///app/starter.js:2:8
22  evaluate@[native code]
23  moduleEvaluation@[native code]
24  promiseReactionJob@[native code]
JavaScript error:
file:///app/vendor.js:6715:14: JS ERROR TypeError: undefined is not an object (evaluating 'hex.toLowerCase')

and this is template App.vue component:

<template>
    <Page>
        <ActionBar title="Welcome to NativeScript-Vue!"/>
        <GridLayout columns="*" rows="*,*">
            <Button class="message" :text="msg1" col="0" row="0" @tap="onButtonTap"/>
            <Button class="message" :text="msg2" col="0" row="1" @tap="enableNFC"/>
        </GridLayout>
    </Page>
</template>

<script >
const Nfc = require("nativescript-nfc").Nfc;
const nfc = new Nfc();

export default {

    data() {
      return {
        msg1: 'Available?',
        msg2: 'Enable',
        appNFC: nfc  
      }
    },

     methods: {
         listenNFC: function() {
             console.log('listenNFC()')
            this.appNFC.setOnNdefDiscoveredListener((data) => {
              if (data.message) {
                let tagMessages = [];
                // data.message is an array of records, so:
                data.message.forEach(record => {
                  console.log("Read record: " + JSON.stringify(record));
                  tagMessages.push(record.payloadAsString);
                });
                console.log("lastNdefDiscovered", "Read: " + tagMessages.join(", "));
              }
            }, {
              stopAfterFirstRead: true,
              scanHint: "Scan a tag, baby!"
            })
                .then(() => console.log("lastNdefDiscovered", "Listening..."))
                .catch(err => alert(err));
         },
         onButtonTap: function(e) {
            this.appNFC.available()
                .then(avail => console.log(avail ? "Available" : "Not Available"));          
         },
        enableNFC: function() {
            this.appNFC.enabled()
                .then(on => console.log('on:',on))
                .catch(err => console.log("error:", err.message))
                .finally(() => this.listenNFC() )
            //this.listenNFC();
        }
     }
  }
</script>

Not sure what is the problem with hexToDec and then hex.toLowerCase, is it because my tag contains non-standard record maybe? I am guessing this case when I tried to read this tag with other apps it saying 'error data' or not displaying anything... but other native apps from Apple Store at least do not crash badly like mine.

evaluating 'hex.toLowerCase'

My knowledge of NFC data payload is tiny. What I've done and it's not crashing the app, I went to nativescript-nfc/nfc.ios.js and commented this bit o code

    NFCNDEFReaderSessionDelegateImpl.prototype.hexToDec = function (hex) {
        //let result = 'Dupa';
        var result = 0, digitValue;
//      
//      console.log('HEX??', hex)
//      
//        hex = hex.toLowerCase();
//        for (var i = 0; i < hex.length; i++) {
//            digitValue = '0123456789abcdefgh'.indexOf(hex[i]);
//            result = result * 16 + digitValue;
//        }
        return result;
    };

Now my app does not crash and the result is

{"tnf":0,"type":0,"id":"[]","payload":"[]","payloadAsHexString":"","payloadAsStringWithPrefix":"","payloadAsString":""}'

So it looks like hexToDec function needs some extra tweaks. Also I have found interesting article regarding NFC, would be great at some point to implement some solutions like this https://medium.com/@vinceyuan/reading-and-parsing-nfc-tag-on-ios-11-60f4bc7a11ea - anyways any help, much appreciated.

EddyVerbruggen commented 5 years ago

Yeah, I guess that value is not OK, and therefore NativeScript gets an undefined hex value from the iOS SDK. Let's no longer attempt to lowercase that ;)

Update to 3.0.2 please. Available from npm rn.