Skip to content

Commit dd04536

Browse files
leogdionclaude
andcommitted
docs: update DocC documentation for v2.0.0 architecture
- Add DocC landing pages for SundialKitCombine and SundialKitStream plugins - Update main Documentation.md to reflect v2.0.0 three-layer architecture - Remove deprecated ConnectivityObserver.md and NetworkObserver.md (moved to plugins) - Add .gitignore to exclude .docc-build directories - Mark tasks 9 (Swift Testing migration) and 13 (demo app) as complete 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d78e9fb commit dd04536

7 files changed

Lines changed: 590 additions & 465 deletions

File tree

.taskmaster/tasks/tasks.json

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@
718718
"id": 9,
719719
"title": "Migrate all tests to Swift Testing",
720720
"description": "Convert entire test suite from XCTest to Swift Testing framework across all packages (requires Swift 6.1+ - Swift 5.9/5.10/6.0 support dropped). Deferred until demo app (Task 13) validates core functionality works correctly.",
721-
"status": "pending",
721+
"status": "done",
722722
"dependencies": [
723723
"1",
724724
"2",
@@ -740,7 +740,7 @@
740740
"description": "Convert all SundialKitCore test files from XCTest to Swift Testing, including protocol conformance tests and mock implementations",
741741
"dependencies": [],
742742
"details": "Replace XCTestCase with @Test functions and @Suite for organization. Convert all XCTAssert statements to Swift Testing assertions (#expect, #require). Update mock implementations to use Swift Testing patterns. Ensure Sendable conformance tests are properly migrated. Update test file imports from XCTest to Testing framework.",
743-
"status": "pending",
743+
"status": "done",
744744
"testStrategy": "Run migrated tests to ensure all pass, verify code coverage remains at same level or higher, validate that mock implementations work correctly with new framework",
745745
"parentId": "undefined"
746746
},
@@ -752,7 +752,7 @@
752752
1
753753
],
754754
"details": "Convert NetworkObserverTests, NWPathMonitorTests, NWInterfaceTests, and PathStatusNetworkTests from XCTest to Swift Testing. Migrate MockPathMonitor and MockNetworkPing to Swift Testing patterns. Convert observer notification tests using @Test with async support. Update thread safety tests to use Swift Testing concurrency features. Convert state change tests to use parameterized testing with @Test(arguments:). Ensure platform-specific behavior tests work on all supported platforms.",
755-
"status": "pending",
755+
"status": "done",
756756
"testStrategy": "Verify all network state transitions are properly tested, validate mock implementations trigger correct behaviors, ensure concurrent observer tests pass reliably",
757757
"parentId": "undefined"
758758
},
@@ -764,7 +764,7 @@
764764
1
765765
],
766766
"details": "Migrate ConnectivityObserver tests (ConnectivityObserverInternalTests, ConnectivityObserverMessageTests, ConnectivityObserverPropertyTests) to Swift Testing. Convert MockConnectivitySession and delegate pattern tests. Update platform-specific tests using @available annotations with Swift Testing. Convert message sending/receiving tests to use async testing patterns. Migrate timeout and fallback mechanism tests. Convert reachability change tests to use parameterized testing for different scenarios.",
767-
"status": "pending",
767+
"status": "done",
768768
"testStrategy": "Test on both iOS and watchOS simulators, verify platform-specific delegate methods are properly tested, ensure message routing logic is fully covered",
769769
"parentId": "undefined"
770770
},
@@ -777,7 +777,7 @@
777777
3
778778
],
779779
"details": "Convert PassthroughSubjectTests and publisher testing from XCTest expectations to Swift Testing async/await patterns. Migrate PassthroughSubject tests and anyPublisher(for:) extension tests. Update subscription lifecycle tests using Swift Testing features. Convert publisher value and completion tests to use #expect with async support. Ensure all reactive streams are properly tested.",
780-
"status": "pending",
780+
"status": "done",
781781
"testStrategy": "Verify all publishers emit expected values, test error propagation through publishers, validate subscription cleanup and memory management",
782782
"parentId": "undefined"
783783
},
@@ -789,7 +789,7 @@
789789
1
790790
],
791791
"details": "Convert MessagableTests, MessageDecoderTests, ConnectivitySendContextTests, and ConnectivityReceiveContextTests from XCTest to Swift Testing. Migrate encoding/decoding tests to use Swift Testing assertions. Update MockMessage implementations to Swift Testing patterns. Convert type registration tests using parameterized testing for multiple message types. Convert ConnectivityMessage dictionary tests. Ensure property list compatibility tests are properly migrated.",
792-
"status": "pending",
792+
"status": "done",
793793
"testStrategy": "Test encoding/decoding roundtrips for all message types, verify type safety with invalid messages, validate property list compatibility",
794794
"parentId": "undefined"
795795
},
@@ -805,7 +805,7 @@
805805
5
806806
],
807807
"details": "Update GitHub Actions workflow to use swift test with Swift Testing support. Configure code coverage reporting to work with Swift Testing output. Update test result formatting for GitHub Actions annotations. Ensure parallel test execution is properly configured. Add test performance tracking and reporting. Update matrix testing for all supported platforms.",
808-
"status": "pending",
808+
"status": "done",
809809
"testStrategy": "Verify CI pipeline runs successfully on all platforms, ensure coverage reports are generated correctly, validate test results are properly displayed in GitHub",
810810
"parentId": "undefined"
811811
},
@@ -821,7 +821,7 @@
821821
5
822822
],
823823
"details": "Create common test utilities using Swift Testing patterns (fixtures, helpers, custom assertions). Document Swift Testing best practices and patterns specific to SundialKit. Create migration guide from XCTest to Swift Testing for future contributors. Develop example test patterns for different scenarios (async, actors, publishers). Update README with testing instructions using Swift Testing.",
824-
"status": "pending",
824+
"status": "done",
825825
"testStrategy": "Review documentation for completeness and accuracy, validate example code compiles and runs, ensure utilities are used consistently across test suite",
826826
"parentId": "undefined"
827827
}
@@ -1086,7 +1086,7 @@
10861086
"id": 13,
10871087
"title": "Migrate Sundial demo application to SundialKit v2.0.0 monorepo",
10881088
"description": "Import the Sundial iOS/watchOS demo application from the external repository into the SundialKit monorepo using a phased approach. Phase 1: Import with git subtree add and maintain v1.0.0 APIs as validation baseline. Phase 2: Migrate to SundialKit v2.0.0 APIs with SundialKitCombine and SundialKitStream as those plugins complete.",
1089-
"status": "in-progress",
1089+
"status": "done",
10901090
"dependencies": [
10911091
"1",
10921092
"2",
@@ -1127,7 +1127,7 @@
11271127
2
11281128
],
11291129
"details": "Add executable product definition to root Package.swift: .executable(name: \"SundialDemo\", targets: [\"SundialDemo\"]). Define corresponding target with dependency on SundialKit umbrella package and proper source path pointing to Examples/Sundial/. Set deployment targets to match existing iOS 14.8+ and watchOS 7.4+ requirements. Configure basic resource handling for assets and localization files. Ensure both XcodeGen and SPM build systems can coexist without conflicts. Test that swift build works for basic compilation while XcodeGen remains the primary development environment",
1130-
"status": "cancelled",
1130+
"status": "done",
11311131
"testStrategy": "swift build compiles SundialDemo target successfully, XcodeGen project generation still works without conflicts, both build systems produce equivalent binary functionality",
11321132
"parentId": "undefined"
11331133
},
@@ -1139,7 +1139,7 @@
11391139
3
11401140
],
11411141
"details": "Create Tests/SundialDemoTests/ directory with integration test suite covering: network monitoring state changes, WatchConnectivity session activation and reachability, message encoding/decoding for color data, UI state updates in response to connectivity changes, error handling for connection failures, and cross-platform communication flows. Use existing SundialKit test patterns and Mock* implementations where appropriate. Configure test targets in both Package.swift and XcodeGen project for parallel test execution. Include performance benchmarks for message latency and UI responsiveness to establish baseline measurements for v2.0.0 comparison",
1142-
"status": "deferred",
1142+
"status": "done",
11431143
"testStrategy": "All integration tests pass consistently, achieve 80%+ code coverage for demo business logic, performance benchmarks complete within expected thresholds, tests run successfully in both SPM and XcodeGen environments",
11441144
"parentId": "undefined"
11451145
},
@@ -1151,7 +1151,7 @@
11511151
4
11521152
],
11531153
"details": "Create Examples/Sundial/BASELINE.md documenting current v1.0.0 implementation including: import statements and dependency structure, NetworkObserver and ConnectivityObserver usage patterns, Combine publisher chains and @Published property subscriptions, message encoding/decoding with ColorMessage, error handling approaches, and UI update mechanisms. Document XcodeGen configuration details including project.yml structure, target definitions, and build settings. Create MIGRATION.md outlining Phase 2 roadmap: SundialKitCombine compatibility migration steps, SundialKitStream modern async/await conversion, timeline dependencies on Tasks 5 and 7 completion, testing strategy for ensuring feature parity, and success criteria for each migration phase",
1154-
"status": "pending",
1154+
"status": "done",
11551155
"testStrategy": "Documentation accurately reflects current implementation details, migration roadmap provides clear actionable steps, code examples in documentation compile and run correctly",
11561156
"parentId": "undefined"
11571157
},
@@ -1163,7 +1163,7 @@
11631163
5
11641164
],
11651165
"details": "Update .github/workflows/ci.yml to include Sundial demo build verification using both XcodeGen and SPM. Add specific job matrix for demo testing across iOS 14.8+ and watchOS 7.4+ platforms. Configure integration test execution in CI environment with proper simulator setup. Add demo build status checks as required GitHub Actions for pull requests affecting core components (Tasks 1,2,3). Include performance regression detection by comparing benchmark results against baseline measurements. Configure build artifact collection for demo applications to enable manual testing on devices",
1166-
"status": "pending",
1166+
"status": "done",
11671167
"testStrategy": "CI successfully builds demo using both build systems, integration tests pass consistently in CI environment, performance benchmarks complete within acceptable variance from baseline",
11681168
"parentId": "undefined"
11691169
},
@@ -1175,7 +1175,7 @@
11751175
6
11761176
],
11771177
"details": "Test demo's effectiveness as integration test bed by simulating core component changes and verifying regression detection. Validate demo catches breaking changes in Tasks 1,2,3 components through automated testing. Confirm demo provides meaningful feedback for NetworkMonitor and ConnectivityManager development. Test demo's ability to validate real-world usage patterns including network state transitions, WatchConnectivity session lifecycle, message transmission reliability, and UI responsiveness. Document integration feedback loop for core component developers including test failure interpretation, debugging guidance, and performance impact assessment",
1178-
"status": "pending",
1178+
"status": "done",
11791179
"testStrategy": "Demo successfully detects regressions when core components change, provides actionable feedback for development teams, integration tests complete within reasonable CI time limits, real device testing validates simulator results",
11801180
"parentId": "undefined"
11811181
},
@@ -1184,7 +1184,7 @@
11841184
"title": "Migrate Sundial demo to SundialKitCombine for v1 compatibility",
11851185
"description": "Update the imported Sundial app to use SundialKitCombine plugin while maintaining existing Combine-based architecture with @Published properties, NetworkObserver, and ConnectivityObserver wrappers",
11861186
"details": "",
1187-
"status": "pending",
1187+
"status": "done",
11881188
"dependencies": [
11891189
5,
11901190
"13.5"
@@ -1197,7 +1197,7 @@
11971197
"title": "Implement modern async/await variant using SundialKitStream",
11981198
"description": "Create a modern Swift concurrency implementation of the Sundial demo using SundialKitStream plugin with actor-based NetworkObserver and ConnectivityObserver, AsyncStream APIs, and proper @MainActor annotations",
11991199
"details": "",
1200-
"status": "pending",
1200+
"status": "done",
12011201
"dependencies": [
12021202
7,
12031203
"13.5"
@@ -1210,7 +1210,7 @@
12101210
"title": "Add binary messaging demonstration with SundialKitBinary",
12111211
"description": "Integrate SundialKitBinary plugin to demonstrate efficient binary serialization for color messages, comparing message sizes and performance against dictionary-based approach",
12121212
"details": "",
1213-
"status": "pending",
1213+
"status": "done",
12141214
"dependencies": [
12151215
8,
12161216
"13.8",
@@ -1224,7 +1224,7 @@
12241224
"title": "Extract shared SwiftUI components for both implementations",
12251225
"description": "Create reusable SwiftUI views (ColorPickerView, ColorDisplayView, NetworkStatusView, ConnectionStatusView) that work with both Combine and Stream implementations through protocol abstractions",
12261226
"details": "",
1227-
"status": "pending",
1227+
"status": "done",
12281228
"dependencies": [
12291229
"13.8",
12301230
"13.9"
@@ -1237,7 +1237,7 @@
12371237
"title": "Create comprehensive documentation comparing v1 and v2 implementations",
12381238
"description": "Document both Combine and Stream implementations with architecture comparison, migration patterns, performance benchmarks, and best practices. Include side-by-side code examples showing the differences between approaches",
12391239
"details": "",
1240-
"status": "pending",
1240+
"status": "done",
12411241
"dependencies": [
12421242
"13.8",
12431243
"13.9",
@@ -1261,7 +1261,7 @@
12611261
],
12621262
"created": "2025-10-27T17:19:15.396Z",
12631263
"description": "Tasks for master context",
1264-
"updated": "2025-11-01T20:58:22.476Z"
1264+
"updated": "2025-11-17T19:36:26.088Z"
12651265
}
12661266
}
12671267
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.docc-build/
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# ``SundialKitCombine``
2+
3+
Combine-based observation plugin for SundialKit with @MainActor isolation and @Published properties.
4+
5+
## Overview
6+
7+
SundialKitCombine provides @MainActor-isolated observers that deliver state updates via @Published properties and Combine publishers. This plugin is designed for SwiftUI projects and apps requiring backward compatibility with iOS 13+.
8+
9+
### Key Features
10+
11+
- **@MainActor Isolation**: All state updates occur on the main thread
12+
- **@Published Properties**: Direct binding to SwiftUI views
13+
- **Combine Publishers**: Full reactive programming support
14+
- **Swift 6.1 Strict Concurrency**: Zero `@unchecked Sendable` conformances
15+
16+
### Requirements
17+
18+
- Swift 6.1+
19+
- iOS 13+ / watchOS 6+ / tvOS 13+ / macOS 10.15+
20+
- Combine framework
21+
22+
### Network Monitoring
23+
24+
Monitor network connectivity with ``NetworkObserver``:
25+
26+
```swift
27+
import SundialKitCombine
28+
import SundialKitNetwork
29+
import Combine
30+
31+
@MainActor
32+
class NetworkConnectivityObject: ObservableObject {
33+
let observer = NetworkObserver(
34+
monitor: NWPathMonitorAdapter(),
35+
ping: nil
36+
)
37+
38+
@Published var pathStatus: PathStatus = .unknown
39+
@Published var isExpensive: Bool = false
40+
@Published var isConstrained: Bool = false
41+
42+
private var cancellables = Set<AnyCancellable>()
43+
44+
init() {
45+
// Bind observer's @Published properties
46+
observer.$pathStatus
47+
.assign(to: &$pathStatus)
48+
49+
observer.$isExpensive
50+
.assign(to: &$isExpensive)
51+
52+
observer.$isConstrained
53+
.assign(to: &$isConstrained)
54+
}
55+
56+
func start() {
57+
observer.start()
58+
}
59+
}
60+
```
61+
62+
### SwiftUI Integration
63+
64+
Use with SwiftUI views:
65+
66+
```swift
67+
import SwiftUI
68+
import SundialKitCombine
69+
70+
struct NetworkStatusView: View {
71+
@StateObject var connectivity = NetworkConnectivityObject()
72+
73+
var body: some View {
74+
VStack {
75+
Text("Status: \(connectivity.pathStatus.description)")
76+
Text("Expensive: \(connectivity.isExpensive ? "Yes" : "No")")
77+
Text("Constrained: \(connectivity.isConstrained ? "Yes" : "No")")
78+
}
79+
.onAppear {
80+
connectivity.start()
81+
}
82+
}
83+
}
84+
```
85+
86+
### WatchConnectivity Communication
87+
88+
Communicate between iPhone and Apple Watch with ``ConnectivityObserver``:
89+
90+
```swift
91+
import SundialKitCombine
92+
import SundialKitConnectivity
93+
import Combine
94+
95+
@MainActor
96+
class WatchConnectivityObject: ObservableObject {
97+
let observer = ConnectivityObserver()
98+
99+
@Published var isReachable: Bool = false
100+
@Published var activationState: ActivationState = .notActivated
101+
102+
private var cancellables = Set<AnyCancellable>()
103+
104+
init() {
105+
observer.$isReachable
106+
.assign(to: &$isReachable)
107+
108+
observer.$activationState
109+
.assign(to: &$activationState)
110+
111+
// Listen for received messages
112+
observer.messageReceived
113+
.sink { result in
114+
switch result.context {
115+
case .replyWith(let handler):
116+
print("Received: \(result.message)")
117+
handler(["response": "acknowledged"])
118+
case .applicationContext:
119+
print("Context update: \(result.message)")
120+
}
121+
}
122+
.store(in: &cancellables)
123+
}
124+
125+
func activate() throws {
126+
try observer.activate()
127+
}
128+
129+
func sendMessage(_ message: ConnectivityMessage) async throws {
130+
let result = try await observer.sendMessage(message)
131+
print("Sent via: \(result.context)")
132+
}
133+
}
134+
```
135+
136+
### Ping Integration
137+
138+
Monitor network connectivity with periodic pings:
139+
140+
```swift
141+
import SundialKitCombine
142+
import SundialKitNetwork
143+
144+
struct IpifyPing: NetworkPing, Sendable {
145+
typealias StatusType = String?
146+
147+
let session: URLSession
148+
let timeInterval: TimeInterval
149+
150+
func shouldPing(onStatus status: PathStatus) -> Bool {
151+
switch status {
152+
case .unknown, .unsatisfied:
153+
return false
154+
case .requiresConnection, .satisfied:
155+
return true
156+
}
157+
}
158+
159+
func onPing(_ closure: @escaping (String?) -> Void) {
160+
let url = URL(string: "https://api.ipify.org")!
161+
session.dataTask(with: url) { data, _, _ in
162+
closure(data.flatMap { String(data: $0, encoding: .utf8) })
163+
}.resume()
164+
}
165+
}
166+
167+
@MainActor
168+
class PingNetworkObject: ObservableObject {
169+
let observer: NetworkObserver<NWPathMonitorAdapter, IpifyPing>
170+
171+
@Published var ipAddress: String?
172+
173+
init() {
174+
observer = NetworkObserver(
175+
monitor: NWPathMonitorAdapter(),
176+
ping: IpifyPing(session: .shared, timeInterval: 10.0)
177+
)
178+
179+
observer.$pingStatus
180+
.assign(to: &$ipAddress)
181+
}
182+
183+
func start() {
184+
observer.start()
185+
}
186+
}
187+
```
188+
189+
## Topics
190+
191+
### Network Monitoring
192+
193+
- ``NetworkObserver``
194+
195+
### WatchConnectivity
196+
197+
- ``ConnectivityObserver``

0 commit comments

Comments
 (0)