Yubico / yubikit-ios

Yubico Mobile iOS SDK - YubiKit
Apache License 2.0
198 stars 44 forks source link

YKNFCSession bubbling up of user cancelled state #17

Closed rudyrichter closed 4 years ago

rudyrichter commented 4 years ago

In my particular use case i need to know if the session was closed by user error/invalid tag, cancelled by the user hitting the cancel button, or that it was closed normally after having succeeded in processing the read from the tag.

In wiring things up I found that there isn't a separate user cancelled path in the state enumeration or being made use of in:

- (void)tagReaderSession:(NFCTagReaderSession *)session didInvalidateWithError:(NSError *)error API_AVAILABLE(ios(13.0))

As far as I can tell when the user has cancelled the reader session both session and error will be nil in this method so it might be possible to add a cancelled value to the enum.

imakhalova commented 4 years ago

Hey @rudyrichter , Thank you for sharing your thoughts on error handling.

I understand it would be nice to figure our whether session was cancelled because user hits cancel button or bcz client/application actually successfully finished communication and actually wants to close the session (by calling stopSession). Currently in both cases the method you mentioned above actually will return the error NFCError(200) - Session invalidated by user

I'm planning to add property NSError* which you can check when state is closed. It's going to be set to the NFCError(200) only if session was invalidated by system (not by user). That way you can detect if session was closed by pressed Cancel button or in case of some error (for example, session timeout). WiIl it potentially work for you?

rudyrichter commented 4 years ago

@imakhalova,

I think that would work quite well.

imakhalova commented 4 years ago

Exposed iso7816SessionError which you can check when iso7816SessionState is YKFNFCISO7816SessionStateClosed. See commit 227278e

You should get an error in case if session was invalidated by user. Sample of usage within observer of iso7816SessionState:

if state == .closed {
 guard let error = YubiKitManager.shared.nfcSession.iso7816SessionError else {
           // session was closed without an error
                return
            }
            let errorCode = (error as NSError).code;
            if errorCode == NFCReaderError.readerSessionInvalidationErrorUserCanceled.rawValue {
                // user pressed cancel button 
            }
}
rudyrichter commented 4 years ago

@imakhalova,

Thanks so much, that works great.

eduprat-chwy commented 2 years ago

Hi @imakhalova how can I listen this cancelled on version 4.1.0? I have YKFManagerDelegate callbacks but none is called if the user presses cancel button, that YubiKitManager.shared.nfcSession doesn't exist in this version. Regards

Edited: Found that YKFManagerDelegate has didFailConnectingNFC that will receive the cancelled event, haven't seen before because it's @optional