From 9d42790f2b6fb8e1b186961b44c7931e263f93a7 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Sun, 29 Jun 2025 17:15:07 +0200 Subject: [PATCH] add Signed-off-by: Marino Faggiana --- Sources/NextcloudKit/NKCommon.swift | 2 ++ Sources/NextcloudKit/NKSession.swift | 35 +++++++++++++++---- .../NextcloudKit/NextcloudKitBackground.swift | 22 ++++++++---- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/Sources/NextcloudKit/NKCommon.swift b/Sources/NextcloudKit/NKCommon.swift index 3a062209..28323a1a 100644 --- a/Sources/NextcloudKit/NKCommon.swift +++ b/Sources/NextcloudKit/NKCommon.swift @@ -58,6 +58,8 @@ public struct NKCommon: Sendable { public let identifierSessionUpload: String = "com.nextcloud.nextcloudkit.session.upload" // Background public let identifierSessionDownloadBackground: String = "com.nextcloud.session.downloadbackground" + public let identifierSessionDownloadBackgroundExt: String = "com.nextcloud.session.downloadextension" + public let identifierSessionUploadBackground: String = "com.nextcloud.session.uploadbackground" public let identifierSessionUploadBackgroundWWan: String = "com.nextcloud.session.uploadbackgroundWWan" public let identifierSessionUploadBackgroundExt: String = "com.nextcloud.session.uploadextension" diff --git a/Sources/NextcloudKit/NKSession.swift b/Sources/NextcloudKit/NKSession.swift index 02d681ee..33ea57c9 100644 --- a/Sources/NextcloudKit/NKSession.swift +++ b/Sources/NextcloudKit/NKSession.swift @@ -20,6 +20,7 @@ public struct NKSession: Sendable { public let sessionData: Alamofire.Session public let sessionDataNoCache: Alamofire.Session public let sessionDownloadBackground: URLSession + public let sessionDownloadBackgroundExt: URLSession public let sessionUploadBackground: URLSession public let sessionUploadBackgroundWWan: URLSession public let sessionUploadBackgroundExt: URLSession @@ -47,10 +48,10 @@ public struct NKSession: Sendable { self.httpMaximumConnectionsPerHostInUpload = httpMaximumConnectionsPerHostInUpload let backgroundSessionDelegate = NKBackground(nkCommonInstance: nkCommonInstance) - /// Strange but works ?!?! + // Strange but works ?!?! let sharedCookieStorage = user + "@" + urlBase - /// SessionData Alamofire + // SessionData Alamofire let configurationSessionData = URLSessionConfiguration.af.default configurationSessionData.requestCachePolicy = .useProtocolCachePolicy configurationSessionData.httpMaximumConnectionsPerHost = httpMaximumConnectionsPerHost @@ -67,7 +68,7 @@ public struct NKSession: Sendable { serializationQueue: nkCommonInstance.serializationQueue, eventMonitors: [NKMonitor(nkCommonInstance: nkCommonInstance)]) - /// SessionDataNoCache Alamofire + // SessionDataNoCache Alamofire let configurationSessionDataNoCache = URLSessionConfiguration.af.default configurationSessionDataNoCache.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData configurationSessionDataNoCache.httpMaximumConnectionsPerHost = httpMaximumConnectionsPerHost @@ -80,7 +81,7 @@ public struct NKSession: Sendable { serializationQueue: nkCommonInstance.serializationQueue, eventMonitors: [NKMonitor(nkCommonInstance: nkCommonInstance)]) - /// Session Download Background + // Session Download Background let configurationDownloadBackground = URLSessionConfiguration.background(withIdentifier: NKCommon().getSessionConfigurationIdentifier(NKCommon().identifierSessionDownloadBackground, account: account)) configurationDownloadBackground.allowsCellularAccess = true @@ -99,7 +100,27 @@ public struct NKSession: Sendable { configurationDownloadBackground.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: sharedCookieStorage) sessionDownloadBackground = URLSession(configuration: configurationDownloadBackground, delegate: backgroundSessionDelegate, delegateQueue: OperationQueue.main) - /// Session Upload Background + // Session Download Background Extension + let configurationDownloadBackgroundExt = URLSessionConfiguration.background(withIdentifier: NKCommon().identifierSessionDownloadBackgroundExt + UUID().uuidString) + configurationDownloadBackgroundExt.allowsCellularAccess = true + + if #available(macOS 11, *) { + configurationDownloadBackgroundExt.sessionSendsLaunchEvents = true + } + + configurationDownloadBackgroundExt.isDiscretionary = false + configurationDownloadBackgroundExt.httpMaximumConnectionsPerHost = self.httpMaximumConnectionsPerHostInDownload + configurationDownloadBackgroundExt.requestCachePolicy = .useProtocolCachePolicy + configurationDownloadBackgroundExt.sharedContainerIdentifier = groupIdentifier + + #if os(iOS) || targetEnvironment(macCatalyst) + configurationDownloadBackgroundExt.multipathServiceType = .handover + #endif + + configurationDownloadBackgroundExt.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: sharedCookieStorage) + sessionDownloadBackgroundExt = URLSession(configuration: configurationDownloadBackgroundExt, delegate: backgroundSessionDelegate, delegateQueue: OperationQueue.main) + + // Session Upload Background let configurationUploadBackground = URLSessionConfiguration.background(withIdentifier: NKCommon().getSessionConfigurationIdentifier(NKCommon().identifierSessionUploadBackground, account: account)) configurationUploadBackground.allowsCellularAccess = true @@ -118,7 +139,7 @@ public struct NKSession: Sendable { configurationUploadBackground.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: sharedCookieStorage) sessionUploadBackground = URLSession(configuration: configurationUploadBackground, delegate: backgroundSessionDelegate, delegateQueue: OperationQueue.main) - /// Session Upload Background WWan + // Session Upload Background WWan let configurationUploadBackgroundWWan = URLSessionConfiguration.background(withIdentifier: NKCommon().getSessionConfigurationIdentifier(NKCommon().identifierSessionUploadBackgroundWWan, account: account)) configurationUploadBackgroundWWan.allowsCellularAccess = false @@ -132,7 +153,7 @@ public struct NKSession: Sendable { configurationUploadBackgroundWWan.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: sharedCookieStorage) sessionUploadBackgroundWWan = URLSession(configuration: configurationUploadBackgroundWWan, delegate: backgroundSessionDelegate, delegateQueue: OperationQueue.main) - /// Session Upload Background Extension + // Session Upload Background Extension let configurationUploadBackgroundExt = URLSessionConfiguration.background(withIdentifier: NKCommon().identifierSessionUploadBackgroundExt + UUID().uuidString) configurationUploadBackgroundExt.allowsCellularAccess = true diff --git a/Sources/NextcloudKit/NextcloudKitBackground.swift b/Sources/NextcloudKit/NextcloudKitBackground.swift index 2fc70de9..90672bfd 100644 --- a/Sources/NextcloudKit/NextcloudKitBackground.swift +++ b/Sources/NextcloudKit/NextcloudKitBackground.swift @@ -28,9 +28,11 @@ public final class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDel public func download(serverUrlFileName: Any, fileNameLocalPath: String, taskDescription: String? = nil, + account: String, automaticResume: Bool = true, - account: String) -> (URLSessionDownloadTask?, error: NKError) { + sessionIdentifier: String) -> (URLSessionDownloadTask?, error: NKError) { var url: URL? + var downloadSession: URLSession? let groupDefaults = UserDefaults(suiteName: NextcloudKit.shared.nkCommonInstance.groupIdentifier) /// Check if error is in groupDefaults @@ -68,11 +70,17 @@ public final class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDel request.setValue(nkSession.userAgent, forHTTPHeaderField: "User-Agent") request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization") - let task = nkSession.sessionDownloadBackground.downloadTask(with: request) - task.taskDescription = taskDescription + if sessionIdentifier == nkCommonInstance.identifierSessionDownloadBackground { + downloadSession = nkSession.sessionDownloadBackground + } else if sessionIdentifier == nkCommonInstance.identifierSessionDownloadBackgroundExt { + downloadSession = nkSession.sessionDownloadBackgroundExt + } + + let task = downloadSession?.downloadTask(with: request) + task?.taskDescription = taskDescription if automaticResume { - task.resume() + task?.resume() } return (task, .success) @@ -88,8 +96,9 @@ public final class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDel public func downloadAsync(serverUrlFileName: Any, fileNameLocalPath: String, taskDescription: String? = nil, + account: String, automaticResume: Bool = true, - account: String) async -> ( + sessionIdentifier: String) async -> ( downloadTask: URLSessionDownloadTask?, error: NKError ) { @@ -97,8 +106,9 @@ public final class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDel let (task, error) = download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, taskDescription: taskDescription, + account: account, automaticResume: automaticResume, - account: account) + sessionIdentifier: sessionIdentifier) continuation.resume(returning: (downloadTask: task, error: error)) } }