Skip to content

Commit b332019

Browse files
author
Benedikt Wagner
committed
improve training-data store, fix delete all data
1 parent 2f848ff commit b332019

File tree

5 files changed

+61
-43
lines changed

5 files changed

+61
-43
lines changed

CloudMaster/Features/Course/Views/CourseView.swift

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import SwiftUI
2+
23
struct CourseView: View {
34
@State private var isLoading = false
45
@State private var downloadProgress: [Course: Progress] = [:]
5-
@State private var userTrainingData = UserTrainingData()
6+
67
@State private var showingNotificationSettings = false
78
@State private var notificationsEnabled = false
89
@State private var showingInfoPopup = false
910

1011
@StateObject private var viewModel = DownloadViewModel()
1112
@StateObject private var questionLoader: QuestionLoader
1213

14+
@ObservedObject var userTrainingStore = UserTrainingStore.shared
15+
1316
@Environment(\.colorScheme) var colorScheme
1417

1518
let course: Course
@@ -37,7 +40,7 @@ struct CourseView: View {
3740
HStack {
3841
Image(systemName: "clock")
3942
.foregroundColor(.blue)
40-
Text(formatTimeSpent(userTrainingData.timeSpent))
43+
Text(formatTimeSpent(userTrainingStore.trainingData[course.shortName]?.timeSpent ?? 0))
4144
.font(.subheadline)
4245
}
4346
.padding(.top, 20)
@@ -101,7 +104,7 @@ struct CourseView: View {
101104
}
102105
}
103106
.onAppear {
104-
loadUserTrainingData(for: course)
107+
loadUserTrainingData()
105108
checkNotificationSettings()
106109
if questionLoader.questions.isEmpty {
107110
downloadCourse()
@@ -154,12 +157,8 @@ struct CourseView: View {
154157
}
155158
}
156159

157-
func loadUserTrainingData(for course: Course) {
158-
if let data = UserDefaults.standard.data(forKey: course.shortName) {
159-
if let decodedData = try? JSONDecoder().decode(UserTrainingData.self, from: data) {
160-
userTrainingData = decodedData
161-
}
162-
}
160+
func loadUserTrainingData() {
161+
_ = userTrainingStore.loadTrainingData(forCourse: course.shortName)
163162
}
164163

165164
func formatTimeSpent(_ time: TimeInterval) -> String {
@@ -234,5 +233,4 @@ struct CourseInformationPopup: View {
234233
}
235234
.padding()
236235
}
237-
238236
}

CloudMaster/Features/Settings/Views/SettingsView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct SettingsView: View {
1212
Section(header: Text("Training Data Management")) {
1313
Button(action: {
1414
showAlertWith(title: "Delete Trainingsdata", message: "Are you sure you want to delete all training data?", action: {
15-
UserTrainingStore.shared.resetTrainingData()
15+
UserTrainingStore.shared.deleteAllTrainingData()
1616
})
1717
}) {
1818
Text("Delete Training data")
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import Foundation
2+
import SwiftUI
23

3-
struct UserTrainingData: Codable {
4+
struct UserTrainingData: Codable, Identifiable {
5+
var id = UUID()
6+
let shortName: String
7+
48
var timeSpent: TimeInterval
59
var correctAnswers: Int
610
var wrongAnswers: Int
711
var questionAttempts: [UUID: Int] // Mapping question ID to the number of attempts
812
var questionStats: [UUID: QuestionStats] // Mapping question ID to the stats
913

10-
init() {
14+
init(shortName: String) {
15+
self.shortName = shortName
1116
self.timeSpent = 0
1217
self.correctAnswers = 0
1318
self.wrongAnswers = 0
@@ -16,6 +21,7 @@ struct UserTrainingData: Codable {
1621
}
1722

1823
mutating func updateStats(for questionID: UUID, correctChoices: Set<UUID>, selectedChoices: Set<UUID>) {
24+
1925
// Update question attempts
2026
if let attempts = questionAttempts[questionID] {
2127
questionAttempts[questionID] = attempts + 1
@@ -38,7 +44,6 @@ struct UserTrainingData: Codable {
3844
self.questionStats[questionID] = QuestionStats(timesViewed: 1, timesCorrect: timesCorrect, timesIncorrect: timesIncorrect)
3945
}
4046
}
41-
4247
}
4348

4449
struct QuestionStats: Codable {
@@ -47,33 +52,42 @@ struct QuestionStats: Codable {
4752
var timesIncorrect: Int
4853
}
4954

50-
class UserTrainingStore {
55+
class UserTrainingStore: ObservableObject {
5156
static let shared = UserTrainingStore()
52-
private let userDefaultsKey = "userTrainingData"
57+
private let userDefaultsKeyPrefix = "userTrainingData_"
5358

54-
private init() {
55-
loadTrainingData()
56-
}
59+
private init() {}
5760

58-
var trainingData: UserTrainingData = UserTrainingData()
61+
@Published var trainingData: [String: UserTrainingData] = [:]
5962

60-
func loadTrainingData() {
61-
if let data = UserDefaults.standard.data(forKey: userDefaultsKey) {
62-
if let decodedData = try? JSONDecoder().decode(UserTrainingData.self, from: data) {
63-
trainingData = decodedData
64-
}
63+
func loadTrainingData(forCourse shortName: String) -> UserTrainingData {
64+
if let data = UserDefaults.standard.data(forKey: userDefaultsKeyPrefix + shortName),
65+
let decodedData = try? JSONDecoder().decode(UserTrainingData.self, from: data) {
66+
trainingData[shortName] = decodedData
67+
return decodedData
68+
} else {
69+
let newTrainingData = UserTrainingData(shortName: shortName)
70+
trainingData[shortName] = newTrainingData
71+
return newTrainingData
6572
}
6673
}
6774

68-
func saveTrainingData() {
69-
if let data = try? JSONEncoder().encode(trainingData) {
70-
UserDefaults.standard.set(data, forKey: userDefaultsKey)
75+
func saveTrainingData(_ data: UserTrainingData) {
76+
trainingData[data.shortName] = data
77+
if let encoded = try? JSONEncoder().encode(data) {
78+
UserDefaults.standard.set(encoded, forKey: userDefaultsKeyPrefix + data.shortName)
7179
}
7280
}
7381

74-
func resetTrainingData() {
75-
trainingData = UserTrainingData()
76-
saveTrainingData()
77-
UserDefaults.standard.removeObject(forKey: userDefaultsKey)
82+
func deleteTrainingData(forCourse shortName: String) {
83+
trainingData.removeValue(forKey: shortName)
84+
UserDefaults.standard.removeObject(forKey: userDefaultsKeyPrefix + shortName)
85+
}
86+
87+
func deleteAllTrainingData() {
88+
trainingData.keys.forEach { shortName in
89+
UserDefaults.standard.removeObject(forKey: userDefaultsKeyPrefix + shortName)
90+
}
91+
trainingData.removeAll()
7892
}
7993
}

CloudMaster/Features/Training/Views/TrainingView.swift

+14-10
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ struct TrainingView: View {
44
@State private var currentQuestionIndex = 0
55
@State private var selectedChoices: Set<UUID> = []
66
@State private var showResult = false
7-
@State private var userTrainingData = UserTrainingStore.shared.trainingData
87
@State private var startTime: Date?
98
@State private var isBookmarked: Bool = false
109
@Environment(\.presentationMode) var presentationMode
1110

11+
@ObservedObject var userTrainingStore = UserTrainingStore.shared
12+
1213
let course: Course
1314
@StateObject private var questionLoader: QuestionLoader
1415

@@ -95,6 +96,7 @@ struct TrainingView: View {
9596
.navigationBarHidden(true)
9697
.onAppear {
9798
startTime = Date()
99+
loadUserTrainingData()
98100
updateBookmarkState() // Ensure bookmark state is updated when the view appears
99101
}
100102
.onDisappear {
@@ -161,30 +163,32 @@ struct TrainingView: View {
161163
}
162164

163165
func updateUserTrainingData(for question: Question) {
166+
guard var userTrainingData = userTrainingStore.trainingData[course.shortName] else { return }
167+
164168
if let startTime = startTime {
165169
userTrainingData.timeSpent += Date().timeIntervalSince(startTime)
166170
}
167-
171+
172+
print(userTrainingData.timeSpent)
173+
168174
let correctChoices = Set(question.choices.filter { $0.correct }.map { $0.id })
169175
let userCorrectChoices = selectedChoices.intersection(correctChoices)
170176

171177
userTrainingData.correctAnswers += userCorrectChoices.count
172178
userTrainingData.wrongAnswers += selectedChoices.subtracting(correctChoices).count
173179

174180
userTrainingData.updateStats(for: question.id, correctChoices: correctChoices, selectedChoices: selectedChoices)
181+
182+
userTrainingStore.saveTrainingData(userTrainingData)
175183
}
176184

177-
func loadUserTrainingData(for course: Course) {
178-
if let data = UserDefaults.standard.data(forKey: course.shortName) {
179-
if let decodedData = try? JSONDecoder().decode(UserTrainingData.self, from: data) {
180-
userTrainingData = decodedData
181-
}
182-
}
185+
func loadUserTrainingData() {
186+
_ = userTrainingStore.loadTrainingData(forCourse: course.shortName)
183187
}
184188

185189
func saveUserTrainingData() {
186-
if let data = try? JSONEncoder().encode(userTrainingData) {
187-
UserDefaults.standard.set(data, forKey: course.shortName)
190+
if let userTrainingData = userTrainingStore.trainingData[course.shortName] {
191+
userTrainingStore.saveTrainingData(userTrainingData)
188192
}
189193
}
190194
}

CloudMaster/Utilities/QuestionLoader.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ class QuestionLoader: ObservableObject {
7979
}
8080

8181
private func reorderQuestions(_ questions: [Question]) -> [Question] {
82-
let trainingData = UserTrainingStore.shared.trainingData
82+
guard let trainingData = UserTrainingStore.shared.trainingData[questions.first?.id.uuidString ?? ""] else {
83+
return questions
84+
}
8385

8486
let newQuestions = questions.filter { trainingData.questionStats[$0.id] == nil }
8587
let incorrectQuestions = questions.filter {

0 commit comments

Comments
 (0)