Podcast
Videos
September 6, 2022
Nov 2022
6 Min

Wie man NFC für iOS implementiert

Man hält seine Karte ganz nah an ein Lesegerät und schon ist das Mensa-Essen bezahlt, die Bücher sind ausgeliehen oder die Fahrkarte ist gescannt. Das kennen wir alle. Vergleichsweise neu ist, dass man diese Technologie - Near Field Communication genannt, kurz NFC - auch mit dem iPhone ab Version 7 oder neuer nutzen kann. iOS-Entwickler können diese Funktionalität seit iOS 11 in ihre Apps integrieren. Dafür müssen sie das standardisierte NFC Data Exchange Format (NDEF) einsetzen, auf das Apple seine API für NFC-Tags beschränkt hat und das vom NFC Forum veröffentlicht wurde. Wie man die NFC-Technologie mithilfe von CoreNFC beim Programmieren von Apps nutzt, zeige ich im Folgenden.

Gestaltung der Nutzeroberfläche

Zu Beginn eine gute und eine schlechte Nachricht. Die Schlechte zuerst: Das Lesen von NFC-Tags ist nur mit einem vordefinierten Dialog möglich. Es ist nicht möglich, eine eigene Nutzeroberfläche zur Verfügung zu stellen. Die gute Nachricht: Die Gestaltung des User Interface (UI) ist ziemlich einfach: Das Einzige, was benötigt wird, ist eine kurze Nachricht an den Nutzer, was zu tun ist. Die Sitzung, in der dieser Dialog angezeigt wird, bleibt 60 Sekunden lang aktiv, danach tritt ein Timeout ein und die Sitzung endet automatisch.

Berechtigung

Bevor wir die eigentliche NFC-Funktionalität verwenden können, müssen wir unserer App die Berechtigung dafür erteilen. Dazu wählt man das Projekt im Projektnavigator aus, klickt auf den App-Target und geht zum Capabilities-Tab. Der Screenshot unten zeigt, dass der Schalter neben Near Field Communication Tag Reading auf ON stehen muss. Hierfür unbedingt darauf achten, dass man eine dedizierte App-ID hat! Wildcards funktionieren nicht.

Nachdem wir die Fähigkeit aktiviert haben, erweitern wir unsere info.plist um den Eintrag Privacy - NFC Scan Usage Description. Als Wert muss diesem Eintrag eine detaillierte Erläuterung hinzugefügt werden, die dem Benutzer erklärt, warum wir NFC verwenden.

Los geht's!

Sobald alles wie beschrieben konfiguriert ist, können wir anfangen zu implementieren. Die NFC-Funktionalität ist in der NFCNDEFReaderSession implementiert. Um diese Session nutzen zu können, importieren wir das CoreNFC-Framework, wie am Anfang des folgenden Code-Snippets zu sehen ist.

//
//  ViewController.swift
//  NFC-Sample
//
//  Created by Jens on 08.05.18.
//  Copyright © 2018 Jamit Labs. All rights reserved.
//

import CoreNFC
import UIKit

class ViewController: UITableViewController {
   ...
}

Bevor wir NFCNDEFReaderSession mit der Funktion begin starten können, müssen wir das entsprechende NFCNDEFReaderSessionDelegate implementieren. Letzteres stellt Callback-Funktionen für erkannte Nachrichten und Fehler bereit, wenn etwas schiefgelaufen ist. Die beiden benötigten Funktionen sieht man im folgenden Snippet.

extension ViewController: NFCNDEFReaderSessionDelegate {
   func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
       ...
   }

   func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
       ...
   }
}

Das wäre erledigt. Jetzt gehen wir weiter zum nächsten Code Snippet und konzentrieren uns auf die Funktion addButtonTriggered: Diese erstellt eine neue NFCNDEFReaderSession mit unserem ViewController als Delegate. Wir verwenden keine Queue, also können wir nil als Parameter angeben und invalidateAfterFirstRead auf true setzen. Dieses Attribut kann nützlich sein, wenn wir mehr als einen Tag scannen wollen, bevor der Benutzer die Sitzung beendet oder das 60-Sekunden-Timeout eintritt.Zudem setzen wir auf die alertMessage-Property, die Nachricht, die dem Benutzer anschließend im Dialogfenster angezeigt werden soll.

//
//  ViewController.swift
//  nfc-test
//
//  Created by Jens on 08.05.18.
//  Copyright © 2018 Jamit Labs. All rights reserved.
//

import CoreNFC
import UIKit

class ViewController: UITableViewController {

   override func viewDidLoad() {
       super.viewDidLoad()
   }

   override func didReceiveMemoryWarning() {
       super.didReceiveMemoryWarning()
   }

   @IBAction func addButtonTriggered(_ sender: UIBarButtonItem) {
       let session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true)
       session.alertMessage = "Hey user hold this iPhone near to a NFC-Tag"
       session.begin()
   }
}

extension ViewController: NFCNDEFReaderSessionDelegate {
   func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
       // Handle errors
   }

   func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
       guard let message = messages.first, let record = message.records.first else { return }

       // Handle your payload here
       ...
   }
}

