Thank you for helping improve Universal BLE. This document describes how we work in this repository and what we expect from contributions.
Use GitHub Issues. Include the platform (Android, iOS, macOS, Windows, Linux, Web), Flutter/Dart versions, and a minimal way to reproduce the problem when possible.
- Open PRs against the
mainbranch. - Keep changes focused: one logical concern per PR is easier to review than a large mixed refactor.
- Update
CHANGELOG.mdwhen the change is user-visible (new behavior, fixes, or breaking API changes). Follow the existing bullet style (* …,* BREAKING CHANGE: …where appropriate). - Do not commit secrets, local paths, or generated build artifacts unrelated to the change.
Requirements are defined in pubspec.yaml (Dart SDK and Flutter). Use a stable Flutter channel unless a maintainer asks otherwise.
From the repo root:
flutter pub getThese mirror .github/workflows/pull_request.yml:
flutter analyze
flutter test
flutter test --platform chromeFix any analyzer issues. The project uses flutter_lints via analysis_options.yaml (which includes package:flutter_lints/flutter.yaml).
Format Dart code with the SDK formatter:
dart format .If you only touched specific files, you may format those paths instead of the whole tree.
Host–native APIs are defined in pigeon/universal_ble.dart. If you change that file, regenerate outputs and include them in the same PR:
./build_pigeon.shThat runs dart run pigeon --input pigeon/universal_ble.dart and formats lib/src/universal_ble.g.dart. Regenerated Kotlin, Swift, and C++ files land under android/, darwin/, and windows/ as configured in the Pigeon @ConfigurePigeon block—keep those in sync with the Dart definitions.
- Dart: Follow effective Dart style, existing naming in
lib/, and analyzer rules. Prefer extending existing patterns (platform interface → pigeon channel → native implementations) over new parallel abstractions unless discussed first. - Native: Match the style and structure of the surrounding file on each platform (Kotlin, Swift, C++). When a Pigeon API changes, update every generated implementation and any hand-written glue so all targets stay consistent.
- Tests: Add or extend tests under
test/when behavior is non-trivial or regression-prone. Useflutter_testlike the existing suite. - Example: If the change affects how integrators use the plugin, consider updating the
example/app so it stays a working reference.
- Single-platform features: Prefer not adding a new public API when only one platform can implement it, unless none of the existing APIs can be extended or adapted to cover the behavior. For example, something like Android-only
requestConnectionPriorityshould only become its own method ifconnect,platformConfig, or another existing entry point cannot reasonably subsume it. - Single-platform parameters: When a value applies to one platform only, attach it via a platform-scoped bag (for example
startScantakes an optionalplatformConfigobject for options that only affect a given OS). That keeps the main method signature stable and makes it obvious which settings are platform-specific. - Shared parameters: If more than one platform supports the same option, add it as a normal method parameter on the shared API. Document that implementations on platforms without that capability must ignore the parameter (no-op or documented limitation).
By contributing, you agree that your contributions will be licensed under the same terms as the project: BSD 3-Clause License.