diff --git a/Authorization/AuthorizationTests/AuthorizationMock.generated.swift b/Authorization/AuthorizationTests/AuthorizationMock.generated.swift index e1c3b12b5..f17939bd4 100644 --- a/Authorization/AuthorizationTests/AuthorizationMock.generated.swift +++ b/Authorization/AuthorizationTests/AuthorizationMock.generated.swift @@ -2405,6 +2405,12 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { return __value } + open func removeAppSupportDirectoryUnusedContent() { + addInvocation(.m_removeAppSupportDirectoryUnusedContent) + let perform = methodPerformValue(.m_removeAppSupportDirectoryUnusedContent) as? () -> Void + perform?() + } + fileprivate enum MethodType { case m_publisher @@ -2421,6 +2427,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case m_fileUrl__for_blockId(Parameter) case m_resumeDownloading case m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>) + case m_removeAppSupportDirectoryUnusedContent case p_currentDownloadTask_get static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { @@ -2477,6 +2484,8 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) return Matcher.ComparisonResult(results) + + case (.m_removeAppSupportDirectoryUnusedContent, .m_removeAppSupportDirectoryUnusedContent): return .match case (.p_currentDownloadTask_get,.p_currentDownloadTask_get): return Matcher.ComparisonResult.match default: return .none } @@ -2498,6 +2507,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case let .m_fileUrl__for_blockId(p0): return p0.intValue case .m_resumeDownloading: return 0 case let .m_isLargeVideosSize__blocks_blocks(p0): return p0.intValue + case .m_removeAppSupportDirectoryUnusedContent: return 0 case .p_currentDownloadTask_get: return 0 } } @@ -2517,6 +2527,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case .m_fileUrl__for_blockId: return ".fileUrl(for:)" case .m_resumeDownloading: return ".resumeDownloading()" case .m_isLargeVideosSize__blocks_blocks: return ".isLargeVideosSize(blocks:)" + case .m_removeAppSupportDirectoryUnusedContent: return ".removeAppSupportDirectoryUnusedContent()" case .p_currentDownloadTask_get: return "[get] .currentDownloadTask" } } @@ -2673,6 +2684,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func fileUrl(for blockId: Parameter) -> Verify { return Verify(method: .m_fileUrl__for_blockId(`blockId`))} public static func resumeDownloading() -> Verify { return Verify(method: .m_resumeDownloading)} public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_isLargeVideosSize__blocks_blocks(`blocks`))} + public static func removeAppSupportDirectoryUnusedContent() -> Verify { return Verify(method: .m_removeAppSupportDirectoryUnusedContent)} public static var currentDownloadTask: Verify { return Verify(method: .p_currentDownloadTask_get) } } @@ -2722,6 +2734,9 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { return Perform(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), performs: perform) } + public static func removeAppSupportDirectoryUnusedContent(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeAppSupportDirectoryUnusedContent, performs: perform) + } } public func given(_ method: Given) { diff --git a/Core/Core/Data/CoreStorage.swift b/Core/Core/Data/CoreStorage.swift index b3a8faca0..5acf16b66 100644 --- a/Core/Core/Data/CoreStorage.swift +++ b/Core/Core/Data/CoreStorage.swift @@ -17,6 +17,7 @@ public protocol CoreStorage { var lastReviewDate: Date? {get set} var user: DataLayer.User? {get set} var userSettings: UserSettings? {get set} + var resetAppSupportDirectoryUserData: Bool? {get set} func clear() } @@ -31,6 +32,7 @@ public class CoreStorageMock: CoreStorage { public var lastReviewDate: Date? public var user: DataLayer.User? public var userSettings: UserSettings? + public var resetAppSupportDirectoryUserData: Bool? public func clear() {} public init() {} diff --git a/Core/Core/Network/DownloadManager.swift b/Core/Core/Network/DownloadManager.swift index 1ef8bcb3a..1db912da9 100644 --- a/Core/Core/Network/DownloadManager.swift +++ b/Core/Core/Network/DownloadManager.swift @@ -124,6 +124,8 @@ public protocol DownloadManagerProtocol { func resumeDownloading() throws func fileUrl(for blockId: String) -> URL? func isLargeVideosSize(blocks: [CourseBlock]) -> Bool + + func removeAppSupportDirectoryUnusedContent() } public enum DownloadManagerEvent { @@ -470,6 +472,60 @@ public class DownloadManager: DownloadManagerProtocol { debugLog("SaveFile Error", error.localizedDescription) } } + + public func removeAppSupportDirectoryUnusedContent() { + deleteMD5HashedFolders() + } + + private func getApplicationSupportDirectory() -> URL? { + let fileManager = FileManager.default + do { + let appSupportDirectory = try fileManager.url( + for: .applicationSupportDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: true + ) + return appSupportDirectory + } catch { + debugPrint("Error getting Application Support Directory: \(error)") + return nil + } + } + + private func isMD5Hash(_ folderName: String) -> Bool { + let md5Regex = "^[a-fA-F0-9]{32}$" + let predicate = NSPredicate(format: "SELF MATCHES %@", md5Regex) + return predicate.evaluate(with: folderName) + } + + private func deleteMD5HashedFolders() { + guard let appSupportDirectory = getApplicationSupportDirectory() else { + return + } + + let fileManager = FileManager.default + do { + let folderContents = try fileManager.contentsOfDirectory( + at: appSupportDirectory, + includingPropertiesForKeys: nil, + options: [] + ) + for folderURL in folderContents { + let folderName = folderURL.lastPathComponent + if isMD5Hash(folderName) { + do { + try fileManager.removeItem(at: folderURL) + debugPrint("Deleted folder: \(folderName)") + } catch { + debugPrint("Error deleting folder \(folderName): \(error)") + } + } + } + } catch { + debugPrint("Error reading contents of Application Support directory: \(error)") + } + } } @available(iOSApplicationExtension, unavailable) @@ -638,6 +694,9 @@ public class DownloadManagerMock: DownloadManagerProtocol { false } + public func removeAppSupportDirectoryUnusedContent() { + + } } #endif // swiftlint:enable file_length diff --git a/Course/CourseTests/CourseMock.generated.swift b/Course/CourseTests/CourseMock.generated.swift index 1b68b62f7..855432bc8 100644 --- a/Course/CourseTests/CourseMock.generated.swift +++ b/Course/CourseTests/CourseMock.generated.swift @@ -2831,6 +2831,12 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { return __value } + open func removeAppSupportDirectoryUnusedContent() { + addInvocation(.m_removeAppSupportDirectoryUnusedContent) + let perform = methodPerformValue(.m_removeAppSupportDirectoryUnusedContent) as? () -> Void + perform?() + } + fileprivate enum MethodType { case m_publisher @@ -2847,6 +2853,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case m_fileUrl__for_blockId(Parameter) case m_resumeDownloading case m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>) + case m_removeAppSupportDirectoryUnusedContent case p_currentDownloadTask_get static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { @@ -2903,6 +2910,8 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) return Matcher.ComparisonResult(results) + + case (.m_removeAppSupportDirectoryUnusedContent, .m_removeAppSupportDirectoryUnusedContent): return .match case (.p_currentDownloadTask_get,.p_currentDownloadTask_get): return Matcher.ComparisonResult.match default: return .none } @@ -2924,6 +2933,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case let .m_fileUrl__for_blockId(p0): return p0.intValue case .m_resumeDownloading: return 0 case let .m_isLargeVideosSize__blocks_blocks(p0): return p0.intValue + case .m_removeAppSupportDirectoryUnusedContent: return 0 case .p_currentDownloadTask_get: return 0 } } @@ -2943,6 +2953,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case .m_fileUrl__for_blockId: return ".fileUrl(for:)" case .m_resumeDownloading: return ".resumeDownloading()" case .m_isLargeVideosSize__blocks_blocks: return ".isLargeVideosSize(blocks:)" + case .m_removeAppSupportDirectoryUnusedContent: return ".removeAppSupportDirectoryUnusedContent()" case .p_currentDownloadTask_get: return "[get] .currentDownloadTask" } } @@ -3099,6 +3110,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func fileUrl(for blockId: Parameter) -> Verify { return Verify(method: .m_fileUrl__for_blockId(`blockId`))} public static func resumeDownloading() -> Verify { return Verify(method: .m_resumeDownloading)} public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_isLargeVideosSize__blocks_blocks(`blocks`))} + public static func removeAppSupportDirectoryUnusedContent() -> Verify { return Verify(method: .m_removeAppSupportDirectoryUnusedContent)} public static var currentDownloadTask: Verify { return Verify(method: .p_currentDownloadTask_get) } } @@ -3148,6 +3160,9 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { return Perform(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), performs: perform) } + public static func removeAppSupportDirectoryUnusedContent(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeAppSupportDirectoryUnusedContent, performs: perform) + } } public func given(_ method: Given) { diff --git a/Dashboard/DashboardTests/DashboardMock.generated.swift b/Dashboard/DashboardTests/DashboardMock.generated.swift index 27620fef4..5dd6af2cc 100644 --- a/Dashboard/DashboardTests/DashboardMock.generated.swift +++ b/Dashboard/DashboardTests/DashboardMock.generated.swift @@ -2144,6 +2144,12 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { return __value } + open func removeAppSupportDirectoryUnusedContent() { + addInvocation(.m_removeAppSupportDirectoryUnusedContent) + let perform = methodPerformValue(.m_removeAppSupportDirectoryUnusedContent) as? () -> Void + perform?() + } + fileprivate enum MethodType { case m_publisher @@ -2160,6 +2166,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case m_fileUrl__for_blockId(Parameter) case m_resumeDownloading case m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>) + case m_removeAppSupportDirectoryUnusedContent case p_currentDownloadTask_get static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { @@ -2216,6 +2223,8 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) return Matcher.ComparisonResult(results) + + case (.m_removeAppSupportDirectoryUnusedContent, .m_removeAppSupportDirectoryUnusedContent): return .match case (.p_currentDownloadTask_get,.p_currentDownloadTask_get): return Matcher.ComparisonResult.match default: return .none } @@ -2237,6 +2246,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case let .m_fileUrl__for_blockId(p0): return p0.intValue case .m_resumeDownloading: return 0 case let .m_isLargeVideosSize__blocks_blocks(p0): return p0.intValue + case .m_removeAppSupportDirectoryUnusedContent: return 0 case .p_currentDownloadTask_get: return 0 } } @@ -2256,6 +2266,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case .m_fileUrl__for_blockId: return ".fileUrl(for:)" case .m_resumeDownloading: return ".resumeDownloading()" case .m_isLargeVideosSize__blocks_blocks: return ".isLargeVideosSize(blocks:)" + case .m_removeAppSupportDirectoryUnusedContent: return ".removeAppSupportDirectoryUnusedContent()" case .p_currentDownloadTask_get: return "[get] .currentDownloadTask" } } @@ -2412,6 +2423,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func fileUrl(for blockId: Parameter) -> Verify { return Verify(method: .m_fileUrl__for_blockId(`blockId`))} public static func resumeDownloading() -> Verify { return Verify(method: .m_resumeDownloading)} public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_isLargeVideosSize__blocks_blocks(`blocks`))} + public static func removeAppSupportDirectoryUnusedContent() -> Verify { return Verify(method: .m_removeAppSupportDirectoryUnusedContent)} public static var currentDownloadTask: Verify { return Verify(method: .p_currentDownloadTask_get) } } @@ -2461,6 +2473,9 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { return Perform(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), performs: perform) } + public static func removeAppSupportDirectoryUnusedContent(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeAppSupportDirectoryUnusedContent, performs: perform) + } } public func given(_ method: Given) { diff --git a/Discovery/DiscoveryTests/DiscoveryMock.generated.swift b/Discovery/DiscoveryTests/DiscoveryMock.generated.swift index 28f8eba5a..7b7d2c10a 100644 --- a/Discovery/DiscoveryTests/DiscoveryMock.generated.swift +++ b/Discovery/DiscoveryTests/DiscoveryMock.generated.swift @@ -2338,6 +2338,12 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { return __value } + open func removeAppSupportDirectoryUnusedContent() { + addInvocation(.m_removeAppSupportDirectoryUnusedContent) + let perform = methodPerformValue(.m_removeAppSupportDirectoryUnusedContent) as? () -> Void + perform?() + } + fileprivate enum MethodType { case m_publisher @@ -2354,6 +2360,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case m_fileUrl__for_blockId(Parameter) case m_resumeDownloading case m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>) + case m_removeAppSupportDirectoryUnusedContent case p_currentDownloadTask_get static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { @@ -2410,6 +2417,8 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) return Matcher.ComparisonResult(results) + + case (.m_removeAppSupportDirectoryUnusedContent, .m_removeAppSupportDirectoryUnusedContent): return .match case (.p_currentDownloadTask_get,.p_currentDownloadTask_get): return Matcher.ComparisonResult.match default: return .none } @@ -2431,6 +2440,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case let .m_fileUrl__for_blockId(p0): return p0.intValue case .m_resumeDownloading: return 0 case let .m_isLargeVideosSize__blocks_blocks(p0): return p0.intValue + case .m_removeAppSupportDirectoryUnusedContent: return 0 case .p_currentDownloadTask_get: return 0 } } @@ -2450,6 +2460,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case .m_fileUrl__for_blockId: return ".fileUrl(for:)" case .m_resumeDownloading: return ".resumeDownloading()" case .m_isLargeVideosSize__blocks_blocks: return ".isLargeVideosSize(blocks:)" + case .m_removeAppSupportDirectoryUnusedContent: return ".removeAppSupportDirectoryUnusedContent()" case .p_currentDownloadTask_get: return "[get] .currentDownloadTask" } } @@ -2606,6 +2617,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func fileUrl(for blockId: Parameter) -> Verify { return Verify(method: .m_fileUrl__for_blockId(`blockId`))} public static func resumeDownloading() -> Verify { return Verify(method: .m_resumeDownloading)} public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_isLargeVideosSize__blocks_blocks(`blocks`))} + public static func removeAppSupportDirectoryUnusedContent() -> Verify { return Verify(method: .m_removeAppSupportDirectoryUnusedContent)} public static var currentDownloadTask: Verify { return Verify(method: .p_currentDownloadTask_get) } } @@ -2655,6 +2667,9 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { return Perform(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), performs: perform) } + public static func removeAppSupportDirectoryUnusedContent(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeAppSupportDirectoryUnusedContent, performs: perform) + } } public func given(_ method: Given) { diff --git a/Discussion/DiscussionTests/DiscussionMock.generated.swift b/Discussion/DiscussionTests/DiscussionMock.generated.swift index d8324dd64..85aa084a5 100644 --- a/Discussion/DiscussionTests/DiscussionMock.generated.swift +++ b/Discussion/DiscussionTests/DiscussionMock.generated.swift @@ -3275,6 +3275,12 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { return __value } + open func removeAppSupportDirectoryUnusedContent() { + addInvocation(.m_removeAppSupportDirectoryUnusedContent) + let perform = methodPerformValue(.m_removeAppSupportDirectoryUnusedContent) as? () -> Void + perform?() + } + fileprivate enum MethodType { case m_publisher @@ -3291,6 +3297,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case m_fileUrl__for_blockId(Parameter) case m_resumeDownloading case m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>) + case m_removeAppSupportDirectoryUnusedContent case p_currentDownloadTask_get static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { @@ -3347,6 +3354,8 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) return Matcher.ComparisonResult(results) + + case (.m_removeAppSupportDirectoryUnusedContent, .m_removeAppSupportDirectoryUnusedContent): return .match case (.p_currentDownloadTask_get,.p_currentDownloadTask_get): return Matcher.ComparisonResult.match default: return .none } @@ -3368,6 +3377,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case let .m_fileUrl__for_blockId(p0): return p0.intValue case .m_resumeDownloading: return 0 case let .m_isLargeVideosSize__blocks_blocks(p0): return p0.intValue + case .m_removeAppSupportDirectoryUnusedContent: return 0 case .p_currentDownloadTask_get: return 0 } } @@ -3387,6 +3397,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case .m_fileUrl__for_blockId: return ".fileUrl(for:)" case .m_resumeDownloading: return ".resumeDownloading()" case .m_isLargeVideosSize__blocks_blocks: return ".isLargeVideosSize(blocks:)" + case .m_removeAppSupportDirectoryUnusedContent: return ".removeAppSupportDirectoryUnusedContent()" case .p_currentDownloadTask_get: return "[get] .currentDownloadTask" } } @@ -3543,6 +3554,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func fileUrl(for blockId: Parameter) -> Verify { return Verify(method: .m_fileUrl__for_blockId(`blockId`))} public static func resumeDownloading() -> Verify { return Verify(method: .m_resumeDownloading)} public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_isLargeVideosSize__blocks_blocks(`blocks`))} + public static func removeAppSupportDirectoryUnusedContent() -> Verify { return Verify(method: .m_removeAppSupportDirectoryUnusedContent)} public static var currentDownloadTask: Verify { return Verify(method: .p_currentDownloadTask_get) } } @@ -3592,6 +3604,9 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { return Perform(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), performs: perform) } + public static func removeAppSupportDirectoryUnusedContent(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeAppSupportDirectoryUnusedContent, performs: perform) + } } public func given(_ method: Given) { diff --git a/OpenEdX/Data/AppStorage.swift b/OpenEdX/Data/AppStorage.swift index ff17e4128..e21a94513 100644 --- a/OpenEdX/Data/AppStorage.swift +++ b/OpenEdX/Data/AppStorage.swift @@ -203,7 +203,20 @@ public class AppStorage: CoreStorage, ProfileStorage, WhatsNewStorage, CourseSto } } } - + + public var resetAppSupportDirectoryUserData: Bool? { + get { + return userDefaults.bool(forKey: KEY_RESET_APP_SUPPORT_DIRECTORY_USER_DATA) + } + set(newValue) { + if let newValue { + userDefaults.set(newValue, forKey: KEY_RESET_APP_SUPPORT_DIRECTORY_USER_DATA) + } else { + userDefaults.removeObject(forKey: KEY_RESET_APP_SUPPORT_DIRECTORY_USER_DATA) + } + } + } + public func clear() { accessToken = nil refreshToken = nil @@ -223,4 +236,5 @@ public class AppStorage: CoreStorage, ProfileStorage, WhatsNewStorage, CourseSto private let KEY_APPLE_SIGN_FULLNAME = "appleSignFullName" private let KEY_APPLE_SIGN_EMAIL = "appleSignEmail" private let KEY_ALLOWED_DOWNLOAD_LARGE_FILE = "allowedDownloadLargeFile" + private let KEY_RESET_APP_SUPPORT_DIRECTORY_USER_DATA = "resetAppSupportDirectoryUserData" } diff --git a/OpenEdX/RouteController.swift b/OpenEdX/RouteController.swift index ac53c3d36..6df0b22c0 100644 --- a/OpenEdX/RouteController.swift +++ b/OpenEdX/RouteController.swift @@ -44,6 +44,7 @@ class RouteController: UIViewController { } } + resetAppSupportDirectoryUserData() coreAnalytics.trackEvent(.launch, biValue: .launch) } @@ -99,4 +100,23 @@ class RouteController: UIViewController { } present(navigation, animated: false) } + + /** + This code will delete any old application’s downloaded user data, such as video files, + from the Application Support directory to optimize storage. This activity will be performed + only once during the upgrade from the old Open edX application to the new one or during + fresh installation. We can consider removing this code once we are confident that most or + all users have transitioned to the new application. + */ + private func resetAppSupportDirectoryUserData() { + guard var upgradationValue = Container.shared.resolve(CoreStorage.self), + let downloadManager = Container.shared.resolve(DownloadManagerProtocol.self), + upgradationValue.resetAppSupportDirectoryUserData == false + else { return } + + Task { + downloadManager.removeAppSupportDirectoryUnusedContent() + upgradationValue.resetAppSupportDirectoryUserData = true + } + } } diff --git a/Profile/ProfileTests/ProfileMock.generated.swift b/Profile/ProfileTests/ProfileMock.generated.swift index 1a3cd757b..35a5cae13 100644 --- a/Profile/ProfileTests/ProfileMock.generated.swift +++ b/Profile/ProfileTests/ProfileMock.generated.swift @@ -1612,6 +1612,12 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { return __value } + open func removeAppSupportDirectoryUnusedContent() { + addInvocation(.m_removeAppSupportDirectoryUnusedContent) + let perform = methodPerformValue(.m_removeAppSupportDirectoryUnusedContent) as? () -> Void + perform?() + } + fileprivate enum MethodType { case m_publisher @@ -1628,6 +1634,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case m_fileUrl__for_blockId(Parameter) case m_resumeDownloading case m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>) + case m_removeAppSupportDirectoryUnusedContent case p_currentDownloadTask_get static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { @@ -1684,6 +1691,8 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) return Matcher.ComparisonResult(results) + + case (.m_removeAppSupportDirectoryUnusedContent, .m_removeAppSupportDirectoryUnusedContent): return .match case (.p_currentDownloadTask_get,.p_currentDownloadTask_get): return Matcher.ComparisonResult.match default: return .none } @@ -1705,6 +1714,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case let .m_fileUrl__for_blockId(p0): return p0.intValue case .m_resumeDownloading: return 0 case let .m_isLargeVideosSize__blocks_blocks(p0): return p0.intValue + case .m_removeAppSupportDirectoryUnusedContent: return 0 case .p_currentDownloadTask_get: return 0 } } @@ -1724,6 +1734,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { case .m_fileUrl__for_blockId: return ".fileUrl(for:)" case .m_resumeDownloading: return ".resumeDownloading()" case .m_isLargeVideosSize__blocks_blocks: return ".isLargeVideosSize(blocks:)" + case .m_removeAppSupportDirectoryUnusedContent: return ".removeAppSupportDirectoryUnusedContent()" case .p_currentDownloadTask_get: return "[get] .currentDownloadTask" } } @@ -1880,6 +1891,7 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func fileUrl(for blockId: Parameter) -> Verify { return Verify(method: .m_fileUrl__for_blockId(`blockId`))} public static func resumeDownloading() -> Verify { return Verify(method: .m_resumeDownloading)} public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_isLargeVideosSize__blocks_blocks(`blocks`))} + public static func removeAppSupportDirectoryUnusedContent() -> Verify { return Verify(method: .m_removeAppSupportDirectoryUnusedContent)} public static var currentDownloadTask: Verify { return Verify(method: .p_currentDownloadTask_get) } } @@ -1929,6 +1941,9 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { return Perform(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), performs: perform) } + public static func removeAppSupportDirectoryUnusedContent(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeAppSupportDirectoryUnusedContent, performs: perform) + } } public func given(_ method: Given) {