RGBridge — Developer Integration Guide

Panduan integrasi untuk developer yang menggunakan Flutter package rg_bridge pada aplikasi host.

1. Informasi Package

Item Value
Package rg_bridge
Version 0.1.1-rc-2
Entry point package:rg_bridge/rg_bridge.dart

Dokumentasi ini berfokus pada penggunaan SDK dari sisi aplikasi host.

Dokumentasi ini tidak membahas:

  • endpoint internal;
  • request/response schema service;
  • struktur database/backend;
  • implementasi internal addon;
  • HTTP client internal SDK;
  • utility internal yang bukan bagian dari public API.

2. Konsep Integrasi

rg_bridge menyediakan tiga surface utama:

Surface API Fungsi
Device sdk.device Informasi device dan hardware tests
WebView sdk.webview Session WebView, controller, dan komunikasi event
Form sdk.formSubmission Inisialisasi session dan submit form

Pola integrasi:

Flutter Host App
       │
       ▼
    RGBridge
   ┌───┼──────────────┐
   ▼   ▼              ▼
Device WebView        Form
   │     │              │
   ▼     ▼              ▼
 Result  Event        Response

Prinsip utama

  1. Buat satu instance RGBridge untuk aplikasi.
  2. Gunakan API melalui sdk.device, sdk.webview, dan sdk.formSubmission.
  3. Import hanya public entry point.
  4. Device test menggunakan result stream.
  5. REQUIRES_USER_ACTION merupakan intermediate state, bukan hasil final.
  6. WebView listener dan controller dikelola oleh aplikasi host.
  7. Bersihkan listener dan controller ketika lifecycle screen selesai.

3. Requirements

Flutter / Dart

Gunakan versi Flutter/Dart yang kompatibel dengan package.

Versi yang digunakan pada release ini:

Dart: ^3.12.2
Flutter: >=1.17.0

Android

Untuk hardware test, device Android fisik lebih disarankan daripada emulator karena tidak semua hardware tersedia pada emulator.

Permission yang diperlukan bergantung pada fitur yang digunakan. Package mendeklarasikan permission native yang dibutuhkan oleh fitur-fitur tersebut.

iOS

Beberapa native capability pada iOS masih berupa stub atau dapat menghasilkan NOT_SUPPORTED.

Jika aplikasi menggunakan fitur yang membutuhkan permission native, host tetap perlu menyediakan usage description yang sesuai di Info.plist.


4. Installation

4.1 Dependency

Tambahkan package dari pub.dev:

dependencies:
  rg_bridge: ^0.1.1-rc-1

Kemudian jalankan:

flutter pub get

4.2 Import

Gunakan public entry point:

import 'package:rg_bridge/rg_bridge.dart';

Jangan mengakses file internal melalui:

import 'package:rg_bridge/src/...';

5. Initialization

Buat satu instance RGBridge pada lifecycle aplikasi atau service yang mengelola SDK:

final sdk = RGBridge(
  baseUrl: 'https://api.example.com',
  clientId: 'rg_your_client_id',
);

baseUrl dan clientId digunakan oleh SDK untuk kebutuhan fitur yang membutuhkan koneksi service.

Rekomendasi

Jangan membuat instance baru pada setiap screen jika tidak diperlukan.

Contoh service sederhana:

class RGBridgeService {
  late final RGBridge sdk;

  RGBridgeService() {
    sdk = RGBridge(
      baseUrl: 'https://api.example.com',
      clientId: 'rg_client_id',
    );
  }
}

6. SDK Lifecycle

Secara umum lifecycle aplikasi host:

Create RGBridge
      │
      ▼
Use Device / WebView / Form
      │
      ▼
Handle Result / Event
      │
      ▼
Cleanup Listener / Controller
      │
      ▼
Screen / Flow selesai

Tanggung jawab host

Object Tanggung jawab
RGBridge Dikelola sebagai instance SDK aplikasi
Device controller Dispose setelah test selesai atau screen ditutup
WebView listener Register saat flow dimulai, unregister saat flow selesai
WebView controller Dikelola dan di-dispose oleh host

Contoh cleanup:

@override
void dispose() {
  _deviceController?.checkDispose();
  sdk.webview.offAllEvents();

  super.dispose();
}

7. Device Integration

7.1 Overview

Gunakan:

sdk.device

untuk:

  • mendapatkan informasi perangkat;
  • melakukan hardware capability/test;
  • mendapatkan structured test result;
  • menjalankan touchscreen test widget.

Device addon dapat digunakan secara standalone dan tidak bergantung pada WebView.


7.2 Device Information

Ambil informasi perangkat:

final info = await sdk.device.getDeviceInfo();

Jika membutuhkan stable identifier:

final info = await sdk.device.getDeviceInfo(
  includeStableId: true,
);

Contoh penggunaan:

final info = await sdk.device.getDeviceInfo();

print(info.brand);
print(info.model);
print(info.osName);
print(info.osVersion);

7.3 Hardware Test Lifecycle

Hardware test menggunakan pola:

Create Controller
      ↓
Subscribe Result Stream
      ↓
Start Test
      ↓
Handle Intermediate State
      ↓
Wait Terminal Result
      ↓
Dispose Controller

Contoh:

final controller = sdk.device.checkGps();

final subscription = controller.getResultStream.listen((result) {
  print(result.status);

  if (!result.status.isTerminal) {
    return;
  }

  print(result.toJson());
});

await controller.checkStart();

Setelah test selesai:

controller.checkDispose();
await subscription.cancel();

Subscribe stream sebelum memanggil checkStart() agar tidak melewatkan result.


7.4 Result Status

Result hardware dapat melewati lebih dari satu state.

Secara umum:

STARTED
   ↓
REQUIRES_USER_ACTION
   ↓
PASS / FAILED / SKIPPED / NOT_SUPPORTED

REQUIRES_USER_ACTION bukan hasil final.

Jika status tersebut diterima, aplikasi host perlu menampilkan UI atau melakukan tindakan yang diminta oleh test sebelum menunggu result berikutnya.

Gunakan:

if (result.status.isTerminal) {
  // Final result
}

7.5 Supported Test

Daftar test yang tersedia dapat diperoleh melalui:

final tests = sdk.device.getSupportedTestIds();

Test yang tersedia pada release ini mencakup:

touchscreen
accelerometer
gyroscope
biometric
bluetooth
wifi
gps
camera
speaker
vibration
speech
microphone
flashlight
navigation_button
power
volume_button

Tidak semua test tersedia atau memiliki behavior yang sama pada setiap platform/device.


8. Touchscreen Test Widget

SDK menyediakan widget untuk touchscreen test:

CheckTouchscreenWidget

Import:

import 'package:rg_bridge/rg_bridge.dart';

Widget dapat ditempatkan langsung pada UI aplikasi host sesuai kebutuhan flow testing.

Lifecycle widget mengikuti lifecycle widget Flutter host.


9. WebView Integration

Gunakan:

sdk.webview

untuk flow yang membutuhkan:

  • session WebView;
  • WebView controller;
  • loading content;
  • komunikasi Flutter ↔ JavaScript;
  • event dari halaman WebView.

Flow umum:

Init WebView Session
        ↓
Register Event Listener
        ↓
Create WebView Controller
        ↓
Open / Load WebView
        ↓
Receive WebView Events
        ↓
Cleanup

9.1 Initialize Session

Contoh:

final session = await sdk.webview.initSessionWebView(
  type: 'workflow-type',
  firstName: 'John',
  lastName: 'Doe',
  memberCode: '123456',
);

Session digunakan sebagai dasar untuk membuka workflow WebView.


9.2 Create Controller

Controller WebView dibuat melalui SDK:

final controller = sdk.webview.createController(
  session: session,
);

Controller kemudian digunakan oleh host untuk membangun screen WebView.

Detail implementasi UI WebView tetap menjadi tanggung jawab aplikasi host.


9.3 WebView Events

Daftarkan listener sebelum WebView digunakan:

sdk.webview.onEvent((event) {
  print(event.type);
  print(event.data);
});

Event dapat digunakan untuk mengetahui perubahan state dari workflow WebView.

Event yang tersedia pada release ini mencakup:

formSubmitted
formCancelled
formError
formSuccess
imageCaptured

Contoh:

sdk.webview.onEvent((event) {
  switch (event.type) {
    case WebviewEventType.formSubmitted:
      // handle submit
      break;

    case WebviewEventType.formCancelled:
      // handle cancellation
      break;

    case WebviewEventType.formError:
      // handle error
      break;

    case WebviewEventType.formSuccess:
      // handle success
      break;

    case WebviewEventType.imageCaptured:
      // handle captured image
      break;
  }
});

9.4 Flutter → WebView

Host dapat mengirim event/data ke halaman WebView melalui API SDK:

sdk.webview.sendToWebView(
  type: 'event-type',
  data: {
    'key': 'value',
  },
);

