feat(macos): add Swift 6 strict concurrency compatibility

Prepares the macOS app for Swift 6 strict concurrency mode by:

1. Adding Sendable conformance to WizardNextResult, WizardStartResult,
   and WizardStatusResult in GatewayModels.swift

2. Adding AnyCodable bridging helpers in OnboardingWizard.swift to
   handle type conflicts between ClawdisProtocol and local module

3. Making CLLocationManagerDelegate methods nonisolated in:
   - MacNodeLocationService.swift
   - PermissionManager.swift (LocationPermissionRequester)

   Using Task { @MainActor in } pattern to safely access MainActor
   state from nonisolated protocol requirements.

These changes are forward-compatible and don't affect behavior on
current Swift versions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Tu Nombre Real
2026-01-04 03:13:31 +01:00
committed by Peter Steinberger
parent 72a9e58777
commit b978cc4e91
4 changed files with 53 additions and 28 deletions

View File

@@ -6,6 +6,20 @@ import SwiftUI
private let onboardingWizardLogger = Logger(subsystem: "com.clawdis", category: "onboarding.wizard")
// MARK: - Swift 6 AnyCodable Bridging Helpers
// These helpers bridge between ClawdisProtocol.AnyCodable and the local module
// to avoid Swift 6 strict concurrency type conflicts.
private typealias ProtocolAnyCodable = ClawdisProtocol.AnyCodable
private func bridgeToProtocol(_ value: Any) -> ProtocolAnyCodable {
ProtocolAnyCodable(value)
}
private func bridgeDict(_ dict: [String: Any]) -> [String: ProtocolAnyCodable] {
dict.mapValues { ProtocolAnyCodable($0) }
}
@MainActor
@Observable
final class OnboardingWizardModel {
@@ -307,12 +321,12 @@ private struct WizardOptionItem: Identifiable {
}
private struct WizardOption {
let value: AnyCodable?
let value: ProtocolAnyCodable?
let label: String
let hint: String?
}
private func decodeWizardStep(_ raw: [String: AnyCodable]?) -> WizardStep? {
private func decodeWizardStep(_ raw: [String: ProtocolAnyCodable]?) -> WizardStep? {
guard let raw else { return nil }
do {
let data = try JSONEncoder().encode(raw)
@@ -323,7 +337,7 @@ private func decodeWizardStep(_ raw: [String: AnyCodable]?) -> WizardStep? {
}
}
private func parseWizardOptions(_ raw: [[String: AnyCodable]]?) -> [WizardOption] {
private func parseWizardOptions(_ raw: [[String: ProtocolAnyCodable]]?) -> [WizardOption] {
guard let raw else { return [] }
return raw.map { entry in
let value = entry["value"]
@@ -337,7 +351,7 @@ private func wizardStepType(_ step: WizardStep) -> String {
(step.type.value as? String) ?? ""
}
private func anyCodableString(_ value: AnyCodable?) -> String {
private func anyCodableString(_ value: ProtocolAnyCodable?) -> String {
switch value?.value {
case let string as String:
return string
@@ -352,11 +366,11 @@ private func anyCodableString(_ value: AnyCodable?) -> String {
}
}
private func anyCodableStringValue(_ value: AnyCodable?) -> String? {
private func anyCodableStringValue(_ value: ProtocolAnyCodable?) -> String? {
value?.value as? String
}
private func anyCodableBool(_ value: AnyCodable?) -> Bool {
private func anyCodableBool(_ value: ProtocolAnyCodable?) -> Bool {
switch value?.value {
case let bool as Bool:
return bool
@@ -367,18 +381,18 @@ private func anyCodableBool(_ value: AnyCodable?) -> Bool {
}
}
private func anyCodableArray(_ value: AnyCodable?) -> [AnyCodable] {
private func anyCodableArray(_ value: ProtocolAnyCodable?) -> [ProtocolAnyCodable] {
switch value?.value {
case let arr as [AnyCodable]:
case let arr as [ProtocolAnyCodable]:
return arr
case let arr as [Any]:
return arr.map { AnyCodable($0) }
return arr.map { ProtocolAnyCodable($0) }
default:
return []
}
}
private func anyCodableEqual(_ lhs: AnyCodable?, _ rhs: AnyCodable?) -> Bool {
private func anyCodableEqual(_ lhs: ProtocolAnyCodable?, _ rhs: ProtocolAnyCodable?) -> Bool {
switch (lhs?.value, rhs?.value) {
case let (l as String, r as String):
return l == r