Skip to content

Document Processing on a Web Service

To get the maximum performance and ease the document processing on a mobile side, you can perform the document processing on the Document Reader Web API. The size of the mobile application significantly decreases.

Step 1: Preparation

Android

Add the INTERNET permission to your AndroidManifest file - it's needed to send requests to the Web API service.

AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />

iOS

No permissions needed.

Step 2: Select Processing Mode

Before setting up, you need to specify the processing mode for the Mobile SDK. There two modes available: MANUAL and AUTO.

Manual Mode

In this mode, the document processing is performed fully on the Web API service, while the Mobile SDK is used only for capturing document images and passing them to the service.

Scheme of the online processing manual mode

  • The processing is performed fully on the backend.
  • No need to add the Core framework.
  • No need to add the database.
  • No need to perform the initialization process.

Auto Mode

In this mode, the document processing is performed both on the mobile side and on the Web API service.

Scheme of the online processing auto mode

Step 3: Start Processing

Create a configuration object and then use it on the document processing:

let onlineConfig = DocReader.OnlineProcessingConfig(mode: .manual)

let config = DocReader.ScannerConfig()
config.scenario = RGL_SCENARIO_FULL_PROCESS
config.onlineProcessingConfig = onlineConfig

DocReader.shared.showScanner(presenter: self, config: config) { (action, result, error) in
    if action == .complete || action == .processTimeout {
        print(result)
    }
}
RGLOnlineProcessingConfig *onlineConfig = [[RGLOnlineProcessingConfig alloc] initWithMode:RGLOnlineProcessingModeManual];

RGLScannerConfig *config = [[RGLScannerConfig alloc] init];
config.scenario = RGL_SCENARIO_FULL_PROCESS;
config.onlineProcessingConfig = onlineConfig;

[RGLDocReader.shared showScannerFromPresenter:self config:config completion:^(enum RGLDocReaderAction action, RGLDocumentReaderResults * _Nullable results, NSError * _Nullable error) {
    if (action == RGLDocReaderActionComplete || action == RGLDocReaderActionProcessTimeout) {
        NSLog(@"%@", results);
    }
}];
val config = OnlineProcessingConfig.Builder(OnlineMode.MANUAL).build()
DocumentReader.Instance().showScanner(this@MainActivity, ScannerConfig.Builder(config).build(), completion)
OnlineProcessingConfig config = new OnlineProcessingConfig.Builder(OnlineMode.MANUAL).build();
DocumentReader.Instance().showScanner(MainActivity.this, new ScannerConfig.Builder(config).build(), completion);
var config = ScannerConfig.withOnlineProcessingConfig(OnlineProcessingConfig(OnlineMode.MANUAL));
DocumentReader.instance.scan(config, completion);
var onlineConfig = new OnlineProcessingConfig()
onlineConfig.mode = OnlineMode.MANUAL

var config = new ScannerConfig()
config.onlineProcessingConfig = onlineConfig

DocumentReader.scan(config, _ => { }, _ => { })
var onlineConfig = new OnlineProcessingConfig()
onlineConfig.mode = OnlineMode.MANUAL

var config = new ScannerConfig()
config.onlineProcessingConfig = onlineConfig

DocumentReader.scan(config)
var onlineConfig = new OnlineProcessingConfig()
onlineConfig.mode = OnlineMode.MANUAL

var config = new ScannerConfig()
config.onlineProcessingConfig = onlineConfig

DocumentReader.scan(config, _ => { }, _ => { })
// Android
OnlineProcessingConfig config = new OnlineProcessingConfig.Builder(OnlineMode.Manual).Build();
DocumentReader.Instance().ShowScanner(this, config, completion);

// iOS
RGLOnlineProcessingConfig onlineConfig = new(RGLOnlineProcessingMode.Manual);
RGLScannerConfig config = new()
{
    Scenario = Constants.RGL_SCENARIO_FULL_PROCESS,
    OnlineProcessingConfig = onlineConfig
};
RGLDocReader.Shared.ShowScannerFromPresenter(this, config, completion);

By default, the FullProcess scenario is used to process the document on the Web API service. You can change the scenario and turn on other configuration settings by defining them in the processParams property and passing it to the configuration object.

See options of the document processing on the Getting Started page.

Processing Configuration

The OnlineProcessingConfig class may contain the following config parameters:

Parameter Description
mode Determines the operation mode: MANUAL or AUTO.
processParam Сontains a set of processing parameters used during document recognition or data extraction.
url Specifies the web service endpoint or URL to which the SDK will send requests.
imageFormat Specifies the format of the input image or images, such as JPEG or PNG.
imageCompressionQuality Controls the level of compression applied to images during document recognition.

You can learn more about OnlineProcessingConfig here.

HTTP Request Interception

Since the Document Reader SDK allows processing through the Regula Web Service, you may need to adjust HTTP request properties from your app before requests are sent to the Web Service..

This example demonstrates request interception:

import DocumentReader

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let onlineConfig = DocReader.OnlineProcessingConfig(mode: .manual)
        onlineConfig.requestInterceptingDelegate = self

        let config = DocReader.ScannerConfig()
        config.scenario = RGL_SCENARIO_FULL_PROCESS
        config.onlineProcessingConfig = onlineConfig

        DocReader.shared.showScanner(presenter: self, config: config) { (action, result, error) in
            if action == .complete || action == .processTimeout {
                print(result)
            }
        }

        return true
    }
}

extension AppDelegate: DocReader.URLRequestInterceptingDelegate {
    func interceptorPrepare(_ request: URLRequest) -> URLRequest? {
        var request = request
        request.addValue("Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmYWNlLXNkayI6IkhhdmUgYSBncmVhdCBkYXkhIn0.IPoW0D0LnMv_pL4U22MuIhDNGIdK34TaHhqhKBAaBEs", forHTTPHeaderField: "Authorization")
        return request
    }
}
#import "AppDelegate.h"
#import <DocumentReader/DocumentReader.h>

@interface AppDelegate ()<RGLURLRequestInterceptingDelegate>
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  RGLOnlineProcessingConfig *onlineConfig = [[RGLOnlineProcessingConfig alloc] initWithMode:RGLOnlineProcessingModeManual];
  onlineConfig.requestInterceptingDelegate = self;

  RGLScannerConfig *scannerConfig = [[RGLScannerConfig alloc] init];
  scannerConfig.scenario = RGL_SCENARIO_FULL_PROCESS;
  scannerConfig.onlineProcessingConfig = onlineConfig;

  UIViewController *presenter = self.window.rootViewController;
  [RGLDocReader.shared showScannerFromPresenter:presenter config:scannerConfig completion:^(RGLDocReaderAction action, RGLDocumentReaderResults * _Nullable results, NSError * _Nullable error) {
      if (action == RGLDocReaderActionComplete || action == RGLDocReaderActionProcessTimeout) {
        NSLog(@"%@", results);
      }
  }];
  return YES;
}

- (NSURLRequest * _Nullable)interceptorPrepareRequest:(NSURLRequest * _Nonnull)request {
  NSMutableURLRequest *newRequest  = [request mutableCopy];
  [newRequest addValue:@"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmYWNlLXNkayI6IkhhdmUgYSBncmVhdCBkYXkhIn0.IPoW0D0LnMv_pL4U22MuIhDNGIdK34TaHhqhKBAaBEs"
    forHTTPHeaderField:@"Authorization"];
  return newRequest;
}

@end
class MainActivity : Activity(), NetworkInterceptorListener {

    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onCreate(savedInstanceState, persistentState)

        val onlineProcessingConfig = OnlineProcessingConfig.Builder(OnlineMode.AUTO, Scenario.SCENARIO_FULL_PROCESS).setNetworkInterceptorListener(this).build()
        val config = ScannerConfig.Builder(Scenario.SCENARIO_FULL_PROCESS, onlineProcessingConfig).build()
        DocumentReader.Instance().showScanner(this, config, IDocumentReaderCompletion { action, documentReaderResults, error ->
            if (action == DocReaderAction.COMPLETE || action == DocReaderAction.TIMEOUT) {
                print(result)
            }
        })
    }

    override fun onPrepareRequest(connection: HttpURLConnection?) {
        connection?.setRequestProperty("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmYWNlLXNkayI6IkhhdmUgYSBncmVhdCBkYXkhIn0.IPoW0D0LnMv_pL4U22MuIhDNGIdK34TaHhqhKBAaBEs")
    }
}
public class MainActivity extends Activity implements NetworkInterceptorListener {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        OnlineProcessingConfig onlineProcessingConfig = new OnlineProcessingConfig.Builder(OnlineMode.AUTO, Scenario.SCENARIO_FULL_PROCESS).setNetworkInterceptorListener(this).build();
        ScannerConfig config = new ScannerConfig.Builder(Scenario.SCENARIO_FULL_PROCESS, onlineProcessingConfig).build();
        DocumentReader.Instance().showScanner(this, config, (action, documentReaderResults, e) -> {
            if (action == DocReaderAction.COMPLETE || action == DocReaderAction.TIMEOUT) {
                print(result)
            }
        });
    }

    @Override
    public void onPrepareRequest(HttpURLConnection httpURLConnection) {
        httpURLConnection.setRequestProperty("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmYWNlLXNkayI6IkhhdmUgYSBncmVhdCBkYXkhIn0.IPoW0D0LnMv_pL4U22MuIhDNGIdK34TaHhqhKBAaBEs");
    }
}

Examples

See the sample project that demonstrates how to set up the document processing on a Web Service.

Next Steps