Mit der begonnenen Sitzung können wir unsere ersten NFC-Tags scannen. Mit jedem gescannten Tag wird die Delegate-Funktion readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) aufgerufen. Dadurch erhalten wir ein Array von Messages, wobei jede Message wiederum ein Array von Records enthält (die Payload der Message). Jeder Record kann entweder verschiedene Daten liefern oder aber zusammenhängende Daten enthalten, die als Chunks gespeichert sind. Wie in der ersten Zeile der Delegate-Funktion zu sehen ist, behandeln wir der Einfachheit halber nur den einzelnen Record.

Der Record kann mehrere Arten von Inhalten enthalten, z.B. einfachen Text oder einen vordefinierten URI-Inhalt. Die Property type des Records beschreibt den Payload-Typ in einem einzigen Zeichen: 'T' für Text und 'U' für URI. Die URI-Payload hat ein vordefiniertes Format. Diese Payload muss mit einem einzelnen Byte beginnen, dass das Protokoll der URI bereitstellt. Ein http:// URI beginnt beispielsweise mit dem Bytewert 0x03. Diese Identifikatoren werden vom NFC Forum, wie zuvor beschrieben, veröffentlicht. Eine vollständige Liste aller Werte und weitere Informationen findet man unter Adafruit - Über das NDEF Format.

Wenn ein Fehler auftritt, wird die Delegate-Funktion didInvalidateWithError aufgerufen. Ein typischer Fehler ist zum Beispiel das 60-Sekunden-Timeout. In dem Fall, dass der Benutzer eine Scan-Session abbricht, wird das Delegate mit dem Fehler vom Typ readerSessionInvalidationErrorUserCanceled aufgerufen.

Im folgenden Bild sieht man den Dialog, den der Nutzer sieht, wenn er die Sitzung startet.

Das war schon alles, jetzt kannst du deine NFC-Tags auslesen!

Fazit

Wie wir gesehen haben, ist das Scannen eines NFC-Tags in iOS sehr einfach. Leider gibt es einige Einschränkungen, da nur Tags im NDEF-Format erkannt werden. Das Scannen wird durch ein Session-Design entkoppelt und um ein von Apple bereitgestelltes Dialogfenster vervollständigt. Uns bleibt lediglich die Möglichkeit, eine Nachricht zu definieren, die dem Benutzer angezeigt wird.
Selbst das Parsen eines Datensatzes geht durch die Verwendung des standardisierten Formates leicht von der Hand.

In Zukunft wird Apple hoffentlich noch weitere Funktionen, wie das Scannen von RFID-Tags oder das Beschreiben von NFC-Tags anbieten, wie es bei Android schon seit Jahren üblich ist.

Übrigens: Mit den neuen iPhones kann man NFC auch im Hintergrund scannen. Was dazu beim Programmieren zu beachten ist, verraten wir demnächst in einem weiteren Blogbeitrag.

Andreas Link
Andreas Link
Anh Dung Pham
Anh Dung Pham
Cihat Gündüz
Cihat Gündüz
Andreas Link
Ekrem Sentürk
Eva Maria Stock
Eva-Marie Stock
Andreas Link
Giulia Maier
Inken Marei Kolthoff
Inken Marei Kolthoff
Janina Baumann
Janina Baumann
Janina Bokeloh
Janina Bokeloh
Jeanette Schmidt
Jeanette Schmidt
Jens Krug
Jens Krug
Kajorn Pathomkeerati
Kajorn Pathomkeerati
Karl Barth
Karl Barth
Kay Dollt
Kay Dollt
Murat Yilmaz
Murat Yilmaz
Thorsten Hack
Thorsten Hack
Thorsten Hack
Thorsten Hack
Inken Marei Kolthoff
Cynthia Murat
Inhaltsverzeichnis

Weitere Artikel

Mitarbeiter-Interview mit Simon
Janina Baumann
26.11.2022
3 Min

Mitarbeiter-Interview mit Simon

Simon gehört bereits etwas länger zu Jamit Labs und hat in dieser Zeit schon so ziemlich alle Anstellungsarten durchlaufen:

Artikel lesen
Android - Bilder für unterschiedliche Pixeldichten anlegen
Inken Marei Kolthoff
26.11.2022
3 Min

Android - Bilder für unterschiedliche Pixeldichten anlegen

Android läuft auf den unterschiedlichsten Geräten, deren Screengrößen und Pixeldichten stark variieren.

Artikel lesen
Bitrise CI für iOS optimal nutzen - Basics
Cihat Gündüz
26.11.2022
12 Min

Bitrise CI für iOS optimal nutzen - Basics

Bitrise ist zwar ein relativ junges Unternehmen im Bereich der Continuous Integration Services, hat sich aber von Anfang an auf mobile Apps konzentriert.

Artikel lesen

Jetzt kostenloses Strategiegespräch sichern!

Die Beratungen sind grundsätzlich schnell ausgebucht, deshalb fülle jetzt in 2 Minuten das kurze Formular aus.

Jetzt Strategiegespräch sichern