Problem with reading NFC tag in background in not working with NFC ISO 14443-3A

Hi folks,

I have trouble with reading NFC tag in background while my application is running.

I still receives a message in my iPhone 13, NFC tag of web Open "donator.cz" in application Safari.

But I would like to open the app Donator which is here: https://apps.apple.com/dk/app/don%C3%A1tor/id6473955033

My NFC chip scanned by "NFC Tools" is ISO 14443-3A (NXP-NTAG213) In the tag is mentioned https://donator.cz/%3C8digits-number%3E*%3Ccode%3E*text

In my Info.plist of application is:

	<key>LSApplicationQueriesSchemes</key>
	<array>
		<string>https://donator.cz</string>
	</array>
	<key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
	<array>
		<string>12FC</string>
	</array>
	<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
	<array>
		<string>D2760000850101</string>
	</array>

Apple CDN looks like: https://app-site-association.cdn-apple.com/a/v1/donator.cz

I have read in Apple documentation https://developer.apple.com/documentation/corenfc/adding-support-for-background-tag-reading that application should be in progress A Core NFC reader session is in progress.

How to do it in AppDelegate or SceneDelegate.

One note is that everything works properly in case of reading NFC based on button click is pressed.

My NFCHandler looks like:

//
//  NFCReader.swift
//  Donator
//
//  Created by Petr Hracek on 22.11.2024.
//

import Foundation
import UIKit
import CoreNFC


class NFCHandler: NSObject, NFCNDEFReaderSessionDelegate {
    var readerSession: NFCNDEFReaderSession?
    
    func startBackgroundScanning() {
        
        guard NFCNDEFReaderSession.readingAvailable else {
            return
        }
        readerSession = NFCNDEFReaderSession(delegate: self, queue: DispatchQueue.main, invalidateAfterFirstRead: true)
        readerSession?.alertMessage = "Prilozte NFC tag"
        readerSession?.begin()
        
    }
    
    
    func readTag(session: NFCNDEFReaderSession , tags: [NFCNDEFTag] ) {
        if tags.count > 1 {
            // Restart polling in 500ms
            let retryInterval = DispatchTimeInterval.milliseconds(500)
            session.alertMessage = "More than 1 tag is detected, please remove all tags and try again."
            DispatchQueue.global().asyncAfter(deadline: .now() + retryInterval, execute: {
                session.restartPolling()
            })
            return
        }
        
        // Connect to the found tag and perform NDEF message reading
        let tag = tags.first!
        session.connect(to: tag, completionHandler: { (error: Error?) in
            if nil != error {
                session.alertMessage = "Unable to connect to tag."
                session.invalidate()
                return
            }
            
            tag.queryNDEFStatus(completionHandler: { (ndefStatus: NFCNDEFStatus, capacity: Int, error: Error?) in
                if .notSupported == ndefStatus {
                    session.alertMessage = "Tag is not NDEF compliant"
                    session.invalidate()
                    return
                } else if nil != error {
                    session.alertMessage = "Unable to query NDEF status of tag"
                    session.invalidate()
                    return
                }
                
                tag.readNDEF(completionHandler: { (message: NFCNDEFMessage?, error: Error?) in
                    var statusMessage: String
                    if nil != error || nil == message {
                        statusMessage = "Fail to read NDEF from tag"
                    } else {
                        statusMessage = "Found 1 NDEF message"
                        DispatchQueue.main.async {
                            // Process detected NFCNDEFMessage objects.
                            debugPrint(message!)
                            //self.tableView.reloadData()
                        }
                    }
                    
                    session.alertMessage = statusMessage
                    session.invalidate()
                })
            })
        })
    }
    
    /// - Tag: sessionBecomeActive
   /// This method will called when NFC session become active
   /// Tells the delegate that the session detected NFC tags with NDEF messages.
    func readerSessionDidBecomeActive(_ session: NFCNDEFReaderSession) {
         debugPrint("NFC session become active======")
    }
    
    func readerSessionDidInvalidate(_ session: NFCNDEFReaderSession) {
        debugPrint("NFC session invalidate======")
    }

    func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        print(error)
    }

    func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
        for message in messages {
            for record in message.records {
                print("Type name format: \(record.typeNameFormat)")
                print("Payload: \(record.payload)")
                print("Type: \(record.type)")
                print("Identifier: \(record.identifier)")
            }
        }
    }

    /// - Tag: processingNDEFTag
    /// if This method is not implement then only   func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) will call
    /// Tells the delegate that the session detected NFC tags with NDEF messages and enables read-write capability for the session.
    func readerSession(_ session: NFCNDEFReaderSession, didDetect tags: [NFCNDEFTag]) {
        self.readTag(session: session, tags: tags)
    }
}


Everything is solved. the problem was with apple-app-site-association. It should be really strict. Feel free to close it.

Problem with reading NFC tag in background in not working with NFC ISO 14443-3A
 
 
Q