React Native NFC Manager not working on IOS after cancelling too quickly

202 Views Asked by At

I'm trying to create a basic NFC reading app with React Native NFC Manager, but I have a problem: When I click on the TouchableOpacity, then close the pop-up (with the cancel button) and open it again too quickly, nothing shows up... is there anything I forgot on the code ? No error is shown... It might be related to the nfc process taking too long... Here is what I wrote:


import React, {useState} from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
import NfcManager, {NfcTech} from 'react-native-nfc-manager';

// Pre-step, call this before any NFC operations
NfcManager.start();

function App() {
  const [loaded, setLoaded] = useState(true);
  async function readNdef() {
    try {
      setLoaded(false);
      // register for the NFC tag with NDEF in it
      await NfcManager.requestTechnology(NfcTech.Ndef);
      // the resolved tag object will contain `ndefMessage` property
      const tag = await NfcManager.getTag();
      console.warn('Tag found', tag);
    } catch (ex) {
      console.warn('Oops!', ex);
    } finally {
      // stop the nfc scanning
      try {
        await NfcManager.cancelTechnologyRequest();
      } catch (ex) {
        console.warn('Error while canceling technology request', ex);
      } finally {
        setLoaded(true);
      }
    }
  }

  return (
    <View style={styles.wrapper}>
      {loaded && (
        <TouchableOpacity onPress={readNdef}>
          <Text style={{color: 'white'}}>Scan a Tag</Text>
        </TouchableOpacity>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default App; 
1

There are 1 best solutions below

0
Pratik Prakash Bindage On

the NFC manager gets started when the component mounts and stopped when it unmounts using the useEffect hook. Additionally, it verifies that the pop-up is loaded before initiating NFC operations to prevent problems in the event that the user quickly opens and shuts the window.

import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import NfcManager, { NfcTech } from 'react-native-nfc-manager';

function App() {
  const [loaded, setLoaded] = useState(true);

  useEffect(() => {
    NfcManager.start();
    return () => {
      NfcManager.stop();
    };
  }, []);

  async function readNdef() 
  {
    try {
      setLoaded(false);
      if (!loaded) 
      {
        return;
      }

      await NfcManager.requestTechnology(NfcTech.Ndef);

      const tag = await NfcManager.getTag();

    } 
    catch (ex) 
    {
      console.warn('Oops!', ex);
    } 
    finally
    {
      try 
      {
        await NfcManager.cancelTechnologyRequest();
      } 
      catch (ex) 
      {
        console.warn('Error while canceling technology request', ex);
      } 
      finally 
      {
        if (!loaded) 
        {
          setLoaded(true);
        }
      }
    }
  }

  return (
    <View style={styles.wrapper}>
      {
        loaded && (
          <TouchableOpacity onPress={readNdef}>
            <Text style={{ color: 'white' }}>Scan a Tag</Text>
          </TouchableOpacity>
        )
      }
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default App;