Gunakan hanya event/data yang sudah disepakati oleh halaman WebView yang diintegrasikan.


9.5 Loading HTML

SDK menyediakan API untuk kebutuhan HTML content:

sdk.webview.loadHtmlString(...);

dan:

sdk.webview.loadHtmlStringWithInlineJs(...);

Gunakan content yang berasal dari sumber tepercaya.


9.6 Cleanup WebView

Ketika screen atau flow selesai:

sdk.webview.offAllEvents();

Controller WebView mengikuti lifecycle widget/controller yang digunakan oleh aplikasi host.


10. Form Submission

Gunakan:

sdk.formSubmission

untuk flow submit form tanpa UI WebView.

Flow:

Initialize Form Session
        ↓
Prepare Form Data
        ↓
Submit
        ↓
Handle Result
        ↓
Flow selesai

10.1 Initialize Session

final session = await sdk.formSubmission.initFormSubmission();

Simpan informasi session selama form flow masih berlangsung.


10.2 Submit Form

Submit menggunakan API SDK:

final result = await sdk.formSubmission.submitForm(
  sessionToken: session.sessionToken,
  form: form,
);

Contoh dengan error handling:

try {
  final result = await sdk.formSubmission.submitForm(
    sessionToken: session.sessionToken,
    form: form,
  );

  print(result);
} catch (e) {
  // Tampilkan error atau lakukan handling
}

Jika session sudah tidak valid, host dapat melakukan initialization session kembali sesuai kebutuhan flow aplikasi.


11. Error Handling

Tidak semua kegagalan SDK berbentuk exception.

Surface Cara handling
Device Periksa DeviceTestResult dan status
WebView Tangani event/error dari WebView
Form Gunakan try/catch
Network Gunakan try/catch dan tampilkan state error pada UI

Contoh Form:

try {
  final result = await sdk.formSubmission.submitForm(
    sessionToken: token,
    form: form,
  );
} catch (e) {
  // Handle error
}

Untuk device test, jangan hanya mengandalkan try/catch. Result test harus diproses melalui stream.


12. Permission Handling

Permission yang dibutuhkan bergantung pada fitur yang digunakan.

Flow umum:

Feature digunakan
      ↓
Permission diperlukan
      ↓
Permission granted
      │
      ├── Yes → lanjutkan test
      │
      └── No  → handle pada host

Jika permission ditolak secara permanen, aplikasi host dapat mengarahkan user ke Settings.

Pada iOS, pastikan usage description untuk permission yang digunakan sudah tersedia pada Info.plist.


13. Security

Aplikasi host bertanggung jawab terhadap keamanan integrasi.

Network

Gunakan HTTPS untuk environment production.

Client ID

Jangan hardcode credential sensitif pada repository publik.

WebView

Hanya load content dari sumber yang dipercaya.

Karena WebView dapat menjalankan JavaScript, content yang dimuat berada pada trust boundary aplikasi.

Logging

Hindari logging:

session token
form data sensitif
PII
sensitive device information

terutama pada release build.


14. Recommended Integration Architecture

Untuk aplikasi yang cukup besar, pisahkan SDK integration dari UI:

Flutter App
│
├── RGBridgeService
│     └── RGBridge
│
├── Device Flow
│     ├── Device Info
│     ├── Hardware Tests
│     └── Result Handling
│
├── WebView Flow
│     ├── Session
│     ├── Event Handler
│     └── WebView Screen
│
└── Form Flow
      ├── Session
      ├── Form Data
      └── Submit Handler

Dengan struktur ini, screen tidak perlu mengelola seluruh lifecycle SDK secara langsung.


15. End-to-End Integration Flow

Contoh flow aplikasi:

Application Start
       │
       ▼
Create RGBridge
       │
       ├───────────────┐
       ▼               ▼
 Device Flow       WebView/Form
       │               │
       ▼               ▼
Start Test         Initialize Session
       │               │
       ▼               ▼
Result Stream      Event / Response
       │               │
       └───────┬───────┘
               ▼
          Business Logic
               │
               ▼
            Cleanup

Contoh bootstrap:

import 'package:rg_bridge/rg_bridge.dart';

final sdk = RGBridge(
  baseUrl: 'https://api.example.com',
  clientId: 'rg_client_id',
);

Future<void> bootstrap() async {
  final deviceInfo = await sdk.device.getDeviceInfo();

  print(deviceInfo.model);
}

16. Integration Checklist

