Skip to content

Fix async_without_await SwiftLint warnings#1095

Open
timbms wants to merge 669 commits intodevelopfrom
fix/async-without-await
Open

Fix async_without_await SwiftLint warnings#1095
timbms wants to merge 669 commits intodevelopfrom
fix/async-without-await

Conversation

@timbms
Copy link
Copy Markdown
Contributor

@timbms timbms commented Mar 8, 2026

Summary

  • Enables the async_without_await opt-in SwiftLint rule
  • Removes accidental async from functions that never await: log fetchers, sitemap helpers, notification attachment, actor persistence helpers, test functions
  • Adds // swiftlint:disable:next async_without_await where async is required by a protocol or delegate (Intent handlers, WKNavigationDelegate, ClientCertificateManagerDelegate, etc.)
  • Cleans up all corresponding await call sites for functions that became synchronous
  • Fixes a follow-up: actor-isolated saveTrustedCertificates() called from nonisolated init — restored Task { await self.saveTrustedCertificates() } pattern (actor hop provides async semantics without needing the method itself to be async)

Test plan

  • SwiftLint reports zero async_without_await violations in project sources
  • Build succeeds on iOS and watchOS targets
  • Certificate store migration path still saves on first launch with legacy data

timbms and others added 30 commits January 19, 2026 08:16
Signed-off-by: Tim Bert <5411131+timbms@users.noreply.github.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
  1. Replaced foregroundColor() with foregroundStyle() (35 occurrences across 25+ files)

  - All SwiftUI row views (SliderRowView, SwitchRowView, TextRowView, etc.)
  - Settings views (SettingsView, ServerCertificatesView, MainUISettingsView, etc.)
  - Other views (NotificationsView, LoggerView, ScreenSaverView, etc.)

  2. Replaced cornerRadius() with clipShape(.rect(cornerRadius:)) (8 files)

  - VideoRowView.swift (4 occurrences)
  - WebRowView.swift
  - ImageRowView.swift (3 occurrences)
  - MapRowView.swift
  - NotificationsView.swift
  - ColorTemperaturePickerRowView.swift

  3. Fixed non-private @State properties in SettingsView.swift

  - Made 17 @State properties private
  - Simplified preview to use default SettingsView() initializer

  4. Fixed duplicate state variable in SliderRowView.swift

  - Removed unused lastSentTime variable
  - Kept lastSendTime and fixed throttling logic to update it after sending

  5. Fixed bug: lastSendTime was never updated after sending

  - In SliderRowView.swift, added lastSendTime = now after sendSliderUpdate(newValue) to make throttling work correctly

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
DrawerView and SelectionView
Kept on onTapGesture: ScreenSaverView, SliderRowView, and HomeSelectionView

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Bert <5411131+timbms@users.noreply.github.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
foregroundColor() → foregroundStyle() (Watch App)
 @ObservedObject Inside ObservableObject Class
Redundant MainActor.run in @mainactor Class
onTapGesture → Button for Accessibility   for SliderRowView
Force Unwraps in Preview Code

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- Add valuecolor support to SelectionView and SelectionRowView
  - Selection popup checkmark now respects widget.valuecolor
  - Replace Picker with styled Text to show selected value with correct color
  - Pass valuecolor from EmbeddingRowView and OpenHABSitemapViewController

- Fix valuecolor for group widgets in GenericRowView
  - Apply widget.valuecolor to value text (was hardcoded to .secondary)
  - Apply widget.labelcolor to label text for consistency

- Increase icon size from 24x24 to 32x32 in all row views
  - Matches UIKit cell icon size for visual consistency
  - Updated: Generic, Text, Switch, Selection, Slider, Setpoint,
    Segmented, Rollershutter, ColorPicker, ColorTemperaturePicker,
    DatePickerInput, TextInput, and ButtonGrid row views

- Make Frame headers more compact
  - Reduce vertical padding from 8pt to 4pt for frames with labels
  - Use 0pt padding for empty frame labels (matching UIKit behavior)

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Enable SVG color preprocessing for non-iconify icons in the SwiftUI
implementation, matching the behavior of the Watch IconView and UIKit cells.

- Add processorIconColor(for:) helper to determine when to apply color
- Skip color preprocessing for iconify icons (they handle their own colors)
- Pass widget.iconColor to processor for other SVG icons

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
SwiftUI's Picker with .segmented style doesn't fire selection callbacks
when tapping an already-selected segment. This breaks use cases requiring
repeated command sends (e.g., volume control, scene triggers).

- Replace Picker-based implementation with individual Button views
- Buttons always respond to taps, even on selected segments
- Maintain visual selection feedback via background highlighting
- Remove isMomentary distinction - unified button-based approach

