Skip to content

Add firmware update notifications#2033

Merged
garthvh merged 5 commits into
meshtastic:mainfrom
RCGV1:codex/update-firmware-notifications
Jul 16, 2026
Merged

Add firmware update notifications#2033
garthvh merged 5 commits into
meshtastic:mainfrom
RCGV1:codex/update-firmware-notifications

Conversation

@RCGV1

@RCGV1 RCGV1 commented Jul 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Notify after connecting to a node when its firmware is older than the latest stable release, while suppressing repeat reminders per node, PlatformIO target, and stable version.
  • Route notification taps to Settings -> Firmware Updates (meshtastic:///settings/firmwareUpdates).
  • Split the notification/Connect-page copy by install method: app-supported OTA hardware points users to Firmware Updates; hardware that needs an external updater tells users to use Meshtastic Flasher instead.
  • Add a separate Connect-page firmware update notice below the connected radio card, plus docs/tests for the behavior.
  • Address CodeRabbit review feedback by awaiting the connect-time notifier, propagating cancellation, logging SwiftData fetch failures, and refining generated docs keywords.

Screenshot

Connect firmware update notice

Notes

This is split out from the broader OTA hardening work so it can be reviewed independently from ESP32/nRF flashing changes. The Connect-page notice currently uses the latest stable firmware data, matching the notification policy.

Validation

  • bash scripts/build-docs.sh --output Meshtastic/Resources/docs
  • git diff --check
  • XcodeBuildMCP simulator tests: MeshtasticTests/FirmwareUpdateNotificationPolicyTests and MeshtasticTests/FirmwareUpdateNotifierTests passed, 12/12.
  • XcodeBuildMCP simulator build/run for scheme Meshtastic on iPhone 17 succeeded.

Summary by CodeRabbit

  • New Features
    • Added local firmware update reminders for connected nodes when firmware is behind the latest stable release.
    • Connect screen can now show an in-app prompt to open Firmware Updates (OTA) or guide to external flashing.
  • Bug Fixes
    • Reminders are deduplicated based on node, hardware target, and stable version.
    • Improved notification-tap routing for OTA vs flasher destinations.
  • Documentation
    • Updated firmware documentation for reminder behavior and what happens when OTA isn’t supported.
  • Tests
    • Added unit tests covering reminder policy, notification generation, and suppression.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d36aec3-bb08-4f69-9f61-93740097e0b8

📥 Commits

Reviewing files that changed from the base of the PR and between 74e5ecf and d745b84.

📒 Files selected for processing (7)
  • Meshtastic.xcodeproj/project.pbxproj
  • Meshtastic/Extensions/UserDefaults.swift
  • Meshtastic/Resources/docs/index.json
  • Meshtastic/Resources/docs/markdown/user/firmware.md
  • Meshtastic/Resources/docs/user/firmware.html
  • Meshtastic/Views/Connect/Connect.swift
  • docs/user/firmware.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • Meshtastic/Resources/docs/markdown/user/firmware.md
  • Meshtastic/Resources/docs/user/firmware.html
  • docs/user/firmware.md
  • Meshtastic/Extensions/UserDefaults.swift
  • Meshtastic.xcodeproj/project.pbxproj
  • Meshtastic/Views/Connect/Connect.swift

📝 Walkthrough

Walkthrough

Adds firmware update notification logic, connect-flow and UI wiring, deduplication persistence, tests, project registration, and documentation/index updates.

Changes

Firmware Update Notification

Layer / File(s) Summary
Notification policy and persistence
Meshtastic/Model/Firmware/FirmwareUpdateNotificationPolicy.swift, Meshtastic/Extensions/UserDefaults.swift, MeshtasticTests/FirmwareUpdateNotificationPolicyTests.swift
Adds install-method selection, version normalization, update checks, notification-key generation, persisted suppression keys, and policy tests.
Notifier orchestration and tests
Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift, MeshtasticTests/FirmwareUpdateNotifierTests.swift
Derives firmware candidates and notices, refreshes stale firmware data, queries SwiftData, schedules local notifications, and tests notifier behavior.
Connect flow and view wiring
Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift, Meshtastic/Views/Connect/Connect.swift, Meshtastic/MeshtasticAppDelegate.swift
Runs notification checks during connection, displays firmware notices, refreshes connected state, and routes firmware-update actions.
Project registration
Meshtastic.xcodeproj/project.pbxproj
Registers firmware-update sources and tests in Xcode groups, references, targets, and build phases.
Docs and keyword index updates
Meshtastic/Resources/docs/..., docs/user/firmware.md, scripts/build-docs.sh
Documents firmware notifications, updates documentation metadata, and expands keyword stop words.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AccessoryManager
  participant FirmwareUpdateNotifier
  participant LocalNotificationManager
  participant UserDefaults

  AccessoryManager->>FirmwareUpdateNotifier: notifyIfNeeded(accessoryManager)
  FirmwareUpdateNotifier->>LocalNotificationManager: schedule notification
  FirmwareUpdateNotifier->>UserDefaults: record notification key
Loading
sequenceDiagram
  participant ConnectView
  participant FirmwareUpdateNotifier
  participant Router
  participant UIApplication

  ConnectView->>FirmwareUpdateNotifier: notice(accessoryManager)
  FirmwareUpdateNotifier-->>ConnectView: FirmwareUpdateNotice
  ConnectView->>Router: route meshtastic URL
  ConnectView->>UIApplication: open flasher URL
Loading

Suggested labels: skip-docs-check

Suggested reviewers: garthvh

Poem

A rabbit found a firmware flare,
And sent one carrot-light through air.
OTA hops or flasher flight,
Keys keep reminders tucked just right. 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding firmware update notifications.
Description check ✅ Passed The description covers the feature, rationale, testing, screenshot, and validation details, with only the checklist/template headings missing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
Meshtastic/Resources/docs/index.json (1)

129-154: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Some keyword entries add little search value.

Generic terms like "not", "over", "usually", "during" are unlikely to help users find this doc via search and dilute the keyword list.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Meshtastic/Resources/docs/index.json` around lines 129 - 154, The keyword
list in the index entry includes several low-value generic terms that dilute
search relevance. Update the keywords associated with the relevant document in
the index data to remove generic words like “not”, “over”, “usually”, and
“during”, keeping only terms that meaningfully describe the doc and improve
discoverability. Use the existing keyword array for this document as the place
to trim and refine the search terms.
Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift (1)

132-158: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Silently swallowed fetch errors via try?.

Both hardwareSupportingAppOTA and latestStableFirmwareVersion discard SwiftData fetch errors with try?, unlike refreshFirmwareDataIfStale above which logs failures via Logger.services.warning. A genuine query failure here silently suppresses the entire notification for that connection with no diagnostic trail.

♻️ Suggested logging on fetch failure
 		descriptor.fetchLimit = 1
-		guard let hardware = try? context.fetch(descriptor).first,
-		      FirmwareUpdateNotificationPolicy.supportsAppOTA(architecture: hardware.architecture) else {
+		let fetchResult = Result { try context.fetch(descriptor) }
+		guard let hardware = (try? fetchResult.get())?.first,
+		      FirmwareUpdateNotificationPolicy.supportsAppOTA(architecture: hardware.architecture) else {
+			if case .failure(let error) = fetchResult {
+				Logger.services.warning("Failed to fetch hardware for OTA check: \(error.localizedDescription, privacy: .public)")
+			}
 			return nil
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift` around lines 132 -
158, The fetches in hardwareSupportingAppOTA and latestStableFirmwareVersion are
swallowing SwiftData errors with try?, which hides query failures. Update these
helpers to handle fetch exceptions explicitly, using the existing
Logger.services.warning pattern from refreshFirmwareDataIfStale to log the
failure with context (including the platformioTarget or stable release lookup)
and then return nil. Keep the behavior of returning nil on failure, but make
sure the error is observable through logging.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Meshtastic/Accessory/Accessory` Manager/AccessoryManager+Connect.swift:
- Around line 229-232: The firmware notification is launched as an untracked
fire-and-forget Task in AccessoryManager+Connect, so it can overlap later
connect steps and outlive disconnects. Update the Step 7 flow around the Task {
`@MainActor` in ... } call in AccessoryManager connect handling to either await
the notification or store and cancel the task as part of connection lifecycle
management, and ensure FirmwareUpdateNotifier.notifyIfNeeded propagates
cancellation with Task.checkCancellation() so it stops safely on teardown.

In `@Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift`:
- Around line 84-116: notifyIfNeeded(accessoryManager:) is fire-and-forget and
should stop when the parent Task is cancelled. Add a cancellation check
immediately after the await refreshFirmwareDataIfStale() call, before any
SwiftData fetches or notification scheduling, so the flow exits early if the
connection session ended. Keep the fix in FirmwareUpdateNotifier.notifyIfNeeded
and ensure no later use of accessoryManager, getNodeInfo, or
LocalNotificationManager happens after cancellation.

---

Nitpick comments:
In `@Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift`:
- Around line 132-158: The fetches in hardwareSupportingAppOTA and
latestStableFirmwareVersion are swallowing SwiftData errors with try?, which
hides query failures. Update these helpers to handle fetch exceptions
explicitly, using the existing Logger.services.warning pattern from
refreshFirmwareDataIfStale to log the failure with context (including the
platformioTarget or stable release lookup) and then return nil. Keep the
behavior of returning nil on failure, but make sure the error is observable
through logging.

In `@Meshtastic/Resources/docs/index.json`:
- Around line 129-154: The keyword list in the index entry includes several
low-value generic terms that dilute search relevance. Update the keywords
associated with the relevant document in the index data to remove generic words
like “not”, “over”, “usually”, and “during”, keeping only terms that
meaningfully describe the doc and improve discoverability. Use the existing
keyword array for this document as the place to trim and refine the search
terms.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3e118829-e584-4f1f-b67f-892d1806abc2

📥 Commits

Reviewing files that changed from the base of the PR and between 0422cb5 and 3c58157.

📒 Files selected for processing (11)
  • Meshtastic.xcodeproj/project.pbxproj
  • Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift
  • Meshtastic/Extensions/UserDefaults.swift
  • Meshtastic/Model/Firmware/FirmwareUpdateNotificationPolicy.swift
  • Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift
  • Meshtastic/Resources/docs/index.json
  • Meshtastic/Resources/docs/markdown/user/firmware.md
  • Meshtastic/Resources/docs/user/firmware.html
  • MeshtasticTests/FirmwareUpdateNotificationPolicyTests.swift
  • MeshtasticTests/FirmwareUpdateNotifierTests.swift
  • docs/user/firmware.md

Comment thread Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift Outdated
@RCGV1
RCGV1 marked this pull request as ready for review July 4, 2026 21:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift (1)

204-231: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Step 7 has no timeout despite now doing a potentially network-bound call.

Unlike Steps 1 (timeout: .seconds(5)), 3 (timeout: .seconds(30)), and 5 (timeout: .seconds(10.0)), Step 7 has no explicit timeout. FirmwareUpdateNotifier.notifyIfNeeded can trigger refreshFirmwareDataIfStale()MeshtasticAPI.shared.refreshFirmwareAPIData() (once per 24h per node) on the first connect after staleness. If that network call hangs without its own timeout, this blocks Step 7 — and thus Step 8 (MQTT/location init) and the overall connect() completion — indefinitely.

🔧 Suggested fix: add an explicit timeout to Step 7
-			// Step 7: Update UI and status to connected
-			Step { `@MainActor` _ in
+			// Step 7: Update UI and status to connected
+			Step(timeout: .seconds(15)) { `@MainActor` _ in
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Meshtastic/Accessory/Accessory` Manager/AccessoryManager+Connect.swift around
lines 204 - 231, Step 7 in AccessoryManager+Connect.swift can block indefinitely
because FirmwareUpdateNotifier.notifyIfNeeded may perform a network-bound
refresh without an explicit timeout. Update the Step { `@MainActor` _ in ... }
block to use a timeout consistent with earlier steps, and make sure the timeout
wraps the FirmwareUpdateNotifier.notifyIfNeeded(accessoryManager:) call so
connect() can continue to Step 8 if the refresh hangs.
🧹 Nitpick comments (2)
Meshtastic/Views/Connect/Connect.swift (2)

693-726: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider hiding the decorative warning icon from VoiceOver.

.accessibilityElement(children: .combine) merges child labels; the exclamationmark.triangle.fill and chevron.right images have no explicit accessibility treatment and may add extraneous symbol-name announcements alongside the combined text and hint.

♻️ Optional: mark decorative icons as hidden
 				Image(systemName: "exclamationmark.triangle.fill")
 					.font(.title3)
 					.foregroundColor(.orange)
 					.padding(.top, 2)
+					.accessibilityHidden(true)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Meshtastic/Views/Connect/Connect.swift` around lines 693 - 726, The
`FirmwareUpdateConnectNotice` button is combining child accessibility labels, so
the decorative `Image` icons can still introduce unwanted symbol-name
announcements. Update the accessibility treatment in
`FirmwareUpdateConnectNotice.body` by hiding the non-informational
`exclamationmark.triangle.fill` and `chevron.right` images from VoiceOver while
keeping the combined label and hint on the `Button`.

561-606: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant .subscribed guard across two functions.

refreshConnectedNodeState() (lines 563-568) already gates on accessoryManager.state == .subscribed before calling refreshFirmwareUpdateNotice() (line 589), which then re-checks the same condition (line 600) since it has no other caller shown in this file. Harmless, but worth consolidating for clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Meshtastic/Views/Connect/Connect.swift` around lines 561 - 606, The
`.subscribed` check is duplicated between `refreshConnectedNodeState()` and
`refreshFirmwareUpdateNotice()`, so consolidate the state gating for clarity.
Update `refreshFirmwareUpdateNotice()` to assume the caller has already
validated `accessoryManager.state` (or move the guard to a single shared entry
point), and keep the existing behavior of clearing `firmwareUpdateNotice` only
when the state is not subscribed. Use the `refreshConnectedNodeState` and
`refreshFirmwareUpdateNotice` methods to locate the duplicated guard logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift`:
- Around line 118-136: The cancellation checks in
notifyIfNeeded(accessoryManager:) can still throw after the accessory has
already reached .subscribed, which can incorrectly bubble into
AccessoryManager.connect() and trigger closeConnection(). Update
FirmwareUpdateNotifier.notifyIfNeeded so cancellation is handled internally as a
best-effort path, either by avoiding propagation from the
Task.checkCancellation() points or by catching cancellation around the
firmware-notification work, while keeping the successful connect state intact.

---

Outside diff comments:
In `@Meshtastic/Accessory/Accessory` Manager/AccessoryManager+Connect.swift:
- Around line 204-231: Step 7 in AccessoryManager+Connect.swift can block
indefinitely because FirmwareUpdateNotifier.notifyIfNeeded may perform a
network-bound refresh without an explicit timeout. Update the Step { `@MainActor`
_ in ... } block to use a timeout consistent with earlier steps, and make sure
the timeout wraps the FirmwareUpdateNotifier.notifyIfNeeded(accessoryManager:)
call so connect() can continue to Step 8 if the refresh hangs.

---

Nitpick comments:
In `@Meshtastic/Views/Connect/Connect.swift`:
- Around line 693-726: The `FirmwareUpdateConnectNotice` button is combining
child accessibility labels, so the decorative `Image` icons can still introduce
unwanted symbol-name announcements. Update the accessibility treatment in
`FirmwareUpdateConnectNotice.body` by hiding the non-informational
`exclamationmark.triangle.fill` and `chevron.right` images from VoiceOver while
keeping the combined label and hint on the `Button`.
- Around line 561-606: The `.subscribed` check is duplicated between
`refreshConnectedNodeState()` and `refreshFirmwareUpdateNotice()`, so
consolidate the state gating for clarity. Update `refreshFirmwareUpdateNotice()`
to assume the caller has already validated `accessoryManager.state` (or move the
guard to a single shared entry point), and keep the existing behavior of
clearing `firmwareUpdateNotice` only when the state is not subscribed. Use the
`refreshConnectedNodeState` and `refreshFirmwareUpdateNotice` methods to locate
the duplicated guard logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a3a636a5-f8c3-4abc-8501-af793e82ebe5

📥 Commits

Reviewing files that changed from the base of the PR and between 3c58157 and bbc464f.

⛔ Files ignored due to path filters (1)
  • docs/assets/screenshots/connectFirmwareUpdateNotice.png is excluded by !**/*.png
📒 Files selected for processing (11)
  • Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift
  • Meshtastic/Model/Firmware/FirmwareUpdateNotificationPolicy.swift
  • Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift
  • Meshtastic/Resources/docs/index.json
  • Meshtastic/Resources/docs/markdown/user/firmware.md
  • Meshtastic/Resources/docs/user/firmware.html
  • Meshtastic/Views/Connect/Connect.swift
  • MeshtasticTests/FirmwareUpdateNotificationPolicyTests.swift
  • MeshtasticTests/FirmwareUpdateNotifierTests.swift
  • docs/user/firmware.md
  • scripts/build-docs.sh
✅ Files skipped from review due to trivial changes (4)
  • docs/user/firmware.md
  • Meshtastic/Resources/docs/user/firmware.html
  • scripts/build-docs.sh
  • Meshtastic/Resources/docs/markdown/user/firmware.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • MeshtasticTests/FirmwareUpdateNotificationPolicyTests.swift
  • Meshtastic/Model/Firmware/FirmwareUpdateNotificationPolicy.swift

Comment thread Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
Meshtastic/MeshtasticAppDelegate.swift (1)

189-195: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Consider handling the open(url:) result.

UIApplication.shared.open(url) is fire-and-forget here; if the flasher URL fails to open (e.g., no browser available in some restricted environment), there's no logging of failure. Since the branch already logs on the unsupported-URL path, consider adding a completion handler for symmetry/observability.

♻️ Optional improvement
-			} else if targetValue == FirmwareUpdateNotifier.flasherTarget && url.absoluteString == FirmwareUpdateNotifier.flasherPath {
-				UIApplication.shared.open(url)
+			} else if targetValue == FirmwareUpdateNotifier.flasherTarget && url.absoluteString == FirmwareUpdateNotifier.flasherPath {
+				UIApplication.shared.open(url) { success in
+					if !success {
+						Logger.services.error("Failed to open flasher URL: \(deepLink, privacy: .public)")
+					}
+				}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Meshtastic/MeshtasticAppDelegate.swift` around lines 189 - 195, The flasher
URL branch in MeshtasticAppDelegate’s URL handling ignores the result of
UIApplication.shared.open(url), so failures are never observed. Update the
open(url:) call to use its completion handler and log when opening fails,
keeping the same style as the unsupported-URL Logger.services.error path. Use
the existing URL-routing branch and
FirmwareUpdateNotifier.flasherTarget/FirmwareUpdateNotifier.flasherPath checks
to locate the fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@Meshtastic/MeshtasticAppDelegate.swift`:
- Around line 189-195: The flasher URL branch in MeshtasticAppDelegate’s URL
handling ignores the result of UIApplication.shared.open(url), so failures are
never observed. Update the open(url:) call to use its completion handler and log
when opening fails, keeping the same style as the unsupported-URL
Logger.services.error path. Use the existing URL-routing branch and
FirmwareUpdateNotifier.flasherTarget/FirmwareUpdateNotifier.flasherPath checks
to locate the fix.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dd97eb65-2f09-414e-af84-7d129f20549b

📥 Commits

Reviewing files that changed from the base of the PR and between 61d8dee and 74e5ecf.

📒 Files selected for processing (4)
  • Meshtastic/MeshtasticAppDelegate.swift
  • Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift
  • Meshtastic/Views/Connect/Connect.swift
  • MeshtasticTests/FirmwareUpdateNotifierTests.swift
🚧 Files skipped from review as they are similar to previous changes (2)
  • Meshtastic/Model/Firmware/FirmwareUpdateNotifier.swift
  • Meshtastic/Views/Connect/Connect.swift

# Conflicts:
#	Meshtastic/Extensions/UserDefaults.swift
#	Meshtastic/Resources/docs/index.json
#	Meshtastic/Views/Connect/Connect.swift
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants