Skip to content

refactor(core): Swift 6 publish-readiness — MainActor metrics + atomic snapshot, 94% coverage - #5

Merged
Dicky019 merged 3 commits into
mainfrom
refactor/swift6-publish-readiness
Jun 6, 2026
Merged

Dicky019 merged 3 commits into
mainfrom
refactor/swift6-publish-readiness

Conversation

@Dicky019

@Dicky019 Dicky019 commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Summary

Publish-readiness pass: full Swift 6 language mode, best-practice concurrency, and a ≥85% coverage gate. Pre-1.0, so public API was allowed to change.

Concurrency rearchitecture

  • UIKit metric reads (UIScreen/UIApplication/UIDevice) are isolated to @MainActor; results are published as one immutable Snapshot via swift-atomics ManagedAtomic. All scaling reads stay nonisolated (lock-free, race-free, snapshot-consistent).
  • configure(with:) / refreshMetrics() are now @MainActor; they also refresh on orientation/scene notifications — fixes the stale-on-rotation bug.
  • Deleted the two TTL caches, the Atomic wrapper, and all os_unfair_lock usage. No hand-rolled locks remain.
  • @unchecked Sendable retained with a documented invariant (only shared mutable state is the atomic).

Swift 6 + API

  • swift-tools-version: 6.0, swiftLanguageModes: [.v6], dropped the -strict-concurrency unsafe flag.
  • Clean build with zero concurrency diagnostics on macOS and iOS.
  • ScaleType trimmed to .width/.height/.text/.radius; deviceType removed from the config (now ScreenUtil.shared.deviceType).

SwiftUI

  • Replaced deprecated .cornerRadius(_:) with .clipShape(RoundedRectangle(...)).
  • @ScaledValue.wrappedValue made nonisolated (consistent with @ScreenPercentage).

Tests & CI

  • Test suite expanded to 113 tests, 94.3% line coverage.
  • CI runs build / test / thread-sanitizer under Swift 6, plus a coverage job that fails below 85%.

Conforms to the swift-concurrency and swiftui-expert-skill best-practice guides.

Test Plan

  • swift build — macOS ✅
  • iOS Swift 6 build — 0 concurrency diagnostics ✅
  • swift test — 113 tests, 0 failures ✅
  • swift test --sanitize=thread — 0 data races ✅
  • Line coverage 94.3% (≥85%) ✅

Isolate UIKit metric reads (UIScreen/UIApplication/UIDevice) to the main
actor and publish an immutable Snapshot via swift-atomics ManagedAtomic;
all scaling reads stay nonisolated. Delete the TTL caches, the Atomic
wrapper, and os_unfair_lock. configure(with:)/refreshMetrics() are now
@mainactor and refresh on orientation/scene notifications, fixing the
stale-on-rotation bug.

- Adopt Swift 6 language mode (tools 6.0, swiftLanguageModes [.v6]); drop
  the -strict-concurrency unsafe flag.
- ScreenUtil is compiler-checked Sendable (no @unchecked).
- Trim ScaleType to .width/.height/.text/.radius; drop deviceType from the
  configuration.
- SwiftUI: replace deprecated .cornerRadius with clipShape; make
  @ScaledValue.wrappedValue nonisolated.
- Document the breaking changes in CHANGELOG.
@Dicky019
Dicky019 force-pushed the refactor/swift6-publish-readiness branch from 019f97a to e3f875f Compare June 6, 2026 15:26
Dicky019 added 2 commits June 7, 2026 02:14
Cover numeric scaling on all types, CGGeometry helpers, FastScale,
BatchScaler/batch APIs, ScreenDimensions, SwiftUI Font/Environment and
property wrappers, and the snapshot refresh path. Rewrite the
read-during-reconfigure race test as a fully main-actor-isolated async
TaskGroup. Adjust existing tests for @mainactor configure and the trimmed
ScaleType.

Concurrent test blocks record validity and assert once afterward;
XCTAssert is not safe to call from many threads (mutates shared
XCTestCase state, which ThreadSanitizer flags in CI).
Run build/test/thread-sanitizer under Swift 6 and add a coverage job that
fails when line coverage drops below 85%.
@Dicky019
Dicky019 force-pushed the refactor/swift6-publish-readiness branch from e3f875f to 0e824e7 Compare June 6, 2026 17:14
@Dicky019
Dicky019 merged commit cdb6fd3 into main Jun 6, 2026
4 checks passed
@Dicky019
Dicky019 deleted the refactor/swift6-publish-readiness branch June 6, 2026 17:34
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.

1 participant