Thank you for contributing to Meshtastic Apple! Please read this guide before opening a PR.
brew install swiftlint)Run ./scripts/setup-hooks.sh once after cloning to install the pre-commit SwiftLint hook.
The app ships a built-in Help & Documentation browser, a Jekyll site on GitHub Pages, and documentation is also published to the main meshtastic.org site.
| Resource | Location |
|---|---|
| Meshtastic.org | meshtastic.org/docs/category/apple-apps |
| GitHub Pages | meshtastic.github.io/Meshtastic-Apple |
| In-app | Settings → Help & Documentation |
| Deep link | meshtastic:///settings/helpDocs |
Source markdown lives under docs/user/ and docs/developer/. To rebuild the bundled HTML after editing any markdown:
bash scripts/build-docs.sh --output Meshtastic/Resources/docs
Commit the regenerated files under Meshtastic/Resources/docs/ with your PR.
Branch from main (trunk-based development). Use descriptive names:
feat/bluetooth-reconnect-improvements
fix/crash-on-ble-disconnect
docs/update-mqtt-guide
chore/update-protobufs
Use imperative mood subject lines:
Fix crash when BLE device disconnects
Add TAK CoT position relay support
Update protobufs to v2.7
Explain what changed and why in the body. Keep subject lines under 72 characters.
⌘U in Xcode)docs/developer/deep-links.mdVersionedSchema and MigrationStage./scripts/gen_protos.sh and builtprint(). SwiftLint enforces this.// MARK: - to separate logical sections.guard for early exit; avoid deeply nested if.| Check | Warning | Error |
|---|---|---|
| Line length | 400 | — |
| File length | 3500 | — |
| Type body length | 400 | — |
| Function body length | 200 | — |
| Cyclomatic complexity | 60 | — |
| Type name length | 60 | 70 |
#if !targetEnvironment(macCatalyst)#if canImport(UIKit)if #available(iOS 26, *) { ... }./scripts/gen_protos.sh bumps the protobufs/ submodule and regenerates
MeshtasticProtobufs/Sources/ in one step — no separate git submodule update:
./scripts/gen_protos.sh # pull protobufs origin/master, then regenerate
./scripts/gen_protos.sh develop # pull a different branch, tag or commit
./scripts/gen_protos.sh --no-pull # regenerate against the currently pinned protos
Only protoc needs to be installed (brew install protobuf). The script builds
protoc-gen-swift itself, from the swift-protobuf version pinned in
MeshtasticProtobufs/Package.resolved — never generate with a Homebrew
protoc-gen-swift. Brew's plugin drifts older than what the project links and
silently downgrades every generated file, dropping Sendable,
Swift.CaseIterable/allCases and the // swiftlint:disable all header, which
removes concurrency conformance and makes SwiftLint lint generated code.
After regenerating:
FirmwareEditions, RegionCodes, and friends map by raw value, so an
unmapped case silently falls back to a default instead of failing to compile.See RELEASING.md in the repository root for the full release checklist and App Store submission process.