iOS 11: How to Detect and Read NFC Tags With CoreNFC

0xA1EC
5 min readJun 7, 2017

--

With iOS 11 your iPhone can now read NFC chips

Note: The source code for this project can be found on Github.

iOS 13 Update: Writing to Tags on iOS

It’s finally possible to read and write to NFC Tags on a supporting iOS device! While I don’t go into details in this article, feel free to download my new app, Smart NFC, on the App Store this September 2019 (when iOS 13 is officially launched).

Tags can now be read from, written to, and even locked to prevent future changes. Check out the `NFCNDEFReaderSession` to get started.

While iPhones have been shipping with NFC (Near Field Communication) readers for Apple Pay for three years now, developers have been patiently waiting for access to that little chip. With the release of iOS 11 this fall, Apple has finally delivered this much requested feature to its developers. Luckily, though, we don’t have to wait three months to start playing around with it!

One of iOS 11’s new frameworks is CoreNFC and it is actually pretty simple to set up!

Note: CoreNFC is only supported on the iPhone 7 or iPhone 7 Plus, even though there are other iPhones that have NFC chips inside.

Certificates, Identifiers & Profiles

In order to use an app with the NFC Tag Reading capability, you need to register the App ID on Apple’s Certificates, Identifiers & Profiles webpage. Head on over there and select App IDs under the Identifiers heading.

Go ahead and add an iOS App ID with the same Bundle ID as what you are using in Xcode. You can name the description whatever you’d like. In the App Services section select NFC Tag Reading and click Continue. Finish adding the new App ID and head back over to Xcode to get started!

This step is required regardless of whether or not you will publish this app to the App Store, so don’t skip it!

Getting Started

In my case, I’m going to be making a new project named TestingCoreNFC. Create a new Single View App and name it whatever you want. I am using Swift for this project and skipping out on the Unit Tests. Go ahead and save it wherever, and let’s get started.

Entitlements

In the Project Editor select Capabilities. Turn on any of these and then turn them back off. Why? Because this is the easiest way to add an entitlements file to your application. In my case, it is called TestingCoreNFC.entitlements.

In your entitlements file, add an array with the keycom.apple.developer.nfc.readersession.formats. Add a string inside of the array with the value NDEF.

Now go back to your Project Editor and select the Build Settings tab. Search for Code Signing Entitlements and set its value as the path to your entitlements file.

Info.plist

Open up your Info.plist file and add a new row. Select Privacy — NFC Scan Usage Description as the key and set the value to whatever you want.

Note: The usage description that you set will be shown every time NFC is enabled and will be appended to the text: “Hold iPhone near…”

The Real Fun

Now that we are finished setting up the project, we can get started coding!

Make a new Swift file and name it NFCReader.swift.

The first step in the file is to import the CoreNFC framework.

import CoreNFC

Note: The simulator does not support CoreNFC so you will need to use a device to get this going

Create the class that will contain the actual NFC Reader.

class NFCReader {
}

Set up the class to conform to NFCNDEFReaderSessionDelegate. You will also need to subclass NSObject because the NFC class is actually built on Objective-C.

class NFCReader: NSObject, NFCNDEFReaderSessionDelegate {
}

Add the following two functions to satisfy the protocol:

func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
for message in messages {
for record in message.records {
print("New Record Found:")
print(record.identifier)
print(record.payload)
print(record.type)
print(record.typeNameFormat)
}
}
}
func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
print("NFC NDEF Invalidated")
print("\(error)")
}

These functions account for detections and invalidations respectively. When a code is scanned, the first function will be called. It is set up to print all of the data directly to the debugger. The second function will print out any error that is received while attempting to use the NFC reader.

To pull this all together, add one more function to the NFCReader class:

func beginSession() {
let session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
session.begin()
}

This function is what you will call whenever you want to start searching for NFC chips.

Let’s jump over to the ViewController.swift to pull this all together!

Add a constant to the variables in your class named nfcReader:

let nfcReader = NFCReader()

Add a function to begin a new session in the NFC Reader when the view controller is tapped:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
nfcReader.beginSession()
}

That’s it! Go ahead and run the app on an iPhone 7 or iPhone 7 Plus and give it a try. While it’s running tap the screen and you should see a view pop up from the bottom. Now its time to start scanning things!

You will notice that the screenshot above states, “Hold iPhone near the fire.” That is because I set the usage description for NFC to “…the fire.” Yours should, of course, be different.

Next steps:

Play around with your Main.storyboard and ViewController.swift files and set them to paste the contents of the NFC chip to the screen. This tutorial is the barebones to set up CoreNFC, but I’m leaving it to you to do something unique with it. Let me know what projects you’re working on in the comments, or if you’re running into any troubles!

Don’t forget to 👏 if you loved it!

Note: Remember that this software is still in beta, so it’s likely to change in the coming months!

Note: The source code for this project can be found on Github.

What are you doing with CoreNFC on iOS 11? I’d love to hear from you in the comments, or on Twitter — find me at @_alecoconnor.

--

--

0xA1EC

let meMyselfAndI = [“Husband”, “Disney enthusiast”, “Dog Dad”, “iOS Dev”, “Engineer“, “All-things nerd”]