Skip to content

Dart and Flutter

This specification applies to the Dart/Flutter SDK in sdk/flutter/gizclaw and the Flutter App in apps/gizclaw-app. The SDK has GizClaw contract, transport and reusable client capabilities; the App is responsible for product UI, page status and platform integration, and cannot copy the protocol implementation already provided by the SDK.

Dart basic rules

  • Use the standard format generated by dart format and do not manually maintain formatting that conflicts with the formatter.
  • SDK follows package:lints/recommended.yaml, App follows package:flutter_lints/flutter.yaml; the new lint suppression must be limited to the minimum scope and the reason must be explained.
  • library, file, variable and function use lower_snake_case or lowerCamelCase corresponding Dart official convention; type, enum and extension use UpperCamelCase.
  • Keep symbols private by default and only export stable surfaces that SDK users actually need. Public APIs are uniformly exposed from lib/gizclaw.dart, and callers should not rely on lib/src/.
  • Immutable value is preferred to final; only use mutable variables when reassignment is absolutely necessary.
  • Do not use dynamic or unchecked cast to bypass the bounds check of external payload, platform channel and generated message.

SDK Boundaries

  • OpenAPI, Protobuf and RPC Schema are the source of truth for generating Dart messages and registry methods; lib/src/generated/ can only be updated by the generation process.
  • The signaling, WebRTC transport, RPC frame and payload codec each maintain a single responsibility and do not reassemble the protocol frame or duplicate the method name in the App.
  • SDK public methods should return stable Dart types and clearly express error, cancellation, and shutdown semantics; do not unnecessarily leak internal types of providers, WebRTC plugins, or generated code to the app.
  • The stream must define subscription, error, done, and cancellation behaviors. The owner who created the StreamController, peer connection, data channel or subscription must also be responsible for closing it.
  • Future must be await, returned, or handled explicitly; errors in asynchronous callbacks cannot be lost silently.
  • Network, RPC, signaling, and codec inputs are considered untrusted and must handle malformed frames, unknown methods, bad payloads, repeated closes, and connection interruptions.

Flutter App

  • Widget is only responsible for display and interaction; protocol, transport, retry and resource resolution should be left in the SDK or explicit application service.
  • The controller, subscription, animation, timer and SDK connection created by State must be released by ownership in dispose.
  • After await visit BuildContext or check mounted before calling setState to avoid updates after page destruction.
  • The page must have clear loading, empty, error, success, offline and permission-denied status, and cannot use infinite loading to hide failure.
  • Build methods remain side-effect-free; network requests, subscription creation, and persistence writes cannot be implicitly triggered by repeated builds.
  • Platform-specific behavior is managed through explicit adapter or plugin boundaries, and differences are verified for Android, iOS and test environments respectively.
  • Interactive components should provide stable semantics, clickable scope, disabled state, focus/keyboard behavior, and testable widget keys or semantics.

Status and data flow

  • The source of truth for a state must be unique. Widget local state only saves the local display state, and the connection, session and shared resource states are managed by its explicit owner.
  • Do not pass BuildContext, Widget or State objects into the SDK.
  • For real-time streams, the processing methods of ordering, reconnect, duplicate event, terminal state and backpressure should be clarified.
  • Expensive decoding, audio and video conversion or large resource processing cannot block UI isolate; use isolate or native/plugin capabilities when necessary, and define cancellation and resource release.

Testing and Verification

  • SDK test covers signaling, frame, codec, method registry, transport, error path and connection closure.
  • Widget test covers asynchronous callbacks after loading, error, empty, interaction and destruction; use integration test when real plugin or platform life cycle is involved.
  • Rerun the generation tool after changes in Schema or generated code, and confirm that the generated diff is consistent with the source contract.
  • Run when modifying the SDK:
sh
dart format sdk/flutter/gizclaw
flutter analyze sdk/flutter/gizclaw
flutter test sdk/flutter/gizclaw
  • Run when modifying the app:
sh
dart format apps/gizclaw-app
flutter analyze apps/gizclaw-app
flutter test apps/gizclaw-app