Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS - Catch NSExceptions and repackage as FlutterErrors #64

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jonathanellis
Copy link

Problem

Currently, if the iOS license is invalid/expires, the app crashes with:

*** Terminating app due to uncaught exception 'MB(InvalidLicenseKeyException)', reason: 'Your license key is invalid! Please check if you have all wanted rights.'

Instead of crashing the app, the Flutter SDK should throw an exception, so that it can be caught and handled by the app.

Cause

This is caused by the license key not being validated before launching the scanner:

[self setLicenseKey:licenseKeyDict];
[self scanWith:recognizerCollectionDict overlaySettingsDict:overlaySettingsDict];

Unfortunately, the iOS SDK method [MBMicroblinkSDK setLicenseKey:andLicensee:errorCallback:]; does not return a value, nor does it have a success callback - it only has an errorCallback, and even then the Flutter plugin just has an empty callback body, so this isn't being handled 🥹.

Solution

The solution I've implemented is not 100% ideal, but it does deal with the problem in the short term without requiring more in-depth changes to either the Flutter SDK or iOS SDK...

I just catch all exceptions and repackage them as FlutterErrors. In practice this means I'm not actually getting the error callback when setting the license - I'm catching the exception that gets thrown when launching the scanner with an invalid license.

Better solutions

There are definitely some better potential solutions but these would require more work and/or potentially changes to the underlying iOS SDK:

Improve [MBMicroblinkSDK setLicenseKey:andLicensee:errorCallback:]

It seems currently we have no API to tell if the license is valid, only if it's invalid.

Assuming that this method needs to remain async, rename errorCallback to callback, and make it so that the MBLicenseError is NULL if the license was validated successfully.

This way you could make it so:

(a) If the license is valid, call [BlinkIDFlutterPlugin scanWith:overlaySettingsDict:] (so we don't have to rely on it throwing an InvalidLicenseKeyException.

(b) If the license is invalid, don't try and launch the scanner and instead, repackage the MBLicenseError into a FlutterError and send it as the result.

Separate setting the license and launching the scanner

The BlinkID iOS SDK documentation says:

Note that you need to set the license key before intializing scanning. Ideally in AppDelegate or viewDidLoad before initializing any recognizers.

However, in the Flutter SDK we are only allowed to set the license key immediately before launching the scanner (see above).

The Flutter SDK could be refactored to expose a separate method in the MethodChannel specifically for setting the license. This way we could set the license (and validate it) before we launch the scanner.

For example, we might want to hide the option to use the scanner if the license is expired/invalid (for which we also need a way to check the license validity, as above). We also want to avoid what is I guess currently a potential race condition where the scanner could be launched (and fail) before the license validation (async) has completed (but you may already have mitigations for this!)

Anyway, thanks for all the great work 💪 - hope this is helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant