revtel / react-native-nfc-manager

React Native NFC module for Android & iOS
MIT License
1.32k stars 312 forks source link

Session sometimes closes itself #721

Open pke opened 2 months ago

pke commented 2 months ago

I recon on iOS (Android not tested) an open scan session sometimes closes itself. This means the iOS bottom sheet that displays the alert messages is closed and there is no more active session. Is this a default timeout somewhere (it seems to be around 20 secs)?

The NfcEvents.SessionClosed event listener reports "Unexpected" error.

The phones log reads as follow:

default 02:41:00.789854+0200    app -[NFCTagReaderSession beginSession]:363
default 02:41:00.790369+0200    nfcd    -[_NFHardwareManager queueReaderSession:sessionConfig:completion:]:4565 app, type:TagReader
default 02:41:00.792910+0200    nfcd    -[_NFHardwareManager regularSessionsAllowed:clientName:]:2426 Checking for _NFReaderSession session for app
default 02:41:00.841800+0200    nfcd    -[_NFReaderSession didStartSession:]:270 app (37785) started _NFReaderSession-736908060.790245 ID:0
default 02:41:00.841976+0200    nfcd    -[_NFReaderSession _sync_startPollingForTags:sessionConfig:completion:]:1244 app (37785) _NFReaderSession-736908060.790245
default 02:41:00.872009+0200    app NFCTag didBecomeActive
default 02:41:00.920964+0200    app -[NFCTagReaderSession didDetectTags:connectedTagIndex:]:247 Current connectedTag: None
default 02:41:00.921000+0200    app -[NFCTagReaderSession didDetectTags:connectedTagIndex:]:251 ConnectedTag[0]: <private>
default 02:41:00.921035+0200    app NFCTag didDetectTags
error   02:41:01.796395+0200    app -[NFCTagReaderSession setAlertMessage:]:101 (null)
default 02:41:21.384696+0200    nfcd    -[_NFReaderSession didEndSession:]:248 app (37785) ended _NFReaderSession-736908060.790245
default 02:41:21.385113+0200    app -[NFCTagReaderSession didTerminate:]:205 sessionState=4, proxy=YES, error=Error Domain=nfcd Code=47 UserInfo={NSLocalizedDescription=<private>}
default 02:41:21.513302+0200    powerd  Process nfcd.60 SessionEnded PreventUserIdleSystemSleep "nfcd[process:app,pid:37785,_NFReaderSession,sessionID:0]" age:00:00:20  id:4295008933 [System: PrevIdle SysAct]
giuliobracci commented 1 month ago

Hi @pke, as I recon, there's no way on iOS to set that timeout, but the timeout is treated as an NfcError, so you can check against it when you receive an error. By the way, I've not used the library with its listeners but with only more imperative solutions due the kind of app I'm developing, but I think that you can listen for NfcErrors.

Here's an example of how I've implemented it.

try {
  // Modal should appear
  await NfcManager.requestTechnology(NfcTech.Ndef, {
    alertMessage: t('holdYourPhone')
  });
} catch (err) {
  if (err instanceof NfcError.Timeout) {
  // Here's the timeout.
  }
} finally {
 // do stuff.
}

There's also a NfcError.UserCancel whitch can come very handy to know when the user has pressed on the cancel button.

pke commented 1 month ago

@giuliobracci have you tested this? This causes a "uncaught exception" in my app when the timeout occurs. Similar UserCancel is not caught in the catch clause.