Migrate to 3.0.0


In version 3.0.0 we modernized our UI. In addition, we simplified how the UI is customized, and introduced centralized customization for the color palette and typography. We also removed the Component API integration option and unified the public API of the SDK and introduced an easier way to customize certain parts of the UI.

GiniConfiguration is a singleton now. You don’t need to create a new instance of GiniConfiguration, use GiniConfiguration.shared instead.

Migrate from Component API

The Component API provided more UI customization options at the cost of a more difficult integration and maintenance. It was based on the view controllers, and you managed navigation between them and also updated the navigation whenever we introduced breaking changes.

Maintaining the Component API along with the Screen API required an increasing amount of effort as we added new features. We decided therefore to unify both APIs and introduce the ability to inject fully custom UI elements.

The major benefit of the Component API was the ability to use a custom navigation bar. Via GiniConfiguration.shared.customNavigationController that is still possible with the new public API.

Follow these steps to make the migration to the new public API easier:

  • Configure the SDK the same way as before by using GiniConfiguration.

  • If you used a custom navigation bar, then you can now pass UINavigationViewController to GiniConfiguration.shared.customNavigationController.

  • The SDK provides a custom UIViewController object, which should be shown by your app. It handles the complete process from showing the onboarding to providing a UI for the analysis.

// MARK: - Default networking let viewController = GiniCapture.viewController(withClient: client, importedDocuments: visionDocuments, configuration: visionConfiguration, resultsDelegate: self, documentMetadata: documentMetadata, api: .default, userApi: .default, trackingDelegate: self) // MARK: - Custom networking let viewController = GiniCapture.viewController(importedDocuments: visionDocuments, configuration: visionConfiguration, resultsDelegate: self, documentMetadata: documentMetadata, trackingDelegate: trackingDelegate, networkingService: self)
  • Handling the analysis results and receiving the extracted information (error or cancellation) can be handled through GiniCaptureResultsDelegate protocol implementation.

  • You can also provide your own networking by implementing the GiniCaptureNetworkService and GiniCaptureResultsDelegate protocols. Pass your instances to the UIViewController initialiser of GiniCapture as shown above.

  • Remove all code related to interacting with the SDK’s specific view controllers. From now on the entry point is the UIViewController and customization happens through GiniConfiguration and via overriding of images and color resources.

  • Use the new UI customization options and follow the screen-by-screen UI customization section to adapt the look of the new UI.


Migrate from Screen API

The new public API is based on the Screen API, so you only use the new UI customization options and follow the screen-by-screen UI customization section to adapt the look of the new UI.


Migrate Cleanup and Feedback step

We simplified the feedback-sending logic. When you clean up Gini Capture SDK, pass the values the user uses (and potentially corrects) to GiniConfiguration.shared.cleanup(). All values except the one for the amount are passed in as strings. The amount needs to be passed in as Decimal and its currency as an enum value.

You don’t have to call any additional methods to send the extraction feedback.

Default Networking implementation

You don’t need to maintain a reference and call sendFeedbackBlock anymore. The GiniConfiguration.shared.cleanup() method takes care of sending the feedback.

Custom Networking implementation

Here as well you don’t need to maintain a reference and call sendFeedbackBlock anymore. Your implementation of the GiniCaptureNetworkService.sendFeedback()
method is called when you pass the values the user uses (and potentially corrects) to GiniConfiguration.shared.cleanup().


Overview of new UI customization options

To simplify UI customization we introduced global customization options. There is no need to customize each screen separately anymore.

Colors

We provide a global color palette GiniColors.xcassets which you are free to override. Custom colors are applied on all screens.

For more information about the names of the color resources, see GiniColors.xcassets.

Images

Images customization is done via overriding of GiniImages.xcassets resources.

Typography

We provide global typography based on text appearance styles from UIFont.TextStyle. To override them in your application use GiniConfiguration.updateFont(_ font: UIFont, for textStyle: UIFont.TextStyle), for example:

// If you want to scale your font, use our method `scaledFont()`. let configuration = GiniBankConfiguration.shared let customFontToBeScaled = UIFont.scaledFont(UIFont(name: "Avenir", size: 20) ?? UIFont.systemFont(ofSize: 7, weight: .regular), textStyle: .caption1) configuration.updateFont(customFontToBeScaled, for: .caption1) // If you would like to pass us already scaled font. let customScaledFont = UIFontMetrics(forTextStyle: .caption2).scaledFont(for: UIFont.systemFont(ofSize: 28)) configuration.updateFont(customScaledFont, for: .caption2)

Text

Text customization is done via overriding of string resources.

For more information about the string resources, see Localizable.strings.

UI elements

Certain elements of the UI can now be fully customized via UI injection. It utilizes view adapter interfaces which you can implement and pass to GiniConfiguration when configuring the SDK. These interfaces declare the contract the injected view has to fulfill and let the SDK ask for your view instance when needed.

Top navigation bar

To inject your own navigation bar view, pass your navigation view controller to GiniConfiguration.shared.customNavigationController. The view from the custom navigation view controller is displayed on all screens as the top navigation bar.

Bottom navigation bar

You can opt to show a bottom navigation bar. To enable it, pass true to GiniConfiguration.shared.bottomNavigationBarEnabled.

