offline_webview 1.2.1 copy "offline_webview: ^1.2.1" to clipboard
offline_webview: ^1.2.1 copied to clipboard

A lightweight high-performance Flutter SDK for offline web package loading with URL matching, flow pipeline, WebView integration, monitoring and reporting. Supports iOS/Android/HarmonyOS.

简体中文 | English


offline_webview #

A lightweight high-performance Flutter SDK for offline web package loading.

Features #

  • Offline Package Management: Download, cache, and serve web resources locally
  • URL Matching: Flexible rule-based URL to bisName matching (param mode & rule mode)
  • Flow Pipeline: Extensible chain-of-responsibility processing pipeline
  • WebView Integration: Seamless InAppWebView (iOS/Android/HarmonyOS) integration with screenshot cache and vConsole
  • Performance Monitor: Built-in debug floating panel showing loading timeline comparison
  • Monitoring & Reporting: Built-in logging, monitoring, and data reporting
  • Local Server: Per-package HTTP server on localhost, serving resources without file:// hacks
  • Fastlane CI/CD: One-command build & distribute to Pgyer for iOS/Android
  • HarmonyOS Support: Runs on HarmonyOS (OHOS) via the community-adapted flutter_inappwebview_ohos

Installation #

dependencies:
  offline_webview: ^1.1.0

Quick Start #

1. Start the test server #

cd tool
python3 server.py
# Server auto-detects LAN IP and runs at http://<your-lan-ip>:18730

2. Initialize the SDK #

import 'package:offline_webview/offline_webview.dart';

// Build config (preDownloadAll downloads all available packages from server)
final config = OfflineConfigBuilder()
    .isOpen(true)
    .preDownloadAll(true)
    .build();

// Build params
final params = OfflineParams()
    .config(config)
    .isDebug(true)
    .logBlock((level, message) => print(message))
    .reportBlock((event, bisName, params) => print('Report: $event'))
    .monitorBlock((type, data) => print('Monitor: $type'))
    .requestServer(YourRequest());

await OfflineWebClient.init(params);

3. Use OfflineWebView #

// Param mode: URL contains ?offweb=bisName
OfflineWebView(
  initialUrl: 'https://example.com/page?offweb=my-bis-name',
  enableVConsole: true,  // inject vConsole debug panel
)

// With controller for reload
final controller = OfflineWebViewController();
OfflineWebView(
  initialUrl: 'https://example.com/page?offweb=my-bis-name',
  controller: controller,
  onLoadTiming: (totalMs) => print('Loaded in ${totalMs}ms'),
)

// Reload offline web
controller.reloadOfflineWeb();

4. Implement IOfflineRequest #

class YourRequest extends IOfflineRequest {
  @override
  void requestPackageInfo(
    String bisName,
    String version,
    RequestCallback<OfflinePackageInfo> callback,
  ) async {
    final url = Uri.parse('http://your-server:18730/offweb').replace(
      queryParameters: {'bisName': bisName, 'offlineZipVer': version},
    );
    final response = await http.get(url);
    final json = jsonDecode(response.body);
    callback.onSuccess(OfflinePackageInfo.fromJson(json));
  }

  @override
  void requestAllBisNames(RequestCallback<List<String>> callback) async {
    final response = await http.get(Uri.parse('http://your-server:18730'));
    final json = jsonDecode(response.body);
    final packages = (json['packages'] as List).map((e) => e.toString()).toList();
    callback.onSuccess(packages);
  }
}

Creating Offline Packages #

An offline package is a standard .zip file containing your web resources and a version manifest.

Package structure #

my-package.zip
├── .offweb.json      # Required: version manifest
├── index.html        # Entry point
├── css/
│   └── style.css
├── js/
│   └── app.js
└── images/
    └── logo.png

Version manifest (.offweb.json) #

Place this file at the root of the zip:

{
  "bisName": "my-package",
  "version": "v1"
}

Requirements #

  • .offweb.json must exist at the zip root with bisName and version fields
  • index.html must exist as the entry point
  • All resource paths (CSS, JS, images) should use relative paths
  • H5 pages must support null-origin for cookie/storage (loaded from localhost)

Upload to server #

Place the zip file in the server's packages/ directory, or use the built-in upload page at http://<server-ip>:18730/upload.

Server query API #

When the SDK queries the server, the response format is:

{
  "bisName": "my-package",
  "result": 1,
  "url": "http://server:18730/package?bisName=my-package",
  "refreshMode": 0,
  "version": "v2"
}
Field Description
result -1 = disabled, 0 = same version, 1 = update available
url Download URL for the zip package
refreshMode 0 = normal, 1 = force refresh
version Latest version string

URL Matching #

Param mode #

Append ?offweb=<bisName> to the URL. The SDK automatically intercepts it:

OfflineWebView(
  initialUrl: 'https://example.com/page?offweb=my-bis-name',
)

Rule mode #

Configure OfflineRuleConfig to match URLs by host/path patterns without modifying the URL:

final params = OfflineParams()
    .config(OfflineConfigBuilder().isOpen(true).build())
    .setRule(OfflineRuleConfig(
      rules: [
        OfflineRuleItem(host: 'example.com', path: '/app/*', bisName: 'my-app'),
      ],
    ))
    .requestServer(YourRequest());

