mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-07-05 17:13:44 +00:00
Apple iOS, iPadOS & macOS Clients For Meshtastic
- Swift 92.9%
- HTML 3.9%
- Shell 2.4%
- PowerShell 0.4%
- Python 0.2%
- Other 0.2%
* fix: stop SwiftData SIGTRAP in node list rows and message relay display The node-list rows remained the top crash on the current App Store release (Error Tracking issue ab285602 — SIGTRAP in NodeListItem.swift, faulting on the NodeInfoEntity.user / UserEntity.userNode relationship accessors), with message relay display close behind (MessageEntityExtension.swift). #1991 guarded the row bodies with `modelContext != nil && !isDeleted` and snapshotted position/metrics, but the bodies still read `node.user?...` and many `node.*` persisted properties directly on every re-evaluation. `isDeleted` does not catch a model invalidated by a bulk delete or a delete on another context (clearStaleNodes / clearDatabase / live ingestion): the instance reads `isDeleted == false` while its backing row is gone, so a retained List row that re-evaluates before the List drops it reads a zombie @Model and SwiftData fatally traps. Fix: render the rows from a value-type snapshot captured while the node is live, so a re-evaluation after the model dies never touches the live object. - NodeListRowSummary now captures the full row (name/short name, key status, role, favorite, signed, status message, last heard, online, hops, snr/rssi, channel, mqtt, store-forward, battery, position, log availability) as plain values. NodeListItem/NodeListItemCompact memoize one in @State and render from it; the live node is read only on first appearance (while valid) and in a guarded refresh keyed to lastHeard. No relationship reads remain on the re-evaluation path. - MessageEntityExtension.relayDisplay() guards `self` liveness before reading, filters the fetched users to live ones, and reads the userNode relationship through a new `UserEntity.liveUserNode` that returns nil for a deleted/zombie user instead of trapping. Verified: builds for simulator and Mac Catalyst; launched with 5,000/250 seeded nodes in both standard and compact density with no crash and no visual change to the rows. * fix: address CodeRabbit review on #2027 - Gate the .task(id:) identity on node liveness in NodeListItem and NodeListItemCompact: the id expression reads node.lastHeard during body construction, which could fault on an invalidated model before the task body's guard runs. Read lastHeard only when the node is still live. - Fix the relay-name selection comparator in MessageEntityExtension: the min(by:) closure returned false whenever either side's hopsAway was nil, which isn't a strict weak ordering and let a nil-hops user win by array position. Filter to rankable (non-nil hops) candidates before min, and fall back to the first match when none have hops. |
||
|---|---|---|
| .claude/skills | ||
| .github | ||
| .skills/design-audit | ||
| .specify | ||
| .standards | ||
| .vscode | ||
| ci_scripts | ||
| docs | ||
| itak-example-data-package | ||
| Meshtastic | ||
| Meshtastic Watch App | ||
| Meshtastic.xcodeproj | ||
| Meshtastic.xcworkspace | ||
| MeshtasticProtobufs | ||
| MeshtasticTests | ||
| protobufs@06d729a1eb | ||
| scripts | ||
| Settings.bundle | ||
| specs | ||
| Widgets | ||
| .gitignore | ||
| .gitmodules | ||
| .swiftlint-precommit.yml | ||
| .swiftlint.yml | ||
| CLAUDE.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| Localizable.xcstrings | ||
| meshtastic-1080x1080.png | ||
| pr-description.md | ||
| README.md | ||
| RELEASING.md | ||
| test-bellevue-bbox.geojson | ||
Meshtastic Apple
iOS · iPadOS · macOS · watchOS · visionOS
Open-source LoRa mesh networking for Apple platforms
User Guide • Developer Guide • Getting Started • License
Overview
SwiftUI client applications for iOS, iPadOS, macOS, visionOS and watchOS that communicate with Meshtastic LoRa mesh radio devices over Bluetooth, TCP, and serial.
Key Features
- Mesh messaging — channel and direct messages over LoRa, with CarPlay and Siri support for hands-free use while driving
- Live map — node positions, waypoints, and GeoJSON overlays with offline tile support
- Node management — signal meter, device roles, encryption status, trace routes, and telemetry
- Full radio configuration — LoRa, channels, security, Bluetooth, device, display, network, position, power, and all module configs
- Apple Watch companion — node list and fox hunt compass on your wrist
- TAK integration — CoT position relay and TAK server connectivity
- In-app documentation — full offline help browser with dark-mode support and AI-powered search (iOS 26+)
What's New
For Users
- May 2026 — Docs Translation Pipeline — Community-sourced translations: each device contributes on-device translations that are shared via a CDN feed so future users get instant localized docs.
- May 2026 — Automatic Docs Translation — On iOS 26+, in-app documentation is automatically translated into your device language using the Apple Translation framework.
- May 2026 — Message Formatting Toolbar — Markdown formatting toolbar in the message compose UI (iOS 18+/macOS 15+). Apply bold, italic, strikethrough, code, and links with one tap; live preview shows rendered output before sending.
- May 2026 — Node List Layout — Switchable Complete and Compact density modes for the node list. Compact mode reduces row height for large meshes (100+ nodes) with configurable detail toggles.
- May 2026 — Signal Meter — New deep-dive page explaining how the LoRa signal quality meter works, why negative SNR values are normal, and how to interpret RSSI vs. SNR for your mesh.
- May 2026 — Apple Watch App — New page covering the companion watch app: node list, fox hunt compass, and how it syncs with your iPhone.
- Apr 2026 — Local Mesh Discovery — A diagnostic tool that cycles through multiple LoRa modem presets to audit the local RF environment, collecting nodes and telemetry across presets with configurable dwell times.
For Developers
- May 2026 — Testing — Snapshot test conventions established: consolidated multi-state views into single combined images (light + dark pairs), use
assertViewSnapshothelper with explicitwidth/heightandtransparent: truefor icon snapshots. - May 2026 — Architecture — In-app documentation system added: markdown source under
docs/is converted to HTML byscripts/build-docs.shand bundled atMeshtastic/Resources/docs/. Navigation is driven byindex.json. - May 2026 — App Docs (Jekyll + In-App) — Full offline documentation system: markdown source under
docs/, GitHub Pages Jekyll site, in-app WKWebView browser with dark-mode support, and AI-powered search via Foundation Models (iOS 26+).
Getting Started
- Clone the repo.
git clone git@github.com:meshtastic/Meshtastic-Apple.git - Open the local directory.
cd Meshtastic-Apple - Set up git hooks to automatically lint the project when you commit changes.
./scripts/setup-hooks.sh - Open
Meshtastic.xcworkspaceopen Meshtastic.xcworkspace - Build and run the
Meshtastictarget.
See docs/developer/contributing.md for code style, branch naming, PR checklist, and all other contribution guidelines.
Documentation
| Resource | Link |
|---|---|
| User Guide | https://meshtastic.github.io/Meshtastic-Apple/ |
| Developer Guide | https://meshtastic.github.io/Meshtastic-Apple/developer.html |
| In-app | Settings → Help & Documentation |
Release Process
For more information on how a new release of Meshtastic is managed, please refer to RELEASING.md.
License
This project is licensed under the GPL v3. See the LICENSE file for details.