feat(apple): type-safe SF Symbols via SFSafeSymbols

Replaces every stringly-typed SF Symbol name with a compile-time-checked
SFSymbol case, mirroring the L10n accessor approach. A mistyped or
OS-unavailable symbol is now a build error instead of a silently blank
glyph at runtime.

Adds the SFSafeSymbols SPM package (project.yml) and migrates all call
sites: Image(systemName:)/Label(systemImage:) -> systemSymbol, and the
five symbol-carrying view properties (AppDestination.systemSymbol,
SettingsRow.icon, AboutPoint.symbol, MethodRow.icon, PolicyOption.icon)
flipped from String to SFSymbol end to end.
This commit is contained in:
2026-07-23 17:40:07 +02:00
parent ef42875ddb
commit 1563bf80d6
12 changed files with 74 additions and 59 deletions

View File

@@ -1,4 +1,5 @@
import SwiftUI
import SFSafeSymbols
/// Bottom toast host driven by `UiMessageController`, ported from
/// `ui/feedback/VniDropSnackbarHost.kt`. Tone drives the accent color; errors get
@@ -52,7 +53,7 @@ struct SnackbarHost: View {
.buttonStyle(.borderless)
}
Button(action: dismiss) {
Image(systemName: "xmark")
Image(systemSymbol: .xmark)
.font(.footnote.weight(.semibold))
.foregroundStyle(.secondary)
.frame(width: 36, height: 36)

View File

@@ -1,4 +1,5 @@
import Foundation
import SFSafeSymbols
/// Top-level destinations, ported from `ui/navigation/AppDestination.kt`.
enum AppDestination: String, CaseIterable, Identifiable {
@@ -17,11 +18,11 @@ enum AppDestination: String, CaseIterable, Identifiable {
}
/// SF Symbol approximating the Compose line icon.
var systemImage: String {
var systemSymbol: SFSymbol {
switch self {
case .send: return "paperplane"
case .receive: return "tray.and.arrow.down"
case .settings: return "gearshape"
case .send: return .paperplane
case .receive: return .trayAndArrowDown
case .settings: return .gearshape
}
}
}