Why does a Core NFC session end on its own?
Because the system ends it, and says which of five things happened: the first NDEF tag was read, the user cancelled, the session timed out, the system was busy, or it terminated unexpectedly. The session cannot be restarted afterwards, so the app creates a new one.
The five ways it ends
Apple groups them as session errors, and their names say what happened. readerSessionInvalidationErrorFirstNDEFTagRead arrives when a session created to read one tag has read it. readerSessionInvalidationErrorUserCanceled means the user dismissed the sheet. readerSessionInvalidationErrorSessionTimeout means the session timed out. readerSessionInvalidationErrorSystemIsBusy means the system refused it for its own reasons, and readerSessionInvalidationErrorSessionTerminatedUnexpectedly covers the rest.
Only one of them is a bug in your app, and it is usually the first: a session created with invalidateAfterFirstRead set to true when the app meant to keep reading, which the several tags page untangles. The others are the system and the user doing their job.
The timeout with no number
Apple documents the error and not the duration. A session that stays open with nothing in front of it ends by itself, and no value in the reference says when, so an app that reads a long series plans to open a new session rather than assume the first will last.
That silence has a practical consequence: the duration is not something to hardcode from a measurement on one phone and one version. What code can rely on is the error arriving, and what it does then.
What the app does next
A session is single use. Once invalidated it cannot scan again, so the app creates a new one, which Apple's own tag reader sample does after every invalidation. Anything the app was holding from the old session, tags included, is stale.
Say why, when the user can act. invalidate(errorMessage:) ends a session with a message in the system sheet, and alertMessage sets the text during it: those two are the whole vocabulary the app has inside the sheet, which the scan sheet page describes from the user's side. A cancelled session needs no message at all; a busy system deserves a retry rather than an explanation.
What to check before starting one
readingAvailable answers whether the device can read at all, and Apple asks apps to check it before creating a session. readerErrorRadioDisabled exists for a radio that is off, and readerErrorUnsupportedFeature for a feature the session does not support.
And only one reader session runs in the system at a time, so a second one waits: an app that starts a session while another is open has not failed, it is queued, which the session page covers with the rest of the model.
Frequently asked questions
Can I restart an invalidated session?
No. A session is single use: once invalidated it cannot scan again, and the app creates a new one.
How long before a session times out?
Apple's reference gives no duration. Handle the timeout error and open a new session rather than depending on a measured value.
Which invalidation is my fault?
Usually the first NDEF tag read, when the session was created to end after one tag while the app meant to keep reading.
What does system is busy mean?
The system refused the session for its own reasons. Retry once, and tell the user only if it persists.