Skip to content

Commit eabcc35

Browse files
committed
Place UserDatabase into separate file and provide helper method to wipe out all coverage data
1 parent 286f922 commit eabcc35

File tree

3 files changed

+80
-22
lines changed

3 files changed

+80
-22
lines changed

RMBT.xcodeproj/project.pbxproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
493D514C2DD7526200CC3473 /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 49C5E41A2DD74C3E00C537D9 /* libresolv.9.tbd */; };
2929
494998E32B7E353C0067B3D8 /* TopPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494998E22B7E353C0067B3D8 /* TopPopoverView.swift */; };
3030
49643ED02EAD6F6E001E3B01 /* CleanupDuringMeasurementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49643ECF2EAD6F6D001E3B01 /* CleanupDuringMeasurementTests.swift */; };
31+
49643ED42EAF9267001E3B01 /* UserDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49643ED32EAF9267001E3B01 /* UserDatabase.swift */; };
3132
497B42702D0064A40073775A /* AsyncAlgorithms in Frameworks */ = {isa = PBXBuildFile; productRef = 497B426F2D0064A40073775A /* AsyncAlgorithms */; };
3233
498220BF2D424F51009A7055 /* UIImage+ResultClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 498220BE2D424F51009A7055 /* UIImage+ResultClass.swift */; };
3334
4985815F2EAA792B008C11A7 /* HistoryCoverageResultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4985815E2EAA792B008C11A7 /* HistoryCoverageResultView.swift */; };
@@ -70,7 +71,6 @@
7071
49EDC7942EAA35630009D9A6 /* PersistentFence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EDC7722EAA35630009D9A6 /* PersistentFence.swift */; };
7172
49EDC7952EAA35630009D9A6 /* Fence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EDC7802EAA35630009D9A6 /* Fence.swift */; };
7273
49EDC7962EAA35630009D9A6 /* SendCoverageResultRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EDC77C2EAA35630009D9A6 /* SendCoverageResultRequest.swift */; };
73-
FFF3D1FA2C16447FB06BDD35 /* AcceptableStatusCodeSendCoverageResultsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011858BA6C01475DA0CBB31B /* AcceptableStatusCodeSendCoverageResultsService.swift */; };
7474
49EDC7972EAA35630009D9A6 /* NetworkConnectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EDC76A2EAA35630009D9A6 /* NetworkConnectionType.swift */; };
7575
49EDC7982EAA35630009D9A6 /* NetworkCoverageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EDC7832EAA35630009D9A6 /* NetworkCoverageViewModel.swift */; };
7676
49EDC7992EAA35630009D9A6 /* PersistenceManagingCoverageResultsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EDC76F2EAA35630009D9A6 /* PersistenceManagingCoverageResultsService.swift */; };
@@ -339,6 +339,7 @@
339339
E9E9E90327429B6C005EB393 /* RMBTTestLandscapeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E9E90227429B6B005EB393 /* RMBTTestLandscapeView.swift */; };
340340
E9E9E90527429B90005EB393 /* RMBTTestLandscapeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9E9E90427429B90005EB393 /* RMBTTestLandscapeView.xib */; };
341341
F71B138A4E5F6DC41FF14268 /* Pods_RMBT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32DE166B881B73366FE005F9 /* Pods_RMBT.framework */; };
342+
FFF3D1FA2C16447FB06BDD35 /* AcceptableStatusCodeSendCoverageResultsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011858BA6C01475DA0CBB31B /* AcceptableStatusCodeSendCoverageResultsService.swift */; };
342343
/* End PBXBuildFile section */
343344

344345
/* Begin PBXContainerItemProxy section */
@@ -352,6 +353,7 @@
352353
/* End PBXContainerItemProxy section */
353354