Performance Monitor #

The SDK includes a debug-mode performance monitor with a draggable floating panel:

FloatingPerformancePanel(
  child: OfflineWebView(initialUrl: '...'),
)

// Or standalone (OfflineWebView embeds it internally)
FloatingPerformancePanel()
Metric Description
webViewCreatedMs Time from widget creation to WebView ready
firstPaintMs Time to first visual paint
loadCompleteMs Time to page fully loaded
queryMs Offline query phase (offline mode only)
downloadMs Package download phase (offline mode only)
unzipMs Package extraction phase (offline mode only)

Color coding: green (<50ms), blue (<200ms), yellow (<500ms), red (>=500ms).

Configuration #

final config = OfflineConfigBuilder()
    .isOpen(true)                      // Enable/disable offline feature
    .preDownloadAll(true)              // Pre-download all packages from server
    .addPreDownload('bis-name-1')      // Pre-download specific packages
    .addPreDownload('bis-name-2')
    .addDisable('bis-name-3')          // Disable specific packages
    .build();

Local Development Server #

A Python HTTP server is provided for local testing:

cd tool
python3 server.py

Server endpoints:

  • GET / - Server info & registered packages
  • GET /health - Health check
  • GET /offweb?bisName=xxx&offlineZipVer=xxx - Query package update
  • GET /package?bisName=xxx - Download package zip
  • GET /upload - Web upload page
  • POST /upload - Upload zip package
  • GET /demo - Demo HTML page

Architecture #

+-------------------------------------------------------------+
|                     OfflineWebClient                         |
+-------------------------------------------------------------+
                            |
                            v
+-------------------------------------------------------------+
|                    OfflineWebManager                         |
+-------------------------------------------------------------+
                            |
              +-------------+-------------+
              |                           |
              v                           v
+---------------------------+ +-----------------------------+
|   ResourceFlow Pipeline   | |   PerformanceMonitor         |
|  FetchPackageFlow         | |   (singleton, Stream-based)  |
|    -> DownloadFlow        | |   ↳ FloatingPerformancePanel |
|    -> ParsePackageFlow    | +-----------------------------+
|    -> ReplaceResFlow      |
+---------------------------+
              |
              v
+-------------------------------------------------------------+
|                   OfflineWebView                             |
|   (InAppWebView + LocalServer + WebViewPreloadPool)          |
+-------------------------------------------------------------+

CI/CD with Fastlane #

bundle install

# Build & upload iOS
bundle exec fastlane build_ios

# Build & upload Android
bundle exec fastlane build_android

Platform Support #

  • iOS (InAppWebView / WKWebView)
  • Android (InAppWebView / WebView)
  • HarmonyOS / OHOS (InAppWebView / ArkWeb, via community adaptation — see HarmonyOS Support)
  • Flutter Web (limited)

HarmonyOS Support #

HarmonyOS (OHOS) is supported through the OpenHarmony community adaptation of flutter_inappwebview. The official plugin does not yet declare the ohos platform, so this package overrides it via dependency_overrides in pubspec.yaml:

dependency_overrides:
  flutter_inappwebview:
    git:
      url: https://gitcode.com/openharmony-sig/flutter_inappwebview.git
      path: flutter_inappwebview
      ref: br_v6.1.5_ohos
  path_provider:
    git:
      url: https://gitcode.com/openharmony-tpc/flutter_packages.git
      path: packages/path_provider/path_provider
      ref: br_path_provider-v2.1.5_ohos

The community fork is based on the official v6.1.5 plus an OHOS implementation, so it stays fully compatible with Android/iOS/macOS/Web — existing platforms are unaffected. The git repository uses Git LFS; install git-lfs and set GIT_LFS_SKIP_SMUDGE=1 on first flutter pub get (the SDK's Dart code does not depend on the LFS-tracked binaries).

Running the example on HarmonyOS #

  1. Install the Flutter for OpenHarmony SDK and DevEco Studio (see flutter_flutter_ohos).
  2. cd example && flutter pub get
  3. flutter build hap (or flutter run on a connected HarmonyOS device/emulator).
  4. The OHOS app declares ohos.permission.INTERNET (required by the local HTTP server and package downloads) in example/ohos/entry/src/main/module.json5.

The OHOS adaptation of flutter_inappwebview marks a few APIs as not supported (e.g. keepAlive, onLoadResource, onCreateWindow, onDownloadStartRequest). This SDK only forwards those callbacks to the host app, so they simply won't fire on OHOS unless the app passes them — no breakage. See the support matrix.

Publishing note: dependency_overrides with git references cannot be published to pub.dev. Remove the dependency_overrides block before publishing; HarmonyOS consumers add it back in their own app. See docs/harmonyos_support.md for details.

License #

MIT License - see LICENSE file

1
likes
120
points
20
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A lightweight high-performance Flutter SDK for offline web package loading with URL matching, flow pipeline, WebView integration, monitoring and reporting. Supports iOS/Android/HarmonyOS.

Repository (GitHub)
View/report issues
Contributing

License

MIT (license)

Dependencies

archive, flutter, flutter_inappwebview, http, mime, path, path_provider

More

Packages that depend on offline_webview