The top navigation bar is still used, but its functionality is limited to showing the screen’s title and an optional close button. Inject a custom top navigation bar if your design requires it even if you enabled the bottom navigation bar.


Migrate to new UI

Onboarding screens

The new onboarding screen uses the global UI customization options. You can discard the earlier screen-specific customizations.

Images and text are onboarding page specific and need to be customized for each page.

For more information, see Onboarding Screen.

Breaking changes

Setting custom onboarding pages

The OnboardingPage struct was changed to also enable setting a title for the page and injecting a view for the illustration.

If you set custom onboarding pages, create the OnboardingPage as shown in the example:

configuration.customOnboardingPages = [OnboardingPage(imageName: "captureSuggestion1", title: "Page 1", description: "Description for page 1")]

New features

Custom illustration views

To inject any custom view for the illustration, implement the OnboardingIllustrationAdapter interface and pass it to either GiniConfiguration or the OnboardingPage constructor.

If you want to animate the illustrations on the onboarding pages, implement the OnboardingIllustrationAdapter interface to inject a view that can animate images (for example, Lottie) and pass it to the relevant onboarding illustration adapter setters (for example, onboardingAlignCornersIllustrationAdapter, onboardingLightingIllustrationAdapter, onboardingMultiPageIllustrationAdapter, onboardingQRCodeIllustrationAdapter) when configuring the GiniConfiguration.shared instance.


Camera screen

The new camera screen uses the global UI customization options. You can discard the earlier screen-specific customizations.

For more information, see Camera Screen.


Review screen

The new review screen uses the global UI customization options. You can discard the earlier screen-specific customizations.

Breaking changes

We unified UI for the single page and multi pages options. We removed rotation and reorder functionalities. The tips view was removed as well.

New features

Custom loading indicator

You can show a custom loading indicator with custom animation support on the process button on the screen. Your custom loading indicator should implement OnButtonLoadingIndicatorAdapter interface and be passed to GiniConfiguration.shared.onButtonLoadingIndicator.

Bottom navigation bar

To show a bottom navigation bar, pass true to GiniConfiguration.shared.bottomNavigationBarEnabled. There is a default implementation, but you can also use your own by implementing the ReviewScreenBottomNavigationBarAdapter interface and passing it to GiniConfiguration.shared.reviewNavigationBarBottomAdapter.

For more information, see Review Screen.


Analysis screen

The new analysis screen uses the global UI customization options. You can discard the earlier screen-specific customizations.

Breaking changes

String keys removed: ginicapture.analysis.suggestion.header

The following string keys now represent suggestion titles with new keys added for describing the tips. ginicapture.analysis.suggestion.1 ginicapture.analysis.suggestion.2 ginicapture.analysis.suggestion.3 ginicapture.analysis.suggestion.4 ginicapture.analysis.suggestion.5

New features

Custom loading indicator

You can show a custom loading indicator with custom animation support at the center of the screen. Your custom loading indicator should implement CustomLoadingIndicatorAdapter interface and be passed to GiniConfiguration.shared.customLoadingIndicator. This loading indicator is also used on the Camera screen when loading data for a valid QR code.

For more information, see Analysis Screen.


Help screens

The new help screens use the global UI customization options. You can discard the earlier screen-specific customizations.

Breaking changes

String keys changed: ginicapture.help.menu.firstItem → ginicapture.help.menu.tips ginicapture.help.menu.secondItem→ ginicapture.help.menu.formats ginicapture.help.menu.thirdItem → ginicapture.help.menu.import

New features

Bottom navigation bar

To show a bottom navigation bar, pass true to GiniConfiguration.shared.bottomNavigationBarEnabled. There is a default implementation, but you can also use your own by implementing the HelpBottomNavigationBarAdapter interface and passing it to GiniConfiguration.shared.helpNavigationBarBottomAdapter.

For more information, see Help Screen.


No results screen

The new no-results screen uses the global UI customization options. You can discard the earlier screen-specific customizations.

Breaking Changes

Removed localization keys

ginicapture.noresults.warning ginicapture.noresults.collection.header ginicapture.noresults.gotocamera ginicapture.noresults.warningHelpMenu

New features

New localization keys

ginicapture.noresult.enterManually ginicapture.noresult.retakeImages

Enter manually button

Users can now click the Enter manually button on the no-results screen and exit the SDK. To enable this, implementGiniCaptureResultsDelegate.giniCaptureDidEnterManually().

For more information, see No Results Screen.


Error screen

The new error screen uses the global UI customization options.

Breaking Changes

Showing errors during usage of the SDK was changed from snackbar to a whole new screen.

New Features

New UI

The new error screen gives options to retake photos or enter details manually and displays errors with more detailed descriptions.

Enter manually button

Users can now click the Enter manually button on the no-results screen and exit the SDK. To enable this, implementGiniCaptureResultsDelegate.giniCaptureDidEnterManually().

For more information, see Error Screen.


QR code scanner

During the QR-code-only mode, the capture and import controls are hidden from the camera screen.

To enable the QR-code-only mode, both flags GiniConfiguration.shared.qrCodeScanningEnabled and GiniConfiguration.shared.onlyQRCodeScanningEnabled should be true.

For more information, see QR Code Scanning Guide.