354355
/* Begin PBXFileReference section */
356+
011858BA6C01475DA0CBB31B /* AcceptableStatusCodeSendCoverageResultsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcceptableStatusCodeSendCoverageResultsService.swift; sourceTree = "<group>"; };
355357
09BF4B6D48151BE0513DA599 /* Pods-RMBTTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RMBTTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RMBTTests/Pods-RMBTTests.debug.xcconfig"; sourceTree = "<group>"; };
356358
1C605E59889E3DF77EFDC8CF /* Pods-RMBTTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RMBTTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RMBTTests/Pods-RMBTTests.release.xcconfig"; sourceTree = "<group>"; };
357359
1F9C078F216F751C00F1FC10 /* RMBT.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RMBT.entitlements; sourceTree = "<group>"; };
@@ -378,6 +380,7 @@
378380
49312C742BE91CC2001AA226 /* RMBTHistoryDownloadViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RMBTHistoryDownloadViewController.swift; sourceTree = "<group>"; };
379381
494998E22B7E353C0067B3D8 /* TopPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopPopoverView.swift; sourceTree = "<group>"; };
380382
49643ECF2EAD6F6D001E3B01 /* CleanupDuringMeasurementTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CleanupDuringMeasurementTests.swift; sourceTree = "<group>"; };
383+
49643ED32EAF9267001E3B01 /* UserDatabase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDatabase.swift; sourceTree = "<group>"; };
381384
498220BE2D424F51009A7055 /* UIImage+ResultClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+ResultClass.swift"; sourceTree = "<group>"; };
382385
4985815E2EAA792B008C11A7 /* HistoryCoverageResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryCoverageResultView.swift; sourceTree = "<group>"; };
383386
498581602EAA7982008C11A7 /* TestCoverageResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestCoverageResultView.swift; sourceTree = "<group>"; };
@@ -425,7 +428,6 @@
425428
49EDC7782EAA35630009D9A6 /* UDPPingSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UDPPingSession.swift; sourceTree = "<group>"; };
426429
49EDC77A2EAA35630009D9A6 /* OnlineStatusService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnlineStatusService.swift; sourceTree = "<group>"; };
427430
49EDC77C2EAA35630009D9A6 /* SendCoverageResultRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendCoverageResultRequest.swift; sourceTree = "<group>"; };
428-
011858BA6C01475DA0CBB31B /* AcceptableStatusCodeSendCoverageResultsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcceptableStatusCodeSendCoverageResultsService.swift; sourceTree = "<group>"; };
429431
49EDC77E2EAA35630009D9A6 /* BackgroundActivityActor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundActivityActor.swift; sourceTree = "<group>"; };
430432
49EDC77F2EAA35630009D9A6 /* CoverageResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoverageResultView.swift; sourceTree = "<group>"; };
431433
49EDC7802EAA35630009D9A6 /* Fence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fence.swift; sourceTree = "<group>"; };
@@ -902,6 +904,7 @@
902904
49EDC7742EAA35630009D9A6 /* Persistence */ = {
903905
isa = PBXGroup;
904906
children = (
907+
49643ED32EAF9267001E3B01 /* UserDatabase.swift */,
905908
49EDC76E2EAA35630009D9A6 /* PersistedFencesResender.swift */,
906909
49EDC76F2EAA35630009D9A6 /* PersistenceManagingCoverageResultsService.swift */,
907910
49EDC7702EAA35630009D9A6 /* PersistenceServiceActor.swift */,
@@ -2167,6 +2170,7 @@
21672170
E9E993BE26EA3DD600E7EED6 /* RMBTHistoryNetworkCell.swift in Sources */,
21682171
E9E993FD26EC951200E7EED6 /* RMBTHistoryQoSGroupResultCell.swift in Sources */,
21692172
E9400F1626BE71EE0067273A /* MapMeasurementRequest.swift in Sources */,
2173+
49643ED42EAF9267001E3B01 /* UserDatabase.swift in Sources */,
21702174
E9A23BF42764F62200717814 /* RMBTHistoryQoSSingleResult.swift in Sources */,
21712175
E9AA6420275DD6FA0079E5A1 /* RMBTHistoryPingGraphCell.swift in Sources */,
21722176
E959547C26E3B5DF004EA6D9 /* RMBTHistoryLoadingCell.swift in Sources */,

Sources/NetworkCoverage/NetworkCoverageFactory.swift

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,8 @@
66
// Copyright 2025 appscape gmbh. All rights reserved.
77

88
import Foundation
9-
import SwiftData
109
import AsyncAlgorithms
1110

12-
final class UserDatabase {
13-
static let shared = UserDatabase()
14-
15-
let container: ModelContainer
16-
17-
init(useInMemoryStore: Bool = false) {
18-
let configuration = ModelConfiguration(
19-
for: PersistentFence.self, PersistentCoverageSession.self,
20-
isStoredInMemoryOnly: useInMemoryStore
21-
)
22-
container = try! ModelContainer(
23-
for: PersistentFence.self, PersistentCoverageSession.self,
24-
configurations: configuration
25-
)
26-
}
27-
28-
lazy var modelContext: ModelContext = .init(container)
29-
}
30-
3111
struct NetworkCoverageFactory {
3212
// MARK: - Constants
3313
// FIXME: Temporary workaround - server returns 406 even on successful submissions
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// UserDatabase.swift
3+
// RMBT
4+
//
5+
// Created by Jiri Urbasek on 27.10.2025.
6+
// Copyright © 2025 appscape gmbh. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import SwiftData
11+
12+
final class UserDatabase {
13+
static let shared = UserDatabase()
14+
15+
let container: ModelContainer
16+
17+
init(useInMemoryStore: Bool = false) {
18+
let configuration = ModelConfiguration(
19+
for: PersistentFence.self, PersistentCoverageSession.self,
20+
isStoredInMemoryOnly: useInMemoryStore
21+
)
22+
container = try! ModelContainer(
23+
for: PersistentFence.self, PersistentCoverageSession.self,
24+
configurations: configuration
25+
)
26+
}
27+
28+
lazy var modelContext: ModelContext = .init(container)
29+
}
30+
31+
extension UserDatabase {
32+
/// Deletes all persisted coverage data using SwiftData ModelContext.
33+
/// Intended for debug-only usage.
34+
@discardableResult
35+
func deleteAllPersistedCoverageData() throws -> Int {
36+
var deleted = 0
37+
// Delete PersistentFence objects
38+
do {
39+
let fenceDescriptor = FetchDescriptor<PersistentFence>()
40+
let fences = try modelContext.fetch(fenceDescriptor)
41+
for fence in fences {
42+
modelContext.delete(fence)
43+
deleted += 1
44+
}
45+
} catch {
46+
// Bubble up to caller; they can decide what to do in DEBUG
47+
throw error
48+
}
49+
// Delete PersistentCoverageSession objects
50+
do {
51+
let sessionDescriptor = FetchDescriptor<PersistentCoverageSession>()
52+
let sessions = try modelContext.fetch(sessionDescriptor)
53+
for session in sessions {
54+
modelContext.delete(session)
55+
deleted += 1
56+
}
57+
} catch {
58+
throw error
59+
}
60+
try modelContext.save()
61+
return deleted
62+
}
63+
64+
func wipeOut() {
65+
#if DEBUG
66+
do {
67+
let deleted = try deleteAllPersistedCoverageData()
68+
Log.logger.debug("Cleared persisted coverage data. Deleted items: \(deleted)")
69+
} catch {
70+
Log.logger.error("Failed to clear persisted coverage data: \(String(describing: error))")
71+
}
72+
#endif
73+
}
74+
}

0 commit comments

Comments
 (0)