I am using react-native-nfc-manager to read nfc tags in ios. I have to read tags every time app discovers a tag, it works fine. However, after some time (about a minute) nfc session is auto closed and app stops reading the tags, to make it work again I have to manually start the session. How can I keep session active as long as I want .
import { FlatList, Pressable, StyleSheet, Text, View } from "react-native";
import React, { useEffect, useState } from "react";
import NfcManager, {
Ndef,
NfcAdapter,
NfcEvents,
NfcTech,
} from "react-native-nfc-manager";
import AppButton from "@/components/AppButton";
import Animated, { SlideInLeft } from "react-native-reanimated";
NfcManager.start({
onSessionClosedIOS: () => {
console.log("ios session closed");
},
})
.then((result) => {
console.log("start OK", result);
})
.catch((error) => {
console.warn("device does not support nfc!");
});
const Item = ({ title }) => {
return (
<Animated.View
entering={SlideInLeft.duration(300)}
style={{
backgroundColor: "lightgreen",
marginVertical: 4,
padding: 12,
borderRadius: 2,
borderLeftWidth: 4,
}}
>
<Animated.Text
entering={SlideInLeft.duration(100)}
style={{ fontSize: 16 }}
>
{title}
</Animated.Text>
</Animated.View>
);
};
const Page = () => {
const [tags, setTags] = useState([]);
const [nfcState, setNfcState] = useState(null);
const [nfcSupport, setNfcSupport] = useState(null);
console.log(tags);
const processNfcTag = (tag) => {
if (tag.ndefMessage) {
const ndefMessage = tag.ndefMessage[0]; // Assuming only one NDEF record
const text = Ndef.text.decodePayload(ndefMessage.payload);
// Use the decoded text
console.log("Decoded Text:", text);
setTags((pre) => {
return [...pre, { id: pre.length, tag: text }];
});
} else {
}
};
useEffect(() => {
NfcManager.setEventListener(NfcEvents.DiscoverTag, (tag) => {
console.log("tag found", tag.ndefMessage);
// let text = "";
// for (let i = 0; i < tag.ndefMessage[0].payload.length; i++) {
// if (i <= 2) continue;
// text = text + String.fromCharCode(tag.ndefMessage[0].payload[i]);
// }
// setTags((pre) => {
// return [...pre, { id: pre.length, tag: text }];
// });
processNfcTag(tag);
});
return () => {
NfcManager.setEventListener(NfcEvents.DiscoverTag, null);
};
}, []);
useEffect(() => {
const checkNfcState = async () => {
const _nfcSupport = await NfcManager.isSupported();
setNfcSupport(_nfcSupport);
const _nfcState = await NfcManager.isEnabled();
setNfcState(_nfcState);
console.log(_nfcState, "nfcState");
console.log(_nfcSupport, "nfcSupport");
};
checkNfcState();
}, []);
const readTag = async () => {
try {
const isActive = await NfcManager.isSessionAvailableIOS();
// const isTagSessionActive = await NfcManager.isTagSessionAvailableIOS();
console.log(isActive, "is session available");
// console.log(isTagSessionActive, "isTagSessionActive");
if (isActive) {
return; //find a way to terminate the current session and the start new
}
await NfcManager.registerTagEvent({
invalidateAfterFirstRead: false,
isReaderModeEnabled: true,
readerModeFlags:
NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
});
} catch (error) {
console.log(error);
}
};
if (nfcSupport === null || nfcState === null) {
return;
} else if (!nfcSupport) {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text> Your device does not support NFC</Text>
</View>
);
} else if (!nfcState) {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text> NFC is off</Text>
</View>
);
}
return (
<View style={{ padding: 16, gap: 12 }}>
<AppButton
style={{
backgroundColor: "orange",
alignSelf: "center",
width: 100,
}}
title="Start"
textColor="#111"
onPress={readTag}
/>
<FlatList
data={tags}
keyExtractor={(item) => item.id + "_key"}
renderItem={({ item }) => <Item title={item?.tag} />}
/>
</View>
);
};
export default Page;
const styles = StyleSheet.create({});
I want to keep session active as long as I want.