diff options
7 files changed, 34 insertions, 73 deletions
diff --git a/ios/MullvadMockData/MullvadREST/MockRelayCache.swift b/ios/MullvadMockData/MullvadREST/MockRelayCache.swift index d41173d111..122a3e93ce 100644 --- a/ios/MullvadMockData/MullvadREST/MockRelayCache.swift +++ b/ios/MullvadMockData/MullvadREST/MockRelayCache.swift @@ -5,8 +5,8 @@ // Created by Mojgan on 2025-03-10. // Copyright © 2025 Mullvad VPN AB. All rights reserved. // -import Foundation +import Foundation @testable import MullvadREST public struct MockRelayCache: RelayCacheProtocol { diff --git a/ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 190c222682..3ac5cc069c 100644 --- a/ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "159534cbc9364e3882c14ea288a06d732b74555d93ae12274bcfad4509104caf", + "originHash" : "df1c07b51917a1cc3ae17733b2b162190d08c52c14f2eb6f68410c133c2f28cc", "pins" : [ { "identity" : "swift-log", diff --git a/ios/MullvadVPN/Classes/ConsolidatedApplicationLog.swift b/ios/MullvadVPN/Classes/ConsolidatedApplicationLog.swift index ef357445c5..5cb79a5705 100644 --- a/ios/MullvadVPN/Classes/ConsolidatedApplicationLog.swift +++ b/ios/MullvadVPN/Classes/ConsolidatedApplicationLog.swift @@ -7,7 +7,6 @@ // import Foundation -import Operations private let kLogDelimiter = "====================" private let kRedactedPlaceholder = "[REDACTED]" @@ -17,7 +16,6 @@ private let kRedactedContainerPlaceholder = "[REDACTED CONTAINER PATH]" class ConsolidatedApplicationLog: TextOutputStreamable, @unchecked Sendable { typealias Metadata = KeyValuePairs<MetadataKey, String> private let bufferSize: UInt64 - private var workItem: DispatchWorkItem? enum MetadataKey: String { case id, os @@ -52,36 +50,21 @@ class ConsolidatedApplicationLog: TextOutputStreamable, @unchecked Sendable { } } - func cancel() { - workItem?.cancel() - } - - func addLogFiles(fileURLs: [URL], completion: (@Sendable (Result<String, Error>) -> Void)? = nil) { - let workItem = DispatchWorkItem { [weak self] in + func addLogFiles(fileURLs: [URL], completion: (@Sendable () -> Void)? = nil) { + logQueue.async(flags: .barrier) { for fileURL in fileURLs { - guard let workItem = self?.workItem, !workItem.isCancelled else { - DispatchQueue.main.async { - completion?(.failure(OperationError.cancelled)) - } - return - } - - self?.addSingleLogFile(fileURL) + self.addSingleLogFile(fileURL) } - DispatchQueue.main.async { [weak self] in - guard let self else { return } - completion?(.success(self.string)) + DispatchQueue.main.async { + completion?() } } - self.workItem = workItem - - logQueue.async(execute: workItem) } func addError(message: String, error: String, completion: (@Sendable () -> Void)? = nil) { let redactedError = redact(string: error) - safeAsync { [weak self] in - self?.logs.append(LogAttachment(label: message, content: redactedError)) + logQueue.async(flags: .barrier) { + self.logs.append(LogAttachment(label: message, content: redactedError)) DispatchQueue.main.async { completion?() } @@ -125,17 +108,6 @@ class ConsolidatedApplicationLog: TextOutputStreamable, @unchecked Sendable { return result } - private func safeAsync(execute: @escaping @Sendable () -> Void) { - let isCancelled = workItem?.isCancelled ?? false - guard !isCancelled else { return } - - logQueue.async { - if !isCancelled { - execute() - } - } - } - private func addSingleLogFile(_ fileURL: URL) { guard fileURL.isFileURL else { addError( @@ -150,8 +122,8 @@ class ConsolidatedApplicationLog: TextOutputStreamable, @unchecked Sendable { if let lossyString = readFileLossy(path: path, maxBytes: bufferSize) { let redactedString = redact(string: lossyString) - safeAsync { [weak self] in - self?.logs.append(LogAttachment(label: redactedPath, content: redactedString)) + logQueue.async(flags: .barrier) { + self.logs.append(LogAttachment(label: redactedPath, content: redactedString)) } } else { addError(message: redactedPath, error: "Log file does not exist: \(path).") diff --git a/ios/MullvadVPN/Notifications/Notification Providers/NewDeviceNotificationProvider.swift b/ios/MullvadVPN/Notifications/Notification Providers/NewDeviceNotificationProvider.swift index 66a448db4d..eb6b9ef32f 100644 --- a/ios/MullvadVPN/Notifications/Notification Providers/NewDeviceNotificationProvider.swift +++ b/ios/MullvadVPN/Notifications/Notification Providers/NewDeviceNotificationProvider.swift @@ -36,7 +36,7 @@ final class NewDeviceNotificationProvider: NotificationProvider, return NSAttributedString( markdownString: string, options: MarkdownStylingOptions( - font: .preferredFont(forTextStyle: .body) + font: .preferredFont(forTextStyle: .subheadline) ) ) { _, _ in [.foregroundColor: UIColor.InAppNotificationBanner.titleColor] diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportInteractor.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportInteractor.swift index 400db47dd1..194e7271f8 100644 --- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportInteractor.swift +++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportInteractor.swift @@ -29,10 +29,13 @@ final class ProblemReportInteractor: @unchecked Sendable { ) } - func fetchReportString(completion: @escaping @Sendable (Result<String, Error>) -> Void) { + func fetchReportString(completion: @escaping @Sendable (String) -> Void) { consolidatedLog.addLogFiles(fileURLs: ApplicationTarget.allCases.flatMap { ApplicationConfiguration.logFileURLs(for: $0, in: ApplicationConfiguration.containerURL) - }, completion: completion) + }) { [weak self] in + guard let self else { return } + completion(consolidatedLog.string) + } } func sendReport( @@ -41,19 +44,15 @@ final class ProblemReportInteractor: @unchecked Sendable { completion: @escaping @Sendable (Result<Void, Error>) -> Void ) { let logString = self.consolidatedLog.string + if logString.isEmpty { - fetchReportString { [weak self] result in - switch result { - case let .success(logString): - self?.sendProblemReport( - email: email, - message: message, - logString: logString, - completion: completion - ) - case let .failure(error): - completion(.failure(error)) - } + fetchReportString { [weak self] updatedLogString in + self?.sendProblemReport( + email: email, + message: message, + logString: updatedLogString, + completion: completion + ) } } else { sendProblemReport( @@ -66,7 +65,6 @@ final class ProblemReportInteractor: @unchecked Sendable { } func cancelSendingReport() { - consolidatedLog.cancel() requestCancellable?.cancel() } @@ -87,7 +85,7 @@ final class ProblemReportInteractor: @unchecked Sendable { metadata: metadataDict ) - requestCancellable = self.apiProxy.sendProblemReport(request, retryStrategy: .default) { result in + requestCancellable = apiProxy.sendProblemReport(request, retryStrategy: .default) { result in DispatchQueue.main.async { completion(result) } diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift index 3ba1ca5f58..01d7afb09c 100644 --- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift +++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift @@ -95,28 +95,20 @@ class ProblemReportReviewViewController: UIViewController { private func loadLogs() { spinnerView.startAnimating() - interactor.fetchReportString { [weak self] result in + interactor.fetchReportString { [weak self] reportString in guard let self else { return } - - if case let .success(reportString) = result { - Task { @MainActor in - textView.text = reportString - spinnerView.stopAnimating() - spinnerContainerView.isHidden = true - } + Task { @MainActor in + textView.text = reportString + spinnerView.stopAnimating() + spinnerContainerView.isHidden = true } } } #if DEBUG private func share() { - interactor.fetchReportString { [weak self] result in - guard - let self, - case let .success(reportString) = result, - !reportString.isEmpty - else { return } - + interactor.fetchReportString { [weak self] reportString in + guard let self,!reportString.isEmpty else { return } Task { @MainActor in let activityController = UIActivityViewController( activityItems: [reportString], diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift index 0d7148380f..005a81bd64 100644 --- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift +++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift @@ -62,8 +62,7 @@ class ProblemReportSubmissionOverlayView: UIView { tableName: "ProblemReport", value: "Thanks!", comment: "" - ), - attributes: [.foregroundColor: UIColor.successColor] + ) ) if email.isEmpty { |
