Commit f834c8a822

f834c8a8223c40bd17b90be8f6ab7db843d0914c

parent: b4147fe8f1

Unsigned

cmc <hello@cleberg.net> · 2026-07-20 20:29 UTC

fix: StoreKit config path and Swift 6 concurrency warnings

The StoreKitConfigurationFileReference added in #11 used one '../' too
many, resolving outside the repository. Xcode resolves it relative to
the .xcodeproj's xcshareddata directory, so two levels reaches the repo
root.

SweepActivityAttributes is now explicitly nonisolated. The app target
sets SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor while the widget target
does not, so a type shared by both inferred a main-actor-isolated
ActivityAttributes conformance that ActivityKit cannot use from its
concurrent contexts.

LocalAPIService's logger closures captured self strongly while their
inner Tasks declared [weak self]. The weak capture is now on the outer
closure and bound before the Task, so the concurrently-executing closure
references an immutable strong local rather than the weak capture.

Layout: unified · split

DomainDig.xcodeproj/xcshareddata/xcschemes/DomainDig.xcscheme +1 −1
@@ -58,7 +58,7 @@
58 </CommandLineArgument> 58 </CommandLineArgument>
59 </CommandLineArguments> 59 </CommandLineArguments>
60 <StoreKitConfigurationFileReference 60 <StoreKitConfigurationFileReference
61 identifier = "../../../DomainDig.storekit"> 61 identifier = "../../DomainDig.storekit">
62 </StoreKitConfigurationFileReference> 62 </StoreKitConfigurationFileReference>
63 </LaunchAction> 63 </LaunchAction>
64 <ProfileAction 64 <ProfileAction
LocalAPIService.swift +8 −6
@@ -182,14 +182,16 @@ final class LocalAPIService {
182 let server = LocalAPIServer( 182 let server = LocalAPIServer(
183 port: Self.sanitizedPort(config.port), 183 port: Self.sanitizedPort(config.port),
184 token: token, 184 token: token,
185 requestLogger: { log in 185 requestLogger: { [weak self] log in
186 Task { @MainActor [weak self] in 186 guard let self else { return }
187 self?.record(log) 187 Task { @MainActor in
188 self.record(log)
188 } 189 }
189 }, 190 },
190 stateLogger: { stateMessage in 191 stateLogger: { [weak self] stateMessage in
191 Task { @MainActor [weak self] in 192 guard let self else { return }
192 self?.statusMessage = stateMessage 193 Task { @MainActor in
194 self.statusMessage = stateMessage
193 } 195 }
194 } 196 }
195 ) 197 )
Shared/SweepActivityAttributes.swift +5 −2
@@ -4,8 +4,11 @@ import Foundation
4/// Live Activity contract for an in-flight watchlist sweep or batch lookup. 4/// Live Activity contract for an in-flight watchlist sweep or batch lookup.
5/// 5///
6/// Lives in `Shared/` because the app starts/updates the activity and the 6/// Lives in `Shared/` because the app starts/updates the activity and the
7/// widget extension renders it. 7/// widget extension renders it. Explicitly `nonisolated`: the app target sets
8struct SweepActivityAttributes: ActivityAttributes { 8/// `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor`, which would otherwise infer a
9/// main-actor-isolated `ActivityAttributes` conformance that ActivityKit cannot
10/// use from its concurrent contexts.
11nonisolated struct SweepActivityAttributes: ActivityAttributes {
9 struct ContentState: Codable, Hashable { 12 struct ContentState: Codable, Hashable {
10 var completed: Int 13 var completed: Int
11 var total: Int 14 var total: Int