How to Build an iOS NFC Tag Scanner App With React Native

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the The newline Guide to NFCs with React Native course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to The newline Guide to NFCs with React Native, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course The newline Guide to NFCs with React Native

Hello, in this lesson we will dive into codes. We will show you how to, first, check NFC availability, then scan for NFC tags. Third, implement our game logic. Okay, I have launched our app in iOS simulator. So you can see the template code generated by ReNative CLI is running. Let's get rid of it. Create a src directory and a new app.js inside it. Then write some most basic JSX. Just let everything be centered on the screen and says hello NFC. Then go back to the original index.js and point the app from the original one into the new src/app.js. Then we would like to detect whether the target mobile device has NFC support or not. Let's create a has NFC state. This state has an initial value to be no, which means we are not yet confirmed whether NFC is supported or not. Once we do, this state will be a boolean value true or false. Then we adjust our UI according to this value. Next step is to actually check the NFC availability. By importing the ReNative NFC manager, we can use the is supported API and it will resolve a boolean value to indicate whether the underlying device supports NFC or not. This the availability won't change during the whole app lifecycle. We can do this inside a use effect hook with no dependency. This basically simulates the component-dit mount behavior for ReAdd class component. And please be aware, the is supported API or most of the APIs for a native module is an async function. Because our JavaScript code will need to cross the bridge and ask the corresponding native part for the result. We can see the simulator is refreshed and the result is not supported. Let's run the code on a real iOS device. As you can see, the reason iPhone from iPhone 8 all supports NFC. Once we can confirm the devices that support NFC, we can do the native module initialization by calling the NFC manager.start function. Quick review, we just use the is supported API to check the NFC availability. And if the device supports it, we then call start to initialize our NFC native module. It's time to start our actual game component. Let's quickly a src/game.js by copying the existing code and removing the unnecessary parts. Then use this game component in our app.js when NFC is available. Now we are finally ready to scan NFC tags. First import NFC manager and NFC events from real native NFC manager. Then use set event listener to listen to nsc events.discover tag event. For now, we just log the message to the console. A small trick here is to use console.worn for logging rather than console.log. So we can see the yellow screen UI pop up without enabling debugger. The actual tag scanning is through the registered tag event API. Once it discovers any NFC tags, the native side will emit discover tag event with the tag data to JavaScript side. Okay, let's test it on a real device. Please remember, the NFC container for an iPhone is on the top of the device. So the proper position to scan a tag is probably like this picture. Now let's scan a tag. Cool, that's indeed something happened. We can see once we hit our start button, the iOS and the C prompt pop up. And the icon changed when the tag is scanned. Let's see what's in our warning message there. It's an object which contains a n-depth message property which is an array. The object in this array contains properties such as payload, type, tnf and id. Don't worry about them, we will dip dive into these properties in our next app. Next, let's move the event listener setup and clean up code into an use effect hook. It's about time to write our game logic. The objective of our game is to calculate how much time player needs to scan five NFC tags. The shorter times means a better score. First, create a start state to track whether a player hits start button. And our use effect hook should depend on this start state. And rerun the hook logic when it is changed. Because in such a case, it basically means the user restart the game. Then we use a variable called count inside the closure of our hook to track the remaining count left for a player to scan. Once the count becomes zero, the game is finished. And we should stop the NFC scanning by calling nsc-manager.unregistered tag event. As well as calculate the total elapsed time. And of course, we will have to also render the duration into react elements. Before testing it on a real device, we noticed one thing. That is, during the game playing, the user cannot see any UI updates. Because the iOS default scan UI is on top of our game component. In order to provide user some messages during the game playing, we can use nsc- manager.set-alert-message-is to update iOS NFC scan prompt. Okay, let's do a final test on the real device again. Cool, all works pretty well. By the way, personal best record is about 5 seconds. See if you can beat me. In review, registered tag event is used to start the detection process of our NFC tags. The unregistered tag event is the method to cancel it. Our callback function is passed through the setEventListener function. The event we are looking for is the undiscovered tag event. We can also use setLearnMessage.is to show some visual cue for our users. That's it for the iOS part. In the next lesson, we will move on to Android. [BLANK_AUDIO]