Setup

  • Tambahkan rg_bridge dari pub.dev.
  • Jalankan flutter pub get.
  • Import package:rg_bridge/rg_bridge.dart.
  • Pastikan Flutter/Dart kompatibel.
  • Lakukan full rebuild setelah menambahkan plugin.

Initialization

  • Buat satu instance RGBridge.
  • Konfigurasi baseUrl.
  • Konfigurasi clientId.

Device

  • Subscribe stream sebelum checkStart().
  • Handle intermediate state.
  • Handle REQUIRES_USER_ACTION.
  • Tunggu terminal result.
  • Panggil checkDispose().
  • Uji hardware pada device fisik.

WebView

  • Initialize session.
  • Register event listener sebelum flow dimulai.
  • Create controller.
  • Load/open WebView.
  • Handle event.
  • Panggil offAllEvents().
  • Dispose controller sesuai lifecycle host.

Form

  • Initialize session.
  • Simpan session selama flow berlangsung.
  • Submit menggunakan API SDK.
  • Handle exception.
  • Re-initialize session jika diperlukan.

17. Compatibility & Versioning

Package menggunakan Semantic Versioning.

Versi yang dibahas pada dokumentasi ini:

0.1.1-rc-1

Gunakan versi package yang eksplisit pada aplikasi agar upgrade SDK dapat dikontrol.

Perubahan API pada versi berikutnya dapat memerlukan penyesuaian pada aplikasi host. Selalu periksa release notes sebelum melakukan upgrade.


18. Troubleshooting

MissingPluginException

Coba:

flutter clean
flutter pub get
flutter run

Lakukan full rebuild setelah plugin native ditambahkan.

Device test timeout

Periksa:

  • device fisik vs emulator;
  • permission;
  • availability hardware;
  • state test;
  • apakah fitur didukung platform/device.

GPS gagal

Periksa:

  • location permission;
  • device fisik;
  • kondisi lokasi/sinyal;
  • accuracy yang tersedia.

WebView blank

Periksa:

  • URL/session yang digunakan;
  • koneksi dan SSL;
  • konfigurasi WebView;
  • lifecycle controller.

Event WebView tidak diterima

Periksa:

  1. listener sudah didaftarkan;
  2. listener didaftarkan sebelum event terjadi;
  3. halaman WebView mengirim event sesuai contract;
  4. channel/event yang digunakan sesuai integrasi.

19. Important Limitations

Developer integrator perlu memperhatikan:

  • Tidak semua hardware tersedia pada setiap platform/device.
  • Emulator tidak merepresentasikan seluruh hardware device fisik.
  • Beberapa capability iOS masih terbatas.
  • REQUIRES_USER_ACTION harus diproses sebagai intermediate state.
  • Lifecycle listener/controller tetap menjadi tanggung jawab host.
  • Retry dan recovery flow pada level aplikasi dapat perlu diimplementasikan oleh host.

20. Integration Golden Path

Jika hanya membutuhkan flow paling sederhana:

INSTALL
  ↓
RGBridge(baseUrl, clientId)
  ↓
┌─────────────────────────────────────┐
│                                     │
│ DEVICE       WEBVIEW        FORM    │
│   │             │             │     │
│ checkXxx()   initSession()  init()  │
│   │             │             │     │
│ stream       onEvent()     submit() │
│   │             │             │     │
│ start        open/load      result  │
│   │             │             │     │
│ result         event        result  │
│                                     │
└──────────────┬──────────────────────┘
               ↓
            CLEANUP
               ↓
     dispose / offAllEvents()

Rule utama

Gunakan public API melalui package:rg_bridge/rg_bridge.dart, kelola lifecycle dari aplikasi host, dan perlakukan result/event SDK sebagai bagian dari state aplikasi.


21. Quick Reference

Initialize

final sdk = RGBridge(
  baseUrl: 'https://api.example.com',
  clientId: 'rg_client_id',
);

Device info

final info = await sdk.device.getDeviceInfo();

Device test

final controller = sdk.device.checkGps();

controller.getResultStream.listen((result) {
  print(result.status);
});

await controller.checkStart();

WebView session

final session = await sdk.webview.initSessionWebView(
  type: 'workflow-type',
  firstName: 'John',
  lastName: 'Doe',
  memberCode: '123456',
);

WebView event

sdk.webview.onEvent((event) {
  print(event.type);
});

Form session

final session = await sdk.formSubmission.initFormSubmission();

Cleanup

sdk.webview.offAllEvents();
controller.checkDispose();

Libraries

rg_bridge