Flutter SDK

In this getting started guide, we will show you how to use the FormX pre-built Receipt Extractor to create an Flutter app that can assist users in capturing Receipt images and extract with FormX.ai

Platform Support

AndroidiOSMacOSWebLinuxWindows
✅(SDK 26+)✅ (iOS 14.0+)

Installation

  • Add formx_sdk_flutter as flutter dependency
dependencies:
  flutter:
    sdk: flutter
  formx_sdk_flutter: ^1.0.2
  • Android

    1. Set the minSdkVersion in android/app/build.gradle:
    android {
        defaultConfig {
            minSdkVersion 26
        }
    }
    
    1. Replace base activity with FlutterFragmentActivity
    class MainActivity: FlutterFragmentActivity() {
    }
    
  • iOS

    1. Update Podfile with:

      target 'Runner' do
      
        ....skiped...
      
        pod 'FormX', :git => 'https://github.com/oursky/formx-sdk.git', tag: '0.2.4'
      
        ....skiped...
      
    2. Set minimum deployments to 14.0

Configure SDK

First, you will need an Access Token and the Form ID of a Pre-Built Receipt Extractor from the FormX portal.

  1. Access Tokens:
    1. Open 'Access Token' tab of 'Manage Team' page on FormX Portal.
    2. Click 'Create Token' button
    3. Enter a name for the token and create it.
    4. Copy the access token and proceed with SDK configuration
  2. Form ID:
    1. Click 'Create new extractor' button of 'Extractors' page on FormX Portal.
    2. Select 'Receipts' in the list of built-in extractors.
    3. Enter a name for the extractor and create it.
    4. Open 'Extract' tab in your extractor detail page to obtain the Form ID.

You can then configure the FormX SDK using the Form ID and access token:

import 'package:formx_sdk_flutter/formx_sdk_flutter.dart';

main() {
  await FormXSDK.init(
    formId: "<FILL_IN_FORM_ID>",
    accessToken: "<FILL_IN_ACCESS_TOKEN>",
  );
}

Capture & Extract Documents

With FormXCameraViewyou can detect documents on the fly. By default offline ML models is used to detect documents, pass DetectMode.online to detectMode argument to using FormX API and make sure network is up.

document detection with offline ML models

document detection with offline ML models

📘

Download example project

A complete example code project can be found at this repo.

import 'package:flutter/material.dart';
import 'package:formx_sdk_flutter/formx_sdk_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:permission_handler/permission_handler.dart';

class CameraScreen extends StatefulWidget {
  const CameraScreen({super.key});

  @override
  State<StatefulWidget> createState() {
    return _CameraScreenState();
  }
}

class _CameraScreenState extends State<CameraScreen> {
  late bool detectOnServer;
  PermissionStatus? _cameraPermissionStatus;
  final _detectOnServer = false; // change to `true` to detect document using FormX api
  final FormXCameraController _controller = FormXCameraController();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => checkCameraPermission());
  }

  void checkCameraPermission() async {
    _cameraPermissionStatus = await Permission.camera.request();

    if (_cameraPermissionStatus != PermissionStatus.granted) {
      showDialog(
          context: context,
          builder: (_) => AlertDialog(
                title: const Text("Permission request"),
                content: const Text("Please grant camera permission"),
                actions: [
                  ElevatedButton(
                    onPressed: () {
                      context.pop();
                      _onCloseCamera();
                    },
                    child: const Text("Ok"),
                  ),
                ],
              ));
    }

    setState(() {});
  }

  _onCloseCamera() {
    context.pop();
  }

  _onCaptured(Uri imagePath) async {
    // receive captured image
    _controller.startCamera(); // resume camera
  }

  _onCaptureError(FormXCameraViewError error) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(error.message),
      ),
    );
  }

  Widget buildEmptyView(PermissionStatus? status) {
    switch (status) {
      case null:
        return const CircularProgressIndicator();
      case PermissionStatus.denied:
        return const Text("Please grant camera permission");
      case PermissionStatus.granted:
        return const SizedBox.shrink();
      default:
        return const Text("Cannot access camera");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _cameraPermissionStatus == PermissionStatus.granted
          ? FormXCameraView(
              controller: _controller,
              detectMode:
                  _detectOnServer ? DetectMode.online : DetectMode.offline,
              onClose: _onCloseCamera,
              onCaptured: _onCaptured,
              onCaptureError: _onCaptureError,
            )
          : Center(
              child: buildEmptyView(_cameraPermissionStatus),
            ),
    );
  }
}

name: formx_sdk_flutter_example
environment:
  sdk: '>=3.1.0 <4.0.0'
dependencies:
  flutter:
    sdk: flutter
  formx_sdk_flutter: ^1.0.0
  permission_handler: ^11.0.1
  go_router: ^12.1.3

To extract document, modified _onCaptured callback:

_onCaptured(Uri imagePath) async {
  try {
    final result = await FormXSDK.extract(widget.imagePath.toFilePath());
    // interpreting extracted fields from result
  } on PlatformException catch (error) {
    // handle error here
  }
}

API References

The API Reference for the Flutter SDK can be found in this link