preface

The word “NFC” is no stranger to the world. Some time ago, Beijing metro’s support for NFC payment made headlines. In fact, from the end of the 1990s to the beginning of 2000, TWO-DIMENSIONAL code and NFC have been born one after another. Because of its low cost and relatively low technical threshold, two-dimensional code quickly occupied the mobile payment market, but the development of NFC did not stop. The development of NFC on Android has been very rapid, but unfortunately Apple has not opened the interface. At this year’s WWDC, Apple announced the opening of its NFC interface CoreNFC, which provides more possibilities for future NFC applications.

The body of the

If you are still unfamiliar with NFC technology, here is a popular knowledge: NFC (Near Field Communication), when two devices are close to each other, information can be exchanged. Many companies put NFC chips in cards, and use cards with NFC chips to grant access to who will be allowed access to, say, the company. Apple CoreNFC currently supports limited formats, NFC Data interchange format or NDEF (commonly used on most tablets and phones on the market today), such as Apple Pay.

CoreNFC Demo

Here we demonstrate how to use CoreNFC with a simple example program that can be used to read information stored in NDEF format on a card.





working-scanner.png

For this, I paired the Adafruit PN532 Shield with an Arduino Uno and sent it to a sample NDEF format card. If you don’t have these things, or don’t want to invest time and money in such hardware, try to find a pre-formatted card with information. In this article, I won’t demonstrate NFC formatting and how to store data into an NDEF card.

Getting Started

Open Xcode 9 to create a simple Swift project. Create simple pages using Storyboard:





ViewController as follows:

import UIKit
 
class ViewController: UIViewController {
 
    @IBOutlet weak var messageLabel: UILabel!
 
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
 
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
 
    @IBAction func scanPressed(_ sender: Any) {
        // this is our newly created IBAction
    }
 
}
Copy the code

Entitlements & Privacy

In order to use NFC, our app must be authorized: the premise is that you must have a valid Apple ID (paid protection fee). For application authorization and privacy Settings, go to developer.apple.com. Log in to your account, create a certificate — sign up for a new APP ID. App instructions should support NFC click Next and make sure your confirmation page looks like this:





Then create the Provisioning Profile:





This step is complete. Import the certificate and description file in the project we just created. After that, we need to configure info.plist.





And with that, our work is done. 👇 We enter the coding phase.

Core NFC

To implement NFC functionality, we need to access the Core NFC framework:

import CoreNFC 

Copy the code

CoreNFC is not currently supported in the iOS emulator. This means that if you try to import CoreNFC, you will receive an error indicating that there is no module named CoreNFC. In this case, select your iPhone or Generic iOS Device. Next we realize NFCNDEFReaderSessionDelegate protocol:

import UIKit
import CoreNFC 

class ViewController: UIViewController, NFCNDEFReaderSessionDelegate { 

    @IBOutlet weak var messageLabel: UILabel!
    var nfcSession: NFCNDEFReaderSession?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func scanPressed(_ sender: Any) {

    }

    func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        print("The session was invalidated: \(error.localizedDescription)")
    }

    func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
        // Parse the card's information
    }
}
Copy the code

The two readerSession functions tell us whether the NFC session succeeded or failed, and return NFCNDEFMessage communication data on success and error on failure. Of course, we also need to initialize NFCNDEFReaderSession and enable NFC listening first.

@IBAction func scanPressed(_ sender: Any) { nfcSession = NFCNDEFReaderSession.init(delegate: self, queue: nil, invalidateAfterFirstRead: true) nfcSession? .begin() }Copy the code

Then run the program and see:





If the message “Session is invalidated” is displayed, carefully check whether the certificate, description file, and Privacy Settings are correct. This process is not difficult and can be done in a few simple steps. Let’s look at how to parse the received message.

Parsing the Message

First, let’s look at this function:

func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) 
Copy the code

Let’s look at what each message object contains:

print(messages[0])
Copy the code

We can see:

( // Payload one (There's only one payload in this card)
    "TNF=1, /* Type Name Format */
    Payload Type=<55>,
    Payload ID=<>,
    Payload=<0048656c 6c6f21>" /* What we're really interested in */
)
Copy the code

Messages is an array of NFCNDEFMessages objects. NFCNDEFMessage has an array of records for NFCNDEFPayload objects.

  1. identifier.
  2. type.
  3. typeNameFormat.
  4. payload.

So we’re really only interested in payload. Ok, let’s see how to parse records.

func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
    var result = ""
    for payload in messages[0].records {
        result += String.init(data: payload.payload.advanced(by: 3), encoding: .utf8)! // 1
    }

    DispatchQueue.main.async {
        self.messageLabel.text = result
    }
}
Copy the code

Here’s the final result:





nice result

reference

Working with CoreNFC in iOS 11