This matches the behavior of Android app and BasicUI (issue #530).

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Icon size:
- Update IconView default size from 24x24 to 32x32 to match UIKit cells

Segmented control:
- Add text truncation with lineLimit(1) and truncationMode(.tail)
- Constrain button width (minWidth: 40, maxWidth: 120) to prevent row explosion

Row heights and density:
- Set defaultMinListRowHeight to 32 to allow compact Frame rows
- Reduce regular row vertical padding from 8pt to 4pt for UIKit-like density
- Frame rows use 6pt vertical padding for ~35pt total height

Background colors (matching UIKit):
- Frame rows: systemGroupedBackground (lighter gray)
- Other rows: secondarySystemGroupedBackground (white/off-white)
- Centralize background handling in EmbeddingRowView

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
IconView dark mode fix:
- Use UIColor.ohBlack as default icon color (adapts to light/dark mode)
- Apply semanticColorToHex() for proper color conversion
- Include colorScheme in view id to force refresh on mode change
- Matches UIKit develop branch implementation

SegmentedRowView improvements:
- Add layout priorities for text truncation order
  - detailTextLabel truncates first (priority 0)
  - labelText truncates second (priority 1)
- Use smaller font (.footnote) for segment buttons
- Remove excessive layoutPriority from buttons to prevent space hogging
- Add fixedSize to pressReleaseButtons for proper sizing

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Prevent text wrapping to multiple lines by adding lineLimit(1) to:
- labelText in all 16 row views
- labelValue in 9 row views that display it

This matches UIKit behavior where labels are truncated with ellipsis
instead of expanding to multiple lines.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Wrap SelectionView in NavigationStack when presented as sheet to display
the navigation title header with Cancel button. Add navigationTitle and
large title display mode to SitemapPageView for collapsing title on scroll.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use SwiftUI Menu to show selection options in a native popover instead
of a full-screen sheet. Maintains valuecolor support for selected value
and shows checkmark next to current selection.
…d pages

- Fix charts not displaying in linked pages by setting openHABRootUrl
  from active connection in SitemapPageViewModel init
- Hide labelValue for chart widgets (only show for images)
- Add animated sliding selection indicator to SegmentedRowView
- Improve segmented control contrast with systemGray5/systemGray3 colors

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Escape trailing % in format strings that aren't already escaped.
Server-side patterns like "%.0f %" should become "%.0f %%" to properly
display a literal percent sign in String(format:).

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
…in a Button based on the switchSupport property

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
timbms and others added 28 commits February 28, 2026 15:56
…erflow

Remove wasInBackground guard in SitemapNavigationView: the app switcher
can bring the app from inactive→active without passing through background,
so the guard silently skipped the refresh in that path (#1075).

Fix UInt64 overflow in watchOS long-poll backoff: replace pow(2.0, …)
float arithmetic with a capped bit-shift (max exponent 5, ceiling 30 s)
and guard the jitter range against a zero upper-bound crash.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: openhab-bot <info@openhabfoundation.org>
original function was implemented in 441b29f

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Use .longTerm service configuration for all OpenAPIService instances in
SitemapPageViewModel, matching watchOS behaviour. This disables the URL
cache so sitemap polling always fetches fresh data after foreground
transitions rather than serving a stale cached response (#1075).

Replace the removed wasInBackground guard with hasSeenActivePhase: skip
only the initial scene-active firing on launch (which would race the
.task startup) and force-restart on every subsequent active transition,
including the inactive→active app-switcher path that wasInBackground
missed.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
also refactor to have common rowWithIcon class,
make debug symbols available during app debugging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- Inline startPageHandling call directly in foregroundRefreshTask,
  removing the no-op performForegroundRefresh() async wrapper
- Drop activeConnectionInfo fallback in waitForConnectionForHandling;
  clear it when the tracker has no active connection so we always wait
  for a verified fresh connection instead of reusing a stale one

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- Trigger refreshOnForegroundIfNeeded() directly from the
  didBecomeActive sink when the side menu is not visible, covering
  the App Switcher / home-screen resume path
- Guard refreshOnForegroundIfNeeded() against firing during the
  initial app activation before any page has loaded
- Remove spurious await on synchronous startPageHandling call
  inside the foregroundRefreshTask closure

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- SessionChallengeHandler: try all configured connections when matching
  a Basic auth challenge host, not just the active one; improves
  credential resolution during connection handover
- NetworkTracker: expose configuredConnections() for the above
- WatchIconView: simplify transient-nil guard to a last-resolved-URL
  grace period; drop settings fallback, IconURLSource enum, and
  deduplicated reason logging
- UserData: improve connection change logging with before/after URLs
- TextInputRowView: remove trailing whitespace

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: DigiH <17110652+DigiH@users.noreply.github.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Bert <5411131+timbms@users.noreply.github.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
@TAKeanice TAKeanice force-pushed the openapigen-swiftui branch from 1f242b5 to 166a59c Compare March 26, 2026 19:48
Base automatically changed from openapigen-swiftui to develop March 30, 2026 19:59
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.

3 participants