From 2777ff6766a52a8aad5209f04dc38406a2aadc80 Mon Sep 17 00:00:00 2001 From: Benedikt Wagner Date: Fri, 21 Jun 2024 07:51:18 +0700 Subject: [PATCH 1/3] add simple image download error handling --- CloudMaster/Utilities/DownloadUtility.swift | 137 +++++++++++--------- 1 file changed, 77 insertions(+), 60 deletions(-) diff --git a/CloudMaster/Utilities/DownloadUtility.swift b/CloudMaster/Utilities/DownloadUtility.swift index 32d8e0d..e301eaf 100644 --- a/CloudMaster/Utilities/DownloadUtility.swift +++ b/CloudMaster/Utilities/DownloadUtility.swift @@ -3,28 +3,28 @@ import Foundation class DownloadUtility { private static var downloadTasks: [String: URLSessionDownloadTask] = [:] private static let downloadQueue = DispatchQueue(label: "com.example.downloadQueue") - + static func downloadAndConvertCourse(course: Course, progressHandler: @escaping (Progress, String) -> Void, completion: @escaping (Result) -> Void) { guard let url = URL(string: course.questionURL) else { completion(.failure(NSError(domain: "Invalid URL", code: 1, userInfo: nil))) return } - + let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let destinationURL = documentsURL.appendingPathComponent("\(course.shortName).md") - + let task = URLSession.shared.downloadTask(with: url) { (tempURL, response, error) in downloadQueue.async { downloadTasks[course.shortName] = nil } - + if let error = error { DispatchQueue.main.async { completion(.failure(error)) } return } - + guard let tempURL = tempURL else { let error = NSError(domain: "com.example.error", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to download file"]) DispatchQueue.main.async { @@ -32,32 +32,32 @@ class DownloadUtility { } return } - + do { try FileManager.default.removeItemIfExists(at: destinationURL) try FileManager.default.moveItem(at: tempURL, to: destinationURL) - + let markdown = try String(contentsOf: destinationURL, encoding: .utf8) var questions = try parseMarkdown(markdown: markdown, course: course) - + let totalTasks = questions.count + 1 - var progress = Progress(totalUnitCount: Int64(totalTasks)) + let progress = Progress(totalUnitCount: Int64(totalTasks)) progress.completedUnitCount = 1 progressHandler(progress, "Questions for \(course.shortName)") - + questions = try downloadImages(for: questions, course: course) { completedImages, totalImages in progress.completedUnitCount = Int64(completedImages + 1) progressHandler(progress, "\(completedImages)/\(totalImages) assets for \(course.shortName)") } - + progress.completedUnitCount = Int64(totalTasks) progressHandler(progress, "Completed downloading \(course.shortName)") - + let jsonData = try JSONSerialization.data(withJSONObject: questions, options: .prettyPrinted) let jsonFileURL = documentsURL.appendingPathComponent("\(course.shortName).json") try FileManager.default.removeItemIfExists(at: jsonFileURL) try jsonData.write(to: jsonFileURL) - + DispatchQueue.main.async { print("Downloaded course: \(course.shortName)") completion(.success(())) @@ -68,14 +68,14 @@ class DownloadUtility { } } } - + downloadQueue.async { downloadTasks[course.shortName] = task } - + task.resume() } - + static func cancelDownload(for course: Course) { downloadQueue.async { if let task = downloadTasks[course.shortName] { @@ -84,7 +84,7 @@ class DownloadUtility { } } } - + private static func parseMarkdown(markdown: String, course: Course) throws -> [[String: Any]] { let lines = markdown.components(separatedBy: .newlines) var questions: [[String: Any]] = [] @@ -92,11 +92,11 @@ class DownloadUtility { var choices: [[String: Any]] = [] var correctCount = 0 var currentImagePaths: [String] = [] - + let questionPattern = try NSRegularExpression(pattern: "### (.+)") let choicePattern = try NSRegularExpression(pattern: "- \\[([ x])\\] (.+)") let imagePattern = try NSRegularExpression(pattern: "!\\[.*\\]\\((images/.+?)\\)") - + for line in lines { if let questionMatch = questionPattern.firstMatch(in: line, range: NSRange(line.startIndex..., in: line)) { if !currentQuestion.isEmpty { @@ -128,7 +128,7 @@ class DownloadUtility { } } } - + if !currentQuestion.isEmpty { currentQuestion["choices"] = choices if correctCount > 1 { @@ -138,73 +138,90 @@ class DownloadUtility { currentQuestion["images"] = currentImagePaths.map { ["path": $0, "url": nil, "downloaded": false] } questions.append(currentQuestion) } - + if questions.isEmpty { throw NSError(domain: "com.example.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Course has no questions, please contact developer"]) } - + return questions } - + private static func downloadImages(for questions: [[String: Any]], course: Course, progressHandler: @escaping (Int, Int) -> Void) throws -> [[String: Any]] { - let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! - let imagesDirectoryURL = documentsURL.appendingPathComponent("images/\(course.shortName)") - - try FileManager.default.createDirectory(at: imagesDirectoryURL, withIntermediateDirectories: true, attributes: nil) - - var updatedQuestions = questions - - let totalImages = questions.reduce(0) { count, question in - count + ((question["images"] as? [[String: Any]])?.count ?? 0) - } - - var downloadedImages = 0 - - for (index, question) in questions.enumerated() { - if let imagePaths = question["images"] as? [[String: Any]] { - var updatedImagePaths: [[String: Any]] = [] - for imagePath in imagePaths { - if let path = imagePath["path"] as? String { - let imageUrlStringMain = "\(course.repositoryURL)/blob/main/\(path.replacingOccurrences(of: "images/\(course.shortName)/", with: ""))".replacingOccurrences(of: "github.com", with: "raw.githubusercontent.com").replacingOccurrences(of: "/blob/", with: "/") - let imageUrlStringMaster = "\(course.repositoryURL)/blob/master/\(path.replacingOccurrences(of: "images/\(course.shortName)/", with: ""))".replacingOccurrences(of: "github.com", with: "raw.githubusercontent.com").replacingOccurrences(of: "/blob/", with: "/") - - if let imageUrlMain = URL(string: imageUrlStringMain), let imageUrlMaster = URL(string: imageUrlStringMaster) { - var imageUrl: URL? = nil + let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + let imagesDirectoryURL = documentsURL.appendingPathComponent("images/\(course.shortName)") + + try FileManager.default.createDirectory(at: imagesDirectoryURL, withIntermediateDirectories: true, attributes: nil) + + var updatedQuestions = questions + + let totalImages = questions.reduce(0) { count, question in + count + ((question["images"] as? [[String: Any]])?.count ?? 0) + } + + var downloadedImages = 0 + var failedImages: [(String, String)] = [] + + for (index, question) in questions.enumerated() { + if let imagePaths = question["images"] as? [[String: Any]] { + var updatedImagePaths: [[String: Any]] = [] + for imagePath in imagePaths { + if let path = imagePath["path"] as? String { + // If the source-repository is using master branch instead of main branch. + let imageUrlStringMain = "\(course.repositoryURL)/blob/main/\(path.replacingOccurrences(of: "images/\(course.shortName)/", with: ""))".replacingOccurrences(of: "github.com", with: "raw.githubusercontent.com").replacingOccurrences(of: "/blob/", with: "/") + let imageUrlStringMaster = "\(course.repositoryURL)/blob/master/\(path.replacingOccurrences(of: "images/\(course.shortName)/", with: ""))".replacingOccurrences(of: "github.com", with: "raw.githubusercontent.com").replacingOccurrences(of: "/blob/", with: "/") + + if let imageUrlMain = URL(string: imageUrlStringMain), let imageUrlMaster = URL(string: imageUrlStringMaster) { + var imageUrl: URL? = nil + do { + _ = try Data(contentsOf: imageUrlMain) + imageUrl = imageUrlMain + } catch { do { - _ = try Data(contentsOf: imageUrlMain) - imageUrl = imageUrlMain - } catch { - _ = try? Data(contentsOf: imageUrlMaster) + _ = try Data(contentsOf: imageUrlMaster) imageUrl = imageUrlMaster + } catch { + failedImages.append((path, "Image not found")) } - - if let imageUrl = imageUrl { - print("Downloading image: \(imageUrl)") + } + + if let imageUrl = imageUrl { + do { let imageData = try Data(contentsOf: imageUrl) let imageFileName = path.replacingOccurrences(of: "images/\(course.shortName)/", with: "") let imageFileURL = imagesDirectoryURL.appendingPathComponent(imageFileName) - + let imageFileDirectory = imageFileURL.deletingLastPathComponent() try FileManager.default.createDirectory(at: imageFileDirectory, withIntermediateDirectories: true, attributes: nil) - + try FileManager.default.removeItemIfExists(at: imageFileURL) try imageData.write(to: imageFileURL) - + updatedImagePaths.append(["path": "images/\(course.shortName)/\(imageFileName)", "url": imageUrl.absoluteString, "downloaded": true]) downloadedImages += 1 progressHandler(downloadedImages, totalImages) + } catch { + failedImages.append((path, "Failed to save image")) } } } } - updatedQuestions[index]["images"] = updatedImagePaths } + updatedQuestions[index]["images"] = updatedImagePaths } - - return updatedQuestions } + + // Debug operation to identify download problems + if !failedImages.isEmpty { + var warningMessage = "Warning: Some images could not be downloaded:\n" + for (path, reason) in failedImages { + warningMessage += "Image: \(path) - Reason: \(reason)\n" + } + print(warningMessage) + } + + return updatedQuestions } - +} extension FileManager { func removeItemIfExists(at url: URL) throws { From 245f4bee22eb1e89924d95483358f5791e00451d Mon Sep 17 00:00:00 2001 From: Benedikt Wagner Date: Fri, 21 Jun 2024 07:51:36 +0700 Subject: [PATCH 2/3] Improve download overlay design --- .../Features/Common/DownloadOverlayView.swift | 88 +++++++++---------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/CloudMaster/Features/Common/DownloadOverlayView.swift b/CloudMaster/Features/Common/DownloadOverlayView.swift index 17fa65e..fecc163 100644 --- a/CloudMaster/Features/Common/DownloadOverlayView.swift +++ b/CloudMaster/Features/Common/DownloadOverlayView.swift @@ -3,69 +3,63 @@ import SwiftUI struct DownloadOverlayView: View { @Binding var isShowing: Bool @StateObject var viewModel: DownloadViewModel - + var body: some View { if isShowing { ZStack { Color.black.opacity(0.8) .edgesIgnoringSafeArea(.all) - + VStack { + Text("\(viewModel.completedDownloads) / \(Int(viewModel.totalCourses)) courses") + .font(.title2) + .foregroundColor(.white) + CircularProgressView(progress: $viewModel.overallProgress) .frame(width: 250, height: 250) .shadow(radius: 10) - - HStack { - if viewModel.totalCourses > 1 { - Text("\(viewModel.completedDownloads) / \(Int(viewModel.totalCourses)) courses") - .font(.headline) - .foregroundColor(.white) - .padding(.top, 10) - } - } - - Text(viewModel.statusMessage) - .font(.subheadline) - .bold() - .foregroundColor(.white) - .padding(.top, 5) + Text(viewModel.statusMessage) + .font(.subheadline) + .bold() + .foregroundColor(.gray) + .padding(.top, 10) } } } } -} - -struct CircularProgressView: View { - @Binding var progress: Double - - var body: some View { - ZStack { - Circle() - .stroke(lineWidth: 10.0) - .opacity(0.5) - .foregroundColor(Color.customSecondary) - - Circle() - .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0))) - .stroke(style: StrokeStyle(lineWidth: 10.0, lineCap: .round, lineJoin: .round)) - .foregroundColor(Color.customAccent) - .rotationEffect(Angle(degrees: 270.0)) - .animation(.linear, value: progress) - - if progress < 1.0 { - Text(String(format: "%.0f %%", min(self.progress, 1.0) * 100.0)) - .font(.largeTitle) - .bold() - } else { - withAnimation(.spring()) { - Image(systemName: "checkmark.circle.fill") - .resizable() - .foregroundColor(Color.correct) - .frame(width: 50, height: 50) + + struct CircularProgressView: View { + @Binding var progress: Double + + var body: some View { + ZStack { + Circle() + .stroke(lineWidth: 10.0) + .opacity(0.5) + .foregroundColor(Color.customSecondary) + + Circle() + .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0))) + .stroke(style: StrokeStyle(lineWidth: 10.0, lineCap: .round, lineJoin: .round)) + .foregroundColor(Color.customAccent) + .rotationEffect(Angle(degrees: 270.0)) + .animation(.linear, value: progress) + + if progress < 1.0 { + Text(String(format: "%.0f %%", min(self.progress, 1.0) * 100.0)) + .font(.largeTitle) + .bold() + } else { + withAnimation(.spring()) { + Image(systemName: "checkmark.circle.fill") + .resizable() + .foregroundColor(Color.correct) + .frame(width: 50, height: 50) + } } } + .padding(40) } - .padding(40) } } From d85820acc283b887aadb589d905891f97b72e6cb Mon Sep 17 00:00:00 2001 From: Benedikt Wagner Date: Fri, 21 Jun 2024 07:52:20 +0700 Subject: [PATCH 3/3] fix deprecation warnings --- .../UserInterfaceState.xcuserstate | Bin 31104 -> 60546 bytes CloudMaster/Constants/Courses.swift | 2 +- .../Features/Course/Views/CourseView.swift | 2 +- .../Features/Courses/Views/CoursesView.swift | 2 +- .../Features/Intro/Views/IntroView.swift | 2 +- .../Shared/Components/QuestionView.swift | 1 - .../Training/Views/TrainingView.swift | 1 - 7 files changed, 4 insertions(+), 6 deletions(-) diff --git a/CloudMaster.xcodeproj/project.xcworkspace/xcuserdata/benedikt.xcuserdatad/UserInterfaceState.xcuserstate b/CloudMaster.xcodeproj/project.xcworkspace/xcuserdata/benedikt.xcuserdatad/UserInterfaceState.xcuserstate index f1a17d0927ad22b65b2acce554132bb73be568ae..d696a8a73f91e0fd659f4ca3ba558ee3fcbccff8 100644 GIT binary patch literal 60546 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 literal 31104 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ⓈJ{6>j!ALTdjj}aU}@Mwa^bnzX0r*vvY5*+m( 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 diff --git a/CloudMaster/Constants/Courses.swift b/CloudMaster/Constants/Courses.swift index 8e21a5d..f0e54e0 100644 --- a/CloudMaster/Constants/Courses.swift +++ b/CloudMaster/Constants/Courses.swift @@ -13,7 +13,7 @@ enum CodingKeys: String, CodingKey { } struct Course: Codable, Hashable, Identifiable { - let id = UUID() // Add this line + var id = UUID() // Add this line let fullName: String let shortName: String let description: String diff --git a/CloudMaster/Features/Course/Views/CourseView.swift b/CloudMaster/Features/Course/Views/CourseView.swift index 99bdaeb..68abf64 100644 --- a/CloudMaster/Features/Course/Views/CourseView.swift +++ b/CloudMaster/Features/Course/Views/CourseView.swift @@ -130,7 +130,7 @@ struct CourseView: View { ) ) .alert(isPresented: $viewModel.showAlert) { - Alert(title: Text("Download Error"), message: Text(viewModel.alertMessage ?? ""), dismissButton: .default(Text("OK"))) + Alert(title: Text("Download Error"), message: Text(viewModel.alertMessage), dismissButton: .default(Text("OK"))) } } diff --git a/CloudMaster/Features/Courses/Views/CoursesView.swift b/CloudMaster/Features/Courses/Views/CoursesView.swift index b41e594..9df8a0b 100644 --- a/CloudMaster/Features/Courses/Views/CoursesView.swift +++ b/CloudMaster/Features/Courses/Views/CoursesView.swift @@ -19,7 +19,7 @@ struct CoursesView: View { ) ) .alert(isPresented: $viewModel.showAlert) { - Alert(title: Text("Download Error"), message: Text(viewModel.alertMessage ?? ""), dismissButton: .default(Text("OK"))) + Alert(title: Text("Download Error"), message: Text(viewModel.alertMessage), dismissButton: .default(Text("OK"))) } } diff --git a/CloudMaster/Features/Intro/Views/IntroView.swift b/CloudMaster/Features/Intro/Views/IntroView.swift index 69f733c..b42a930 100644 --- a/CloudMaster/Features/Intro/Views/IntroView.swift +++ b/CloudMaster/Features/Intro/Views/IntroView.swift @@ -34,7 +34,7 @@ struct IntroView: View { viewModel.downloadCourses(favorites) } } - .onChange(of: viewModel.downloadCompleted) { completed in + .onChange(of: viewModel.downloadCompleted) { completed, _ in if completed { isAppConfigured = true } diff --git a/CloudMaster/Features/Shared/Components/QuestionView.swift b/CloudMaster/Features/Shared/Components/QuestionView.swift index 128f257..7e8f282 100644 --- a/CloudMaster/Features/Shared/Components/QuestionView.swift +++ b/CloudMaster/Features/Shared/Components/QuestionView.swift @@ -87,7 +87,6 @@ struct QuestionView: View { } private func adjustedFontSize(for text: String) -> CGFloat { - let maxWidth = UIScreen.main.bounds.width - 32 let baseFontSize: CGFloat = 20 let minFontSize: CGFloat = 14 diff --git a/CloudMaster/Features/Training/Views/TrainingView.swift b/CloudMaster/Features/Training/Views/TrainingView.swift index 5640a44..67b9e22 100644 --- a/CloudMaster/Features/Training/Views/TrainingView.swift +++ b/CloudMaster/Features/Training/Views/TrainingView.swift @@ -22,7 +22,6 @@ struct TrainingView: View { VStack { if !questionLoader.questions.isEmpty { let questions = Array(questionLoader.questions) - let totalQuestions = questions.count let question = questions[currentQuestionIndex] QuestionNavbar(