Environment:
- Device: iPhone 15
- iOS Version: 26.2
- Xcode Version: (add your version)
- Signing: Automatic with Apple Developer account
Problem: When calling NFCTagReaderSession.begin(), the session immediately fails with error code 2: "Missing required entitlement". This happens even though:
- NFCTagReaderSession.readingAvailable returns true
- NFCNDEFReaderSession.readingAvailable returns true
- The session object is created successfully
Configuration verified:
- BonoResidente.entitlements:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.nfc.readersession.formats</key> <array> <string>TAG</string> </array> </dict> </plist>
- Info.plist (relevant keys):
<key>NFCReaderUsageDescription</key> <string>This app needs NFC permission to read transport cards</string> <key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key> <array> <string>D2760000850101</string> </array>
- Apple Developer Portal:
- App ID com.acalvoelorri.BonoResidente has "NFC Tag Reading" capability enabled
- Provisioning profiles were regenerated after enabling the capability
- Xcode:
- "Near Field Communication Tag Reading" capability added via Signing & Capabilities
- CODE_SIGN_ENTITLEMENTS correctly points to the entitlements file
- Automatic signing enabled with valid Development Team
Steps taken:
- Deleted app from device
- Clean Build Folder (Cmd+Shift+K)
- Deleted and re-added the NFC capability in Xcode
- Manually enabled NFC Tag Reading in Apple Developer Portal
- Rebuilt and reinstalled the app
Code: import CoreNFC
class NFCReaderService: NSObject, ObservableObject, NFCTagReaderSessionDelegate { @Published var lastReadData: String = "" @Published var isReading: Bool = false private var session: NFCTagReaderSession?
func startReading() {
guard NFCTagReaderSession.readingAvailable else {
lastReadData = "NFC not available on this device"
return
}
session = NFCTagReaderSession(
pollingOption: [.iso14443, .iso15693, .iso18092],
delegate: self
)
session?.alertMessage = "Hold your transport card near the iPhone"
session?.begin()
isReading = true
}
func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
print("NFC session active")
}
func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
// Error occurs here immediately after begin()
print("Error: \(error)")
}
func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
// Never reached
}
}
Console logs: ========== NFC DEBUG INFO ========== iOS Version: 26.2 Device Model: iPhone Device Name: iPhone System Name: iOS NFCTagReaderSession.readingAvailable: true NFCNDEFReaderSession.readingAvailable: true Bundle ID: com.acalvoelorri.BonoResidente
Creating NFCTagReaderSession with pollingOption: [.iso14443, .iso15693, .iso18092]... Session created: Optional(<NFCTagReaderSession: 0x110fa50e0>) Setting alertMessage... Calling session.begin()... session.begin() completed, isReading = true ========== NFC ERROR DEBUG ========== Full error: Error Domain=NFCError Code=2 "Missing required entitlement" UserInfo={NSLocalizedDescription=Missing required entitlement} Error type: NFCError Localized: Missing required entitlement NSError domain: NFCError NSError code: 2 NSError userInfo: ["NSLocalizedDescription": Missing required entitlement]
Questions:
- Is there a known issue with NFCTagReaderSession entitlements on iOS 26.2?
- Are there additional entitlements required beyond com.apple.developer.nfc.readersession.formats with value TAG?
- How can I verify that the installed app's provisioning profile actually contains the NFC entitlement?
Any help would be appreciated. Thank you.