Integrating NFC into Mobile App

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Integrating NFC into Mobile App
Medium
~2-3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1050
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

NFC Integration in Mobile Applications

NFC in mobile is used for three tasks: reading tags (passports, transit cards, NFC tags), writing to rewritable tags, and peer-to-peer exchange with another device. Platforms implement these modes differently, and iOS historically restricted capabilities significantly more than Android.

iOS: Core NFC and Its Limitations

iOS supports NFC since iPhone 7 (iOS 11), but full NDEF and non-NDEF tag reading appeared only in iOS 13. Tag writing—iOS 13+. Background tag reading (without explicitly starting a session)—iOS 14+.

Key classes: NFCNDEFReaderSession for NDEF tags, NFCTagReaderSession for non-NDEF (ISO 7816, ISO 15693, FeliCa, MIFARE).

import CoreNFC

class NFCManager: NSObject, NFCNDEFReaderSessionDelegate {
    var session: NFCNDEFReaderSession?

    func startReading() {
        guard NFCNDEFReaderSession.readingAvailable else {
            // device doesn't support NFC or NFC is off
            return
        }
        session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true)
        session?.alertMessage = "Hold NFC tag"
        session?.begin()
    }

    func readerSession(_ session: NFCNDEFReaderSession,
                       didDetectNDEFs messages: [NFCNDEFMessage]) {
        for message in messages {
            for record in message.records {
                if record.typeNameFormat == .nfcWellKnown,
                   let type = String(data: record.type, encoding: .utf8),
                   type == "T" {
                    // text record
                    let payload = record.payload
                    // first byte—encoding + lang length, parse manually
                }
            }
        }
    }

    func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        // NFCReaderError.readerSessionInvalidationErrorUserCanceled — user closed
        // NFCReaderError.readerSessionInvalidationErrorSessionTimeout — timeout
    }
}

Writing to Tags

func readerSession(_ session: NFCNDEFReaderSession, didDetect tags: [NFCNDEFTag]) {
    guard let tag = tags.first else { return }
    session.connect(to: tag) { error in
        guard error == nil else { return }
        tag.queryNDEFStatus { status, capacity, error in
            guard status == .readWrite else {
                session.invalidate(errorMessage: "Tag is write-protected")
                return
            }
            let payload = NFCNDEFPayload.wellKnownTypeURIPayload(url: URL(string: "https://example.com")!)!
            let message = NFCNDEFMessage(records: [payload])
            tag.writeNDEF(message) { error in
                session.invalidate(errorMessage: error != nil ? "Write error" : nil)
            }
        }
    }
}

For non-NDEF tags (bank cards ISO 7816, passports), use NFCTagReaderSession with pollingOption: [.iso14443]. Reading passports (ePassport)—through PACE or Basic Access Control with keys from the MRZ line of the document.

Android: NfcAdapter and Foreground Dispatch

Android NFC API is more open. NfcAdapter.getDefaultAdapter(context) checks for NFC presence. enableForegroundDispatch intercepts tags while the app is in foreground.

val nfcAdapter = NfcAdapter.getDefaultAdapter(context)

// In onResume
val intent = Intent(context, activity.javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_MUTABLE)
nfcAdapter.enableForegroundDispatch(activity, pendingIntent, null, null)

// In onNewIntent
fun handleNfcIntent(intent: Intent) {
    val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG) ?: return
    val ndef = Ndef.get(tag)
    if (ndef != null) {
        ndef.connect()
        val message = ndef.ndefMessage
        for (record in message.records) {
            val payload = String(record.payload, Charsets.UTF_8)
        }
        ndef.close()
    }
}

For MIFARE Classic—separate class MifareClassic, requires authentication with key before sector reading. Default key A: {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}. Most transit cards use custom keys.

Typical Issues

iOS session timeout. NFCNDEFReaderSession lives 60 seconds. If the user doesn't hold the tag in time—session closes with error. Show clear instructions and offer to retry.

Conflict with payment apps on Android. If Google Pay is installed and set as default NFC app, enableForegroundDispatch intercepts tags only while the app is active. In background—Google Pay controls.

NFC doesn't work in case. Not a joke—some metal cases shield the antenna. This must be described in usage requirements.

Integration timeline: 2-3 days—NDEF reading; 4-7 days—if writing, non-NDEF, or work with protected tags is needed. Cost is calculated individually.