From 872583eca8b4e7ae6ef85917604d4a5257b9d125 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Wed, 22 Jul 2026 21:43:42 -0500 Subject: fix: adopt Swift 6 language mode; resolve all concurrency issues (#27) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All three product targets (app, widget, share extension) now build under SWIFT_VERSION = 6.0 with zero errors and zero warnings. The UITests target stays on 5.0: XCTestCase's nonisolated setUp/init overrides conflict with the target's MainActor default isolation under 6, and test tooling is not shipping code. The original seven diagnostics, plus the layers Swift 6 mode surfaced once those cleared: - SMTPChannel is an actor. It was implicitly MainActor while running its receive loop on a background queue, so parsedLines/lineWaiters/ receiveBuffer were declared main-actor-protected and mutated off it — concurrent mutation while resuming a CheckedContinuation can double-resume, which traps. The actor serialises all state; Network callbacks hop in via Task. The start() continuation also gains an OSAllocatedUnfairLock resume-once guard: the state handler can fire .ready and later .failed, and resuming twice was a pre-existing trap of the same family. - CachedLookupResult is nonisolated (a value pair built inside actor LookupRuntime cannot have a MainActor-bound memberwise init) with conditional Sendable — opting out of MainActor isolation also opted out of the implicit Sendable that globally-isolated types get. - PortScanService.printableBanner is nonisolated: a pure transformation called from the connection's queue. - SweepActivityController stores the activity's Sendable id instead of the non-Sendable Activity, re-resolving via Activity.activities inside each fire-and-forget task, so nothing non-Sendable crosses isolation. - App Intents' static title/description/openAppWhenRun become lets (get-only protocol requirements; static var is shared mutable global state), and the summary helpers are @MainActor to match the model properties they read and the perform() implementations that call them. - ExternalDataService's ISO8601DateFormatter is nonisolated(unsafe), citing Apple's documented thread-safety, rather than risking a parser behaviour change by switching APIs with no test coverage. - TaskMetricsDelegate.metrics is nonisolated(unsafe): written on the session's delegate queue, read only after the request completes, and URLSession guarantees didFinishCollecting precedes task completion. - The share extension extracts the host via async/withCheckedContinuation instead of sending a non-Sendable completion into loadItem's @Sendable handler; Task inherits the view controller's MainActor so the manual DispatchQueue.main hop goes too. Validated: clean Swift 6 build of all product targets, and the full enforced 11-test audit suite green on the floor runtime — Swift 6's runtime isolation checks ran the app through every screen without a trap. --- DomainDig.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'DomainDig.xcodeproj') diff --git a/DomainDig.xcodeproj/project.pbxproj b/DomainDig.xcodeproj/project.pbxproj index 6b4c25c..c132d2a 100644 --- a/DomainDig.xcodeproj/project.pbxproj +++ b/DomainDig.xcodeproj/project.pbxproj @@ -591,7 +591,7 @@ SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -628,7 +628,7 @@ SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -657,7 +657,7 @@ SWIFT_APPROACHABLE_CONCURRENCY = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -686,7 +686,7 @@ SWIFT_APPROACHABLE_CONCURRENCY = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -715,7 +715,7 @@ SWIFT_APPROACHABLE_CONCURRENCY = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -744,7 +744,7 @@ SWIFT_APPROACHABLE_CONCURRENCY = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; -- cgit v1.2.3