Implementing Anyline

Since we created a Single View App, Visual Studio automatically created a Storyboard and a View Controller for us. By default, the Storyboard is named MainStoryboard.storyboard and the View Controller is named RootViewController.

Create and set up a Scan View

There are five module-specific Scan Views available:

  • AnylineOCRModuleView for generic use cases (see /toc/modules/anyline_ocr/index Module)
  • AnylineEnergyModuleView for power, gas and water meter scanning (see /toc/modules/energy/index Module)
  • AnylineBarcodeModuleView for barcode scanning (see /toc/modules/barcode/index Module)
  • AnylineMRZModuleView for MRZ and passport scanning (see /toc/modules/mrz/index Module)
  • AnylineDocumentModuleView for document scanning (see /toc/modules/document/index Module)

In this example, we implement Barcode scanning.

RootViewController.cs

In the RootViewController.cs, we will implement the Anyline SDK. The setup, scanning and tear down will be handled within the lifecycle methods.

First, add the Anyline Xamarin.iOS SDK reference:

using AnylineXamarinSDK.iOS;

Adding a scanView

In the next step, create a member variable scanView of the type of the module-specific view that you want to implement.

AnylineBarcodeModuleView scanView;

Set up in ViewDidLoad

The scanView is set up and added to the View of the ViewController.

Basically, a new instance of our module-specific view (in this case: AnylineBarcodeModuleView) is created and a frame in which the view is rendered is delivered.

In the next step, SetupWithLicenseKey is called with the following parameters:

  • The license key of your personal bundle identifier (see Generate an Anyline License Key)
  • The Delegate that will listen to the results (in this case: the RootViewController, because we’ll let it implement the delegate of our module-specific view)
  • An NSError object which gets filled with an error description if the setup fails (for example, if the license key is wrong).

Finally, the scan view is added as a subview of our RootViewController.View

public override void ViewDidLoad()
{
    base.ViewDidLoad();

    //initialize the scan view with a frame
    scanView = new AnylineBarcodeModuleView(UIScreen.MainScreen.Bounds);

    //setup the scan view with your license key, the delegate (this) that handles the results and store any possible error in a variable
    NSError error;
    bool success = scanView.SetupWithLicenseKey("YOUR LICENSE KEY HERE", this, out error);

    //show an alert if something went wrong
    if (!success)
    {
        new UIAlertView("Error", error.DebugDescription, null, "OK", null).Show();
    }

    // After the setup is done we add the module to the view of this view controller
    View.AddSubview(scanView);
}

Loading a View Configuration via JSON

If you want to use the standard module-view-configurations, you don’t have to do anything, since the appropriate view configuration is loaded from the AnylineResources.bundle automatically.

However, if you would like to override this with your own configuration, you can load the configuration json file with the follwing code inside ViewDidLoad:

Load the View Configuration via JSON
String s;

String confPath = NSBundle.MainBundle.PathForResource(@"view_config", @"json");
scanView.CurrentConfiguration = ALUIConfiguration.CutoutConfigurationFromJsonFile(confPath);

Start Scanning in ViewDidAppear

The scanning itself is started in ViewDidAppear.

public override void ViewDidAppear(bool animated)
{
    base.ViewDidAppear(animated);
    /*
     This is the place where we tell Anyline to start receiving and displaying images from the camera.
     Success/error tells us if everything went fine.
     */
    NSError error;
    bool success = scanView.StartScanningAndReturnError(out error);

    if (!success)
    {
        // Something went wrong. The error object contains the error description
        new UIAlertView(@"Start Scanning Error", error.DebugDescription, null, "OK", null).Show();
    }
}

Stop Scanning in ViewWillDissapear

In order to avoid problems, the scanning process is stopped in ViewWillDissapear.

Unregister in ViewDidDissapear

Unregister any event handlers and dispose/remove the scanView so there are no circular dependencies left.

The Anyline OCR Module Configuration

In case you want to use the /toc/modules/anyline_ocr/index, you can set your parameters analogous to the Parameters on iOS.

Simply set the parameters to an instance of ALOCRConfig, and assign the instance to your scanView:

Set the Anyline OCR Parameters
ALOCRConfig ocrConfig = new ALOCRConfig();
// ...
success = scanView.SetupWithLicenseKey(licenseKey, this.Self, ocrConfig, out error);

Load a Custom Command File

To load a Custom Command File in Xamarin.Android, simply set it to the ALOCRConfig:

Load a Custom Commmand File
ocrConfig.CustomCmdFilePath = NSBundle.MainBundle.PathForResource(@"Modules/OCR/your_command_file", @"ale");

Handling Scan Results

To handle scan results, the RootViewController has to implement the interface of a module-specific view delegate.

Simply modify the class header signature as shown in the example below.

// for generic scans, implement IAnylineOCRModuleDelegate
public partial class RootViewController : UIViewController, IAnylineOCRModuleDelegate
{
    ...
}
// for energy meter scans, implement IAnylineEnergyModuleDelegate
public partial class RootViewController : UIViewController, IAnylineEnergyModuleDelegate
{
    ...
}
// for barcode scans, implement IAnylineBarcodeModuleDelegate
public partial class RootViewController : UIViewController, IAnylineBarcodeModuleDelegate
{
    ...
}
// for MRZ and passport scans, implement IAnylineMRZModuleDelegate
public partial class RootViewController : UIViewController, IAnylineMRZModuleDelegate
{
    ...
}
// for document scans, implement IAnylineDocumentModuleDelegate
public partial class RootViewController : UIViewController, IAnylineDocumentModuleDelegate
{
    ...
}

The interface can be implemented by right-clicking on the Interface and selecting Implement Interface > Implement Interface explicitly.

Visual Studio automatically generates the DidFindScanResult method of the module-specific delegate. This method is called every time a result is found.

Implement the Interface

The following code shows an implementation where the result is presented in an UIAlertView.

void IAnylineBarcodeModuleDelegate.DidFindResult(AnylineBarcodeModuleView anylineBarcodeModuleView, ALBarcodeResult scanResult)
{
        new UIAlertView(@"Result", scanResult.Result.ToString(), null, "OK", null).Show();
}

Testing your app on an iOS device

Build your project and deploy your application on your iOS device. Make sure you choose your storyboard and an adequate deployment target in your Info.plist (>= 10 - but not higher than your device target).

Flags

Make sure that that you have selected Link all assemblies in the Linker Options!

Info.plist and camera access

Newer iOS versions require that the camera usage is defined with a description in the Info.plist file. Open this file in a text editor and add the following tags manually:

<key>NSCameraUsageDescription</key>
<string>Yes we scan!</string>

Gotchas

Garbage Collector

Xamarins Garbage Collector may not be able to collect all garbage, which means that there might be memory leaks if there are any dependencies left in the ViewController. Therefore, make sure that all registered events are unregistered and all subviews are removed from the ViewController view and disposed!

Draw on the ScanView

If you use a community edition license you are not allowed to place any visual element over the Anyline watermark while scanning. We will give you a friendly exception if you try to do so. Please contact us at the Anyline Support Request Website, if you need to draw over the scanning view.

Stop Scanning

Always make sure that scanning is stopped before the view appears!