diff --git a/Sora/SoraApp.swift b/Sora/SoraApp.swift index f394ce4..80ebdd2 100644 --- a/Sora/SoraApp.swift +++ b/Sora/SoraApp.swift @@ -20,9 +20,13 @@ struct SoraApp: App { UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = userAccentColor } - Task { @MainActor in + Task { await Self.clearTmpFolder() + await MainActor.run { + jsController.initializeDownloadSession() + } + TraktToken.checkAuthenticationStatus { isAuthenticated in if isAuthenticated { Logger.shared.log("Trakt authentication is valid", type: "Debug") diff --git a/Sora/Utlis & Misc/DownloadUtils/DownloadManager.swift b/Sora/Utlis & Misc/DownloadUtils/DownloadManager.swift index e3eabd5..0e330e6 100644 --- a/Sora/Utlis & Misc/DownloadUtils/DownloadManager.swift +++ b/Sora/Utlis & Misc/DownloadUtils/DownloadManager.swift @@ -21,25 +21,40 @@ class DownloadManager: NSObject, ObservableObject { override init() { super.init() - initializeDownloadSession() + Task { + await initializeDownloadSession() + } loadLocalContent() } - private func initializeDownloadSession() { + private func initializeDownloadSession() async { #if targetEnvironment(simulator) Logger.shared.log("Download Sessions are not available on Simulator", type: "Error") #else - let configuration = URLSessionConfiguration.background(withIdentifier: "hls-downloader") - - assetDownloadURLSession = AVAssetDownloadURLSession( - configuration: configuration, - assetDownloadDelegate: self, - delegateQueue: .main - ) + await MainActor.run { + let configuration = URLSessionConfiguration.background(withIdentifier: "hls-downloader") + + assetDownloadURLSession = AVAssetDownloadURLSession( + configuration: configuration, + assetDownloadDelegate: self, + delegateQueue: .main + ) + } #endif } func downloadAsset(from url: URL, headers: [String: String]? = nil, subtitleURL: URL? = nil) { + guard assetDownloadURLSession != nil else { + Logger.shared.log("Download session not initialized yet, retrying...", type: "Warning") + Task { + await initializeDownloadSession() + await MainActor.run { + self.downloadAsset(from: url, headers: headers, subtitleURL: subtitleURL) + } + } + return + } + if let headers = headers { activeDownloadHeaders[url] = headers } diff --git a/Sora/Utlis & Misc/JSLoader/Downloads/JSController+Downloader.swift b/Sora/Utlis & Misc/JSLoader/Downloads/JSController+Downloader.swift index 9ebe998..810a917 100644 --- a/Sora/Utlis & Misc/JSLoader/Downloads/JSController+Downloader.swift +++ b/Sora/Utlis & Misc/JSLoader/Downloads/JSController+Downloader.swift @@ -143,7 +143,15 @@ extension JSController { } guard let downloadSession = downloadURLSession else { - completionHandler?(false, "Download session not available") + Logger.shared.log("Download session not initialized, initializing and retrying...", type: "Warning") + Task { + await MainActor.run { + self.initializeDownloadSession() + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + self.downloadMP4(request: request, completionHandler: completionHandler) + } + } + } return } diff --git a/Sora/Utlis & Misc/JSLoader/Downloads/JSController-Downloads.swift b/Sora/Utlis & Misc/JSLoader/Downloads/JSController-Downloads.swift index 68ec73f..024d44a 100644 --- a/Sora/Utlis & Misc/JSLoader/Downloads/JSController-Downloads.swift +++ b/Sora/Utlis & Misc/JSLoader/Downloads/JSController-Downloads.swift @@ -46,24 +46,25 @@ extension JSController { #if targetEnvironment(simulator) Logger.shared.log("Download Sessions are not available on Simulator", type: "Error") #else - // Create a unique identifier for the background session - let sessionIdentifier = "hls-downloader-\(UUID().uuidString)" + Task { + let sessionIdentifier = "hls-downloader-\(UUID().uuidString)" - let configuration = URLSessionConfiguration.background(withIdentifier: sessionIdentifier) + let configuration = URLSessionConfiguration.background(withIdentifier: sessionIdentifier) - // Configure session - configuration.allowsCellularAccess = true - configuration.shouldUseExtendedBackgroundIdleMode = true - configuration.waitsForConnectivity = true + configuration.allowsCellularAccess = true + configuration.shouldUseExtendedBackgroundIdleMode = true + configuration.waitsForConnectivity = true - // Create session with configuration - downloadURLSession = AVAssetDownloadURLSession( - configuration: configuration, - assetDownloadDelegate: self, - delegateQueue: .main - ) + await MainActor.run { + self.downloadURLSession = AVAssetDownloadURLSession( + configuration: configuration, + assetDownloadDelegate: self, + delegateQueue: .main + ) - print("Download session initialized with ID: \(sessionIdentifier)") + print("Download session initialized with ID: \(sessionIdentifier)") + } + } #endif loadSavedAssets() @@ -208,6 +209,17 @@ extension JSController { // Set flag to prevent multiple concurrent processing isProcessingQueue = true + // Check if download session is ready before processing queue + guard downloadURLSession != nil else { + print("Download session not ready, deferring queue processing...") + isProcessingQueue = false + // Retry after a delay to allow session initialization + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in + self?.processDownloadQueue() + } + return + } + // Calculate how many more downloads we can start let activeCount = activeDownloads.count let slotsAvailable = max(0, maxConcurrentDownloads - activeCount) @@ -288,8 +300,15 @@ extension JSController { return } - // Create the download task - guard let task = downloadURLSession?.makeAssetDownloadTask( + guard let downloadSession = downloadURLSession else { + print("Download session not yet initialized, retrying in background...") + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in + self?.startQueuedDownload(queuedDownload) + } + return + } + + guard let task = downloadSession.makeAssetDownloadTask( asset: asset, assetTitle: queuedDownload.title ?? queuedDownload.originalURL.lastPathComponent, assetArtworkData: nil, @@ -1627,4 +1646,4 @@ enum DownloadQueueStatus: Equatable { case downloading /// Download has been completed case completed -} \ No newline at end of file +} diff --git a/Sora/Utlis & Misc/JSLoader/JSController.swift b/Sora/Utlis & Misc/JSLoader/JSController.swift index 5024428..25b074d 100644 --- a/Sora/Utlis & Misc/JSLoader/JSController.swift +++ b/Sora/Utlis & Misc/JSLoader/JSController.swift @@ -69,13 +69,14 @@ class JSController: NSObject, ObservableObject { context.exceptionHandler = { context, exception in print("[JS Exception]", exception?.toString() ?? "unknown") } - setupDownloadSession() } private func setupDownloadSession() { if downloadURLSession == nil { - initializeDownloadSession() - setupDownloadFunction() + Task { + initializeDownloadSession() + setupDownloadFunction() + } } }