From dced9a859145d0c42fb73f7f238ebd28eda38d0f Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 11:02:01 +0200 Subject: [PATCH 01/10] cod Signed-off-by: Marino Faggiana --- Sources/NextcloudKit/NextcloudKit+API.swift | 417 ++++++++++++++++-- .../NextcloudKit/NextcloudKit+Assistant.swift | 111 +++++ .../NextcloudKit+AssistantV2.swift | 87 ++++ .../NextcloudKit/NextcloudKit+Comments.swift | 136 ++++++ .../NextcloudKit/NextcloudKit+Dashboard.swift | 85 ++-- .../NextcloudKit/NextcloudKit+Download.swift | 42 ++ Sources/NextcloudKit/NextcloudKit+E2EE.swift | 357 +++++++++++++-- .../NextcloudKit/NextcloudKit+FilesLock.swift | 35 ++ .../NextcloudKit+Groupfolders.swift | 27 ++ 9 files changed, 1196 insertions(+), 101 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+API.swift b/Sources/NextcloudKit/NextcloudKit+API.swift index ceaec9e2..ed90b941 100644 --- a/Sources/NextcloudKit/NextcloudKit+API.swift +++ b/Sources/NextcloudKit/NextcloudKit+API.swift @@ -50,6 +50,22 @@ public extension NextcloudKit { } } + /// Asynchronously checks the server status using the provided URL and request options. + /// - Parameters: + /// - serverUrl: The URL of the server to check. + /// - options: Optional request options (default: `NKRequestOptions()`). + /// - taskHandler: Optional closure to receive the `URLSessionTask` (default: no-op). + /// - Returns: A tuple containing the optional `AFDataResponse` and an `NKError`. + func checkServerAsync(serverUrl: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + checkServer(serverUrl: serverUrl, options: options, taskHandler: taskHandler) { responseData, error in + continuation.resume(returning: (responseData, error)) + } + } + } + // MARK: - func generalWithEndpoint(_ endpoint: String, @@ -76,6 +92,30 @@ public extension NextcloudKit { } } + /// Asynchronously executes a general network request with the specified endpoint and method. + /// - Parameters: + /// - endpoint: The endpoint to call (e.g., "/ocs/v2.php/apps/..."). + /// - account: The identifier for the user/account associated with the request. + /// - method: The HTTP method (e.g., "GET", "POST"). + /// - options: Optional request options (default: `NKRequestOptions()`). + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple containing the account, the optional response, and the `NKError`. + func generalWithEndpointAsync(_ endpoint: String, + account: String, + method: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + generalWithEndpoint(endpoint, + account: account, + method: method, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } + // MARK: - func getExternalSite(account: String, @@ -116,10 +156,16 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves external sites for the given account. + /// - Parameters: + /// - account: The identifier for the account. + /// - options: Optional request options (default: `NKRequestOptions()`). + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple with account identifier, external sites list, response data, and NKError. func getExternalSiteAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (account: String, externalSite: [NKExternalSite], responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation { continuation in + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKExternalSite], AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in getExternalSite(account: account, options: options, taskHandler: taskHandler) { account, externalSite, responseData, error in @@ -199,10 +245,16 @@ public extension NextcloudKit { } } + /// Asynchronously checks the server status and parses the result. + /// - Parameters: + /// - serverUrl: The full URL of the server to check. + /// - options: Optional request options. + /// - taskHandler: Optional closure to get access to the underlying URLSessionTask. + /// - Returns: A tuple containing the response and the parsed `ServerInfoResult`. func getServerStatusAsync(serverUrl: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (responseData: AFDataResponse?, result: ServerInfoResult) { - await withUnsafeContinuation { continuation in + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (AFDataResponse?, ServerInfoResult) { + await withCheckedContinuation { continuation in getServerStatus(serverUrl: serverUrl, options: options, taskHandler: taskHandler) { responseData, result in @@ -242,14 +294,28 @@ public extension NextcloudKit { } } + /// Asynchronously downloads a preview for a given file URL. + /// - Parameters: + /// - url: The full URL of the file preview to download. + /// - account: The account identifier. + /// - etag: Optional ETag for cache validation. + /// - options: Optional request options. + /// - taskHandler: Optional closure to handle the URLSessionTask. + /// - Returns: A tuple with the account, optional response, and NKError. func downloadPreviewAsync(url: URL, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.downloadPreview(url: url, account: account, options: options) { account, responseData, error in - continuation.resume(returning: (account: account, responseData: responseData, error: error)) + etag: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + downloadPreview(url: url, + account: account, + etag: etag, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) } - }) + } } func downloadPreview(fileId: String, @@ -291,15 +357,46 @@ public extension NextcloudKit { } } + /// Asynchronously downloads a preview by file ID with specified dimensions and parameters. + /// - Parameters: + /// - fileId: The unique identifier of the file. + /// - width: Desired preview width (default: 1024). + /// - height: Desired preview height (default: 1024). + /// - etag: Optional ETag for cache validation. + /// - crop: Crop flag (default: 1). + /// - cropMode: Crop mode (default: "cover"). + /// - forceIcon: Force icon flag (default: 0). + /// - mimeFallback: MIME fallback flag (default: 0). + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to handle the URLSessionTask. + /// - Returns: A tuple containing account, dimensions, ETag, response and error. func downloadPreviewAsync(fileId: String, + width: Int = 1024, + height: Int = 1024, etag: String? = nil, + crop: Int = 1, + cropMode: String = "cover", + forceIcon: Int = 0, + mimeFallback: Int = 0, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, width: Int, height: Int, etag: String?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.downloadPreview(fileId: fileId, etag: etag, account: account, options: options) { account, width, height, etag, responseData, error in - continuation.resume(returning: (account: account, width: width, height: height, etag: etag, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, Int, Int, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + downloadPreview(fileId: fileId, + width: width, + height: height, + etag: etag, + crop: crop, + cropMode: cropMode, + forceIcon: forceIcon, + mimeFallback: mimeFallback, + account: account, + options: options, + taskHandler: taskHandler) { account, w, h, tag, responseData, error in + continuation.resume(returning: (account, w, h, tag, responseData, error)) } - }) + } } func downloadTrashPreview(fileId: String, @@ -335,6 +432,45 @@ public extension NextcloudKit { } } + /// Asynchronously downloads a preview for a trashed file by ID with specified dimensions and flags. + /// - Parameters: + /// - fileId: The unique identifier of the trashed file. + /// - width: Desired width of the preview (default: 512). + /// - height: Desired height of the preview (default: 512). + /// - crop: Crop flag (default: 1). + /// - cropMode: Crop mode string (default: "cover"). + /// - forceIcon: Force icon flag (default: 0). + /// - mimeFallback: MIME fallback flag (default: 0). + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to get the URLSessionTask. + /// - Returns: A tuple with account, preview dimensions, response, and error. + func downloadTrashPreviewAsync(fileId: String, + width: Int = 512, + height: Int = 512, + crop: Int = 1, + cropMode: String = "cover", + forceIcon: Int = 0, + mimeFallback: Int = 0, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, Int, Int, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + downloadTrashPreview(fileId: fileId, + width: width, + height: height, + crop: crop, + cropMode: cropMode, + forceIcon: forceIcon, + mimeFallback: mimeFallback, + account: account, + options: options, + taskHandler: taskHandler) { account, w, h, responseData, error in + continuation.resume(returning: (account, w, h, responseData, error)) + } + } + } + func downloadAvatar(user: String, fileNameLocalPath: String, sizeImage: Int, @@ -436,6 +572,17 @@ public extension NextcloudKit { } } + /// Asynchronously downloads an avatar image for the specified user. + /// - Parameters: + /// - user: Username whose avatar is being requested. + /// - fileNameLocalPath: Local file path to cache or save the avatar. + /// - sizeImage: Size of the avatar image. + /// - avatarSizeRounded: Optional rounding size for avatar (default: 0). + /// - etag: Optional ETag for caching. + /// - account: Account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, processed avatar image, original image, ETag, response, and error. func downloadAvatarAsync(user: String, fileNameLocalPath: String, sizeImage: Int, @@ -443,8 +590,8 @@ public extension NextcloudKit { etag: String?, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (account: String, imageAvatar: UIImage?, imageOriginal: UIImage?, etag: String?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation { continuation in + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, UIImage?, UIImage?, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in downloadAvatar(user: user, fileNameLocalPath: fileNameLocalPath, sizeImage: sizeImage, @@ -483,6 +630,27 @@ public extension NextcloudKit { } } + /// Asynchronously downloads raw content from the specified server URL. + /// - Parameters: + /// - serverUrl: The full URL to download content from. + /// - account: The account identifier associated with the request. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple with account identifier, response, and NKError. + func downloadContentAsync(serverUrl: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + downloadContent(serverUrl: serverUrl, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } + // MARK: - func getUserMetadata(account: String, @@ -520,14 +688,25 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves user metadata for the specified account and user ID. + /// - Parameters: + /// - account: The account identifier. + /// - userId: The target user ID for metadata lookup. + /// - options: Optional request options. + /// - taskHandler: Optional closure to handle the `URLSessionTask`. + /// - Returns: A tuple with account, user profile metadata, response data, and error. func getUserMetadataAsync(account: String, userId: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, userProfile: NKUserProfile?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.getUserMetadata(account: account, userId: userId) { account, userProfile, responseData, error in - continuation.resume(returning: (account: account, userProfile: userProfile, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKUserProfile?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getUserMetadata(account: account, + userId: userId, + options: options, + taskHandler: taskHandler) { account, userProfile, responseData, error in + continuation.resume(returning: (account, userProfile, responseData, error)) } - }) + } } func getUserProfile(account: String, @@ -564,6 +743,24 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves the current user's profile for the given account. + /// - Parameters: + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple with account, user profile, response data, and error. + func getUserProfileAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKUserProfile?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getUserProfile(account: account, + options: options, + taskHandler: taskHandler) { account, userProfile, responseData, error in + continuation.resume(returning: (account, userProfile, responseData, error)) + } + } + } + private func getUserProfile(json: JSON) -> NKUserProfile? { let ocs = json["ocs"] let data = ocs["data"] @@ -645,6 +842,30 @@ public extension NextcloudKit { } } + /// Asynchronously checks if a remote wipe has been requested for the given account and token. + /// - Parameters: + /// - serverUrl: Full URL of the server. + /// - token: Unique token associated with the device/session. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, wipe flag, response data, and NKError. + func getRemoteWipeStatusAsync(serverUrl: String, + token: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, Bool, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getRemoteWipeStatus(serverUrl: serverUrl, + token: token, + account: account, + options: options, + taskHandler: taskHandler) { account, wipe, responseData, error in + continuation.resume(returning: (account, wipe, responseData, error)) + } + } + } + func setRemoteWipeCompletition(serverUrl: String, token: String, account: String, @@ -678,6 +899,30 @@ public extension NextcloudKit { } } + /// Asynchronously notifies the server that the remote wipe process has been completed for the given token. + /// - Parameters: + /// - serverUrl: Full URL of the server. + /// - token: Unique token associated with the device/session. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, response data, and NKError. + func setRemoteWipeCompletitionAsync(serverUrl: String, + token: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + setRemoteWipeCompletition(serverUrl: serverUrl, + token: token, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } + // MARK: - func getActivity(since: Int, @@ -776,6 +1021,39 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves user activity from the server. + /// - Parameters: + /// - since: Timestamp (UNIX) after which to retrieve activities. + /// - limit: Maximum number of activities to retrieve. + /// - objectId: Optional filter for object ID. + /// - objectType: Optional filter for object type. + /// - previews: Whether to include previews in the response. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple with account, activity list, first known timestamp, last given timestamp, response data, and error. + func getActivityAsync(since: Int, + limit: Int, + objectId: String?, + objectType: String?, + previews: Bool, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKActivity], Int, Int, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getActivity(since: since, + limit: limit, + objectId: objectId, + objectType: objectType, + previews: previews, + account: account, + options: options, + taskHandler: taskHandler) { account, activities, firstKnown, lastGiven, responseData, error in + continuation.resume(returning: (account, activities, firstKnown, lastGiven, responseData, error)) + } + } + } + // MARK: - func getNotifications(account: String, @@ -845,6 +1123,24 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves notifications for the specified account. + /// - Parameters: + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, notifications array, response data, and error. + func getNotificationsAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKNotifications]?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getNotifications(account: account, + options: options, + taskHandler: taskHandler) { account, notifications, responseData, error in + continuation.resume(returning: (account, notifications, responseData, error)) + } + } + } + func setNotification(serverUrl: String?, idNotification: Int, method: String, @@ -882,6 +1178,33 @@ public extension NextcloudKit { } } + /// Asynchronously performs an action on a notification (e.g. mark as read, delete). + /// - Parameters: + /// - serverUrl: Optional server URL (can be `nil` to use default). + /// - idNotification: The ID of the notification to act upon. + /// - method: HTTP method to use (e.g. "DELETE", "POST"). + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple with account, response data, and NKError. + func setNotificationAsync(serverUrl: String?, + idNotification: Int, + method: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + setNotification(serverUrl: serverUrl, + idNotification: idNotification, + method: method, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } + // MARK: - func getDirectDownload(fileId: String, @@ -917,6 +1240,27 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves the direct download URL for a given file ID. + /// - Parameters: + /// - fileId: The unique identifier of the file. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, direct download URL, response, and error. + func getDirectDownloadAsync(fileId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getDirectDownload(fileId: fileId, + account: account, + options: options, + taskHandler: taskHandler) { account, url, responseData, error in + continuation.resume(returning: (account, url, responseData, error)) + } + } + } + // MARK: - func sendClientDiagnosticsRemoteOperation(data: Data, @@ -955,20 +1299,23 @@ public extension NextcloudKit { } } - func sendClientDiagnosticsRemoteOperationAsync( - data: Data, - account: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } - ) async -> (responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation { continuation in - sendClientDiagnosticsRemoteOperation( - data: data, - account: account, - options: options, - taskHandler: taskHandler - ) { _, responseData, error in - continuation.resume(returning: (responseData, error)) + /// Asynchronously sends client diagnostics data to the server. + /// - Parameters: + /// - data: Diagnostic payload to be sent. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, response data, and NKError. + func sendClientDiagnosticsRemoteOperationAsync(data: Data, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + sendClientDiagnosticsRemoteOperation(data: data, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) } } } diff --git a/Sources/NextcloudKit/NextcloudKit+Assistant.swift b/Sources/NextcloudKit/NextcloudKit+Assistant.swift index e9eb9268..3a4d1d9e 100644 --- a/Sources/NextcloudKit/NextcloudKit+Assistant.swift +++ b/Sources/NextcloudKit/NextcloudKit+Assistant.swift @@ -40,6 +40,24 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves available text processing task types for the given account. + /// - Parameters: + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple with account, list of task types, response data, and error. + func textProcessingGetTypesAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKTextProcessingTaskType]?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingGetTypes(account: account, + options: options, + taskHandler: taskHandler) { account, types, responseData, error in + continuation.resume(returning: (account, types, responseData, error)) + } + } + } + func textProcessingSchedule(input: String, typeId: String, appId: String = "assistant", @@ -78,6 +96,36 @@ public extension NextcloudKit { } } + /// Asynchronously schedules a text processing task. + /// - Parameters: + /// - input: The input string to be processed. + /// - typeId: The identifier of the processing type. + /// - appId: The app identifier (default: "assistant"). + /// - identifier: The task identifier. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, the scheduled task, response data, and error. + func textProcessingScheduleAsync(input: String, + typeId: String, + appId: String = "assistant", + identifier: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKTextProcessingTask?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingSchedule(input: input, + typeId: typeId, + appId: appId, + identifier: identifier, + account: account, + options: options, + taskHandler: taskHandler) { account, task, responseData, error in + continuation.resume(returning: (account, task, responseData, error)) + } + } + } + func textProcessingGetTask(taskId: Int, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -112,6 +160,27 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves a specific text processing task by ID. + /// - Parameters: + /// - taskId: The unique identifier of the text processing task. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, the task (if found), response data, and error. + func textProcessingGetTaskAsync(taskId: Int, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKTextProcessingTask?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingGetTask(taskId: taskId, + account: account, + options: options, + taskHandler: taskHandler) { account, task, responseData, error in + continuation.resume(returning: (account, task, responseData, error)) + } + } + } + func textProcessingDeleteTask(taskId: Int, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -146,6 +215,27 @@ public extension NextcloudKit { } } + /// Asynchronously deletes a text processing task by its ID. + /// - Parameters: + /// - taskId: The ID of the task to delete. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, the deleted task (if returned), response data, and error. + func textProcessingDeleteTaskAsync(taskId: Int, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKTextProcessingTask?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingDeleteTask(taskId: taskId, + account: account, + options: options, + taskHandler: taskHandler) { account, task, responseData, error in + continuation.resume(returning: (account, task, responseData, error)) + } + } + } + func textProcessingTaskList(appId: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -179,6 +269,27 @@ public extension NextcloudKit { } } } + + /// Asynchronously retrieves the list of text processing tasks for the given app and account. + /// - Parameters: + /// - appId: The application identifier (e.g., "assistant"). + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, task list (if any), response data, and error. + func textProcessingTaskListAsync(appId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKTextProcessingTask]?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingTaskList(appId: appId, + account: account, + options: options, + taskHandler: taskHandler) { account, taskList, responseData, error in + continuation.resume(returning: (account, taskList, responseData, error)) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift b/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift index e3460146..e4fade2a 100644 --- a/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift +++ b/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift @@ -45,6 +45,27 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves available task types (v2) for the given account and supported task type. + /// - Parameters: + /// - account: The account identifier. + /// - supportedTaskType: The supported type (e.g. "Text", default: "Text"). + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, list of task types (if any), response data, and error. + func textProcessingGetTypesV2Async(account: String, + supportedTaskType: String = "Text", + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [TaskTypeData]?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingGetTypesV2(account: account, + supportedTaskType: supportedTaskType, + options: options, + taskHandler: taskHandler) { account, types, responseData, error in + continuation.resume(returning: (account, types, responseData, error)) + } + } + } + func textProcessingScheduleV2(input: String, taskType: TaskTypeData, account: String, @@ -83,6 +104,30 @@ public extension NextcloudKit { } } + /// Asynchronously schedules a text processing task using V2 API. + /// - Parameters: + /// - input: The input text to process. + /// - taskType: The task type data (e.g., summarization, translation). + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, scheduled task (if any), response data, and error. + func textProcessingScheduleV2Async(input: String, + taskType: TaskTypeData, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AssistantTask?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingScheduleV2(input: input, + taskType: taskType, + account: account, + options: options, + taskHandler: taskHandler) { account, task, responseData, error in + continuation.resume(returning: (account, task, responseData, error)) + } + } + } + func textProcessingGetTasksV2(taskType: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -117,6 +162,27 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves the list of tasks for a given task type using V2 API. + /// - Parameters: + /// - taskType: The type of tasks to retrieve (e.g., "summary"). + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, list of tasks (if any), response data, and error. + func textProcessingGetTasksV2Async(taskType: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, TaskList?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingGetTasksV2(taskType: taskType, + account: account, + options: options, + taskHandler: taskHandler) { account, tasks, responseData, error in + continuation.resume(returning: (account, tasks, responseData, error)) + } + } + } + func textProcessingDeleteTaskV2(taskId: Int64, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -148,6 +214,27 @@ public extension NextcloudKit { } } } + + /// Asynchronously deletes a text processing task (V2) by its ID. + /// - Parameters: + /// - taskId: The ID of the task to delete (Int64). + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, response data, and error. + func textProcessingDeleteTaskV2Async(taskId: Int64, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + textProcessingDeleteTaskV2(taskId: taskId, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+Comments.swift b/Sources/NextcloudKit/NextcloudKit+Comments.swift index da6e4ead..2fcd5aa0 100644 --- a/Sources/NextcloudKit/NextcloudKit+Comments.swift +++ b/Sources/NextcloudKit/NextcloudKit+Comments.swift @@ -51,6 +51,27 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves comments for a given file ID. + /// - Parameters: + /// - fileId: The file identifier to fetch comments for. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, list of comments (if any), response data, and error. + func getCommentsAsync(fileId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKComments]?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getComments(fileId: fileId, + account: account, + options: options, + taskHandler: taskHandler) { account, items, responseData, error in + continuation.resume(returning: (account, items, responseData, error)) + } + } + } + func putComments(fileId: String, message: String, account: String, @@ -90,6 +111,30 @@ public extension NextcloudKit { } } + /// Asynchronously adds a comment to a file. + /// - Parameters: + /// - fileId: The file identifier to comment on. + /// - message: The comment message. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, response data, and error. + func putCommentsAsync(fileId: String, + message: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + putComments(fileId: fileId, + message: message, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } + func updateComments(fileId: String, messageId: String, message: String, @@ -131,6 +176,43 @@ public extension NextcloudKit { } } + /// Asynchronously updates an existing comment on a file. + /// - Parameters: + /// - fileId: The file identifier. + /// - messageId: The ID of the comment to update. + /// - message: The updated comment message. + /// - account: The account identifier. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with account, response data, and error. + func updateCommentsAsync(fileId: String, + messageId: String, + message: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + updateComments(fileId: fileId, + messageId: messageId, + message: message, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } + + // Deletes a specific comment from a file on the server for a given Nextcloud account. + // It performs an HTTP request (typically DELETE) and returns the result through a completion handler. + // + // Parameters: + // - fileId: The identifier of the file the comment belongs to. + // - messageId: The identifier of the comment to be deleted. + // - account: The Nextcloud account performing the operation. + // - options: Optional request options such as custom headers or retry policy (default is empty). + // - taskHandler: A closure to access the underlying URLSessionTask, useful for progress or cancellation. + // - completion: Completion handler returning the account, the raw response (if any), and an NKError. func deleteComments(fileId: String, messageId: String, account: String, @@ -158,6 +240,39 @@ public extension NextcloudKit { } } + /// Asynchronously deletes a specific comment from a file for the given account. + /// - Parameters: + /// - fileId: The identifier of the file containing the comment. + /// - messageId: The ID of the comment to delete. + /// - account: The account performing the request. + /// - options: Optional request options (default is empty). + /// - taskHandler: Closure to access the URLSessionTask (default is empty). + /// - Returns: A tuple containing the account identifier, optional response, and NKError. + func deleteCommentsAsync(fileId: String, + messageId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + deleteComments(fileId: fileId, + messageId: messageId, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } + + // Marks all comments on a given file as read for the specified Nextcloud account. + // It performs an HTTP request (likely POST or PUT) to update the read status on the server. + // + // Parameters: + // - fileId: The identifier of the file whose comments should be marked as read. + // - account: The Nextcloud account performing the operation. + // - options: Optional request options (default is empty). + // - taskHandler: A closure to access the underlying URLSessionTask (default is no-op). + // - completion: Completion handler returning the account, the raw response, and any NKError. func markAsReadComments(fileId: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -196,4 +311,25 @@ public extension NextcloudKit { } } } + + /// Asynchronously marks all comments on a file as read for the given account. + /// - Parameters: + /// - fileId: The identifier of the file. + /// - account: The account performing the request. + /// - options: Optional request options (default is empty). + /// - taskHandler: Optional closure to access the URLSessionTask (default is no-op). + /// - Returns: A tuple with the account, optional response, and NKError. + func markAsReadCommentsAsync(fileId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + markAsReadComments(fileId: fileId, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+Dashboard.swift b/Sources/NextcloudKit/NextcloudKit+Dashboard.swift index d21249e2..712dbc0c 100644 --- a/Sources/NextcloudKit/NextcloudKit+Dashboard.swift +++ b/Sources/NextcloudKit/NextcloudKit+Dashboard.swift @@ -7,6 +7,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Retrieves the list of dashboard widgets available for the specified Nextcloud account. + // This typically calls the dashboard API endpoint and returns a list of `NCCDashboardWidget` items. + // + // Parameters: + // - account: The Nextcloud account performing the request. + // - options: Optional request options such as custom headers or retry policy (default is empty). + // - request: A closure that receives the underlying Alamofire `DataRequest`, useful for inspection or mutation. + // - taskHandler: A closure to access the `URLSessionTask` for progress or cancellation control. + // - completion: Completion handler returning the account, list of widgets, the raw response, and any NKError. func getDashboardWidget(account: String, options: NKRequestOptions = NKRequestOptions(), request: @escaping (DataRequest?) -> Void = { _ in }, @@ -42,29 +51,37 @@ public extension NextcloudKit { options.queue.async { request(dashboardRequest) } } + /// Asynchronously retrieves the dashboard widgets for the given account. + /// - Parameters: + /// - account: The account requesting the widgets. + /// - options: Optional request options (default is empty). + /// - request: Optional closure that receives the internal Alamofire `DataRequest`. + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple with the account, optional widget list, raw response, and NKError. func getDashboardWidgetAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (account: String, - dashboardWidgets: [NCCDashboardWidget]?, - responseData: AFDataResponse?, - request: DataRequest?, - task: URLSessionTask?, - error: NKError) { + request: @escaping (DataRequest?) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NCCDashboardWidget]?, AFDataResponse?, NKError) { await withCheckedContinuation { continuation in - var capturedRequest: DataRequest? - var capturedTask: URLSessionTask? - - getDashboardWidget(account: account, options: options, request: { req in - capturedRequest = req - }, taskHandler: { task in - capturedTask = task - taskHandler(task) // lo inoltriamo comunque al chiamante - }, completion: { account, widgets, response, error in - continuation.resume(returning: (account, widgets, response, capturedRequest, capturedTask, error)) - }) + getDashboardWidget(account: account, + options: options, + request: request, + taskHandler: taskHandler) { account, dashboardWidgets, responseData, error in + continuation.resume(returning: (account, dashboardWidgets, responseData, error)) + } } } + // Retrieves the list of dashboard application widgets for the specified account and item string. + // This is typically used to fetch available dashboard apps filtered by `items` (e.g., "weather,tasks"). + // + // Parameters: + // - items: A comma-separated string representing widget types or categories to fetch. + // - account: The Nextcloud account performing the request. + // - options: Optional request options (default is empty). + // - request: A closure that receives the underlying Alamofire `DataRequest`, useful for inspection or mutation. + // - taskHandler: A closure to access the `URLSessionTask` for progress or cancellation. + // - completion: Completion handler returning the account, list of applications, response, and error. func getDashboardWidgetsApplication(_ items: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -101,27 +118,27 @@ public extension NextcloudKit { options.queue.async { request(dashboardRequest) } } + /// Asynchronously retrieves dashboard application widgets for the given account and item list. + /// - Parameters: + /// - items: A comma-separated list of widget types to retrieve. + /// - account: The account performing the request. + /// - options: Optional request options (default is empty). + /// - request: Optional closure to inspect the internal `DataRequest`. + /// - taskHandler: Optional closure to access the `URLSessionTask`. + /// - Returns: A tuple with account, list of dashboard applications, raw response, and error. func getDashboardWidgetsApplicationAsync(_ items: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (account: String, - dashboardApplications: [NCCDashboardApplication]?, - responseData: AFDataResponse?, - request: DataRequest?, - task: URLSessionTask?, - error: NKError) { + request: @escaping (DataRequest?) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NCCDashboardApplication]?, AFDataResponse?, NKError) { await withCheckedContinuation { continuation in - var capturedRequest: DataRequest? - var capturedTask: URLSessionTask? - - getDashboardWidgetsApplication(items, account: account, options: options, request: { req in - capturedRequest = req - }, taskHandler: { task in - capturedTask = task - taskHandler(task) // propaghiamo al chiamante - }, completion: { account, apps, response, error in - continuation.resume(returning: (account, apps, response, capturedRequest, capturedTask, error )) - }) + getDashboardWidgetsApplication(items, + account: account, + options: options, + request: request, + taskHandler: taskHandler) { account, dashboardApplications, responseData, error in + continuation.resume(returning: (account, dashboardApplications, responseData, error)) + } } } } diff --git a/Sources/NextcloudKit/NextcloudKit+Download.swift b/Sources/NextcloudKit/NextcloudKit+Download.swift index c6159139..d45b4d81 100644 --- a/Sources/NextcloudKit/NextcloudKit+Download.swift +++ b/Sources/NextcloudKit/NextcloudKit+Download.swift @@ -7,6 +7,18 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Downloads a remote file and stores it at a local path for the specified Nextcloud account. + // It provides detailed progress, headers, and metadata such as ETag, last modified date, and content length. + // + // Parameters: + // - serverUrlFileName: A value representing the remote file URL or path (typically String or URL). + // - fileNameLocalPath: The local filesystem path where the file should be saved. + // - account: The Nextcloud account performing the download. + // - options: Optional request options (default is empty). + // - requestHandler: Closure to access the Alamofire `DownloadRequest` (for customization, inspection, etc.). + // - taskHandler: Closure to access the underlying `URLSessionTask` (e.g. for progress or cancellation). + // - progressHandler: Closure that receives periodic progress updates. + // - completionHandler: Completion closure returning metadata: account, ETag, modification date, content length, headers, AFError, and NKError. func download(serverUrlFileName: Any, fileNameLocalPath: String, account: String, @@ -69,4 +81,34 @@ public extension NextcloudKit { options.queue.async { requestHandler(request) } } + + /// Asynchronously downloads a file and returns detailed download metadata. + /// - Parameters: + /// - serverUrlFileName: The remote file path or URL (typically String or URL). + /// - fileNameLocalPath: The local file path where the file will be saved. + /// - account: The account performing the download. + /// - options: Optional request options (default is empty). + /// - requestHandler: Closure to access the `DownloadRequest`. + /// - taskHandler: Closure to access the `URLSessionTask`. + /// - progressHandler: Closure to monitor download progress. + /// - Returns: A tuple with account, ETag, modified date, file size, headers, AFError (if any), and NKError. + func downloadAsync(serverUrlFileName: Any, + fileNameLocalPath: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + requestHandler: @escaping (_ request: DownloadRequest) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + progressHandler: @escaping (_ progress: Progress) -> Void = { _ in }) async -> (String, String?, Date?, Int64, [AnyHashable: Any]?, AFError?, NKError) { + await withCheckedContinuation { continuation in + download(serverUrlFileName: serverUrlFileName, + fileNameLocalPath: fileNameLocalPath, + account: account, + options: options, + requestHandler: requestHandler, + taskHandler: taskHandler, + progressHandler: progressHandler) { account, etag, date, length, headers, afError, nKError in + continuation.resume(returning: (account, etag, date, length, headers, afError, nKError)) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+E2EE.swift b/Sources/NextcloudKit/NextcloudKit+E2EE.swift index ec2eb9af..c669f293 100644 --- a/Sources/NextcloudKit/NextcloudKit+E2EE.swift +++ b/Sources/NextcloudKit/NextcloudKit+E2EE.swift @@ -7,6 +7,16 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Marks or unmarks a folder as End-to-End Encrypted (E2EE) for a given Nextcloud account. + // Depending on the `delete` flag, this function either enables or disables the E2EE status for the folder. + // + // Parameters: + // - fileId: The identifier of the folder to mark/unmark. + // - delete: If `true`, removes the E2EE mark; if `false`, adds the E2EE mark. + // - account: The Nextcloud account performing the operation. + // - options: Optional request options (default is empty). + // - taskHandler: Closure to access the `URLSessionTask` (default is no-op). + // - completion: Completion handler returning the account, raw response, and any NKError. func markE2EEFolder(fileId: String, delete: Bool, account: String, @@ -45,17 +55,43 @@ public extension NextcloudKit { } } + /// Asynchronously marks or unmarks a folder as E2EE for the specified account. + /// - Parameters: + /// - fileId: The ID of the folder. + /// - delete: Whether to remove (`true`) or set (`false`) the E2EE mark. + /// - account: The account performing the request. + /// - options: Optional request options (default is empty). + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple containing the account, raw response, and NKError. func markE2EEFolderAsync(fileId: String, delete: Bool, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.markE2EEFolder(fileId: fileId, delete: delete, account: account, options: options) { account, responseData, error in - continuation.resume(returning: (account: account, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + markE2EEFolder(fileId: fileId, + delete: delete, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: (account, responseData, error)) } - }) + } } + // Locks or unlocks a folder for End-to-End Encryption (E2EE) using a provided token and counter. + // Depending on the HTTP `method` (e.g. "LOCK", "UNLOCK", "PUT"), the operation will either lock the folder, + // refresh the E2EE token, or perform another action defined by the server API. + // + // Parameters: + // - fileId: The identifier of the folder to lock or unlock. + // - e2eToken: Optional E2EE token used to lock the folder (nil if unlocking). + // - e2eCounter: Optional counter value for token freshness or verification. + // - method: The HTTP method to use for the request (e.g., "LOCK", "PUT", etc.). + // - account: The Nextcloud account performing the request. + // - options: Optional request options (default is empty). + // - taskHandler: Closure to access the `URLSessionTask` (default is no-op). + // - completion: Completion handler returning the account, updated E2EE token, raw response, and any NKError. func lockE2EEFolder(fileId: String, e2eToken: String?, e2eCounter: String?, @@ -106,20 +142,48 @@ public extension NextcloudKit { } } + /// Asynchronously locks or unlocks an E2EE folder for the given account using the specified method and token. + /// - Parameters: + /// - fileId: The ID of the folder to lock/unlock. + /// - e2eToken: Optional E2EE token to lock the folder (nil for unlock). + /// - e2eCounter: Optional counter value (used for token freshness). + /// - method: The HTTP method to use (e.g. "LOCK", "PUT"). + /// - account: The account performing the operation. + /// - options: Optional request options (default is empty). + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - Returns: A tuple with the account, resulting E2EE token (if any), raw response, and NKError. func lockE2EEFolderAsync(fileId: String, e2eToken: String?, e2eCounter: String?, method: String, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, e2eToken: String?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.lockE2EEFolder(fileId: fileId, e2eToken: e2eToken, e2eCounter: e2eCounter, method: method, account: account, options: options) { account, e2eToken, responseData, error in - continuation.resume(returning: (account: account, e2eToken: e2eToken, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + lockE2EEFolder(fileId: fileId, + e2eToken: e2eToken, + e2eCounter: e2eCounter, + method: method, + account: account, + options: options, + taskHandler: taskHandler) { account, e2eToken, responseData, error in + continuation.resume(returning: (account, e2eToken, responseData, error)) } - }) + } } - + // Retrieves E2EE metadata and signature for a specific file from the Nextcloud E2EE API. + // It supports different API versions via the `options.version` property (default is "v1"). + // This request is authenticated and validated, and returns both metadata and signature + // (from header `X-NC-E2EE-SIGNATURE`) if the operation is successful. + // + // Parameters: + // - fileId: The file identifier to retrieve metadata for. + // - e2eToken: Optional E2EE token used for authorization or context. + // - account: The Nextcloud account performing the request. + // - options: Optional request options (includes version, queue, task description, etc.). + // - taskHandler: Closure to access the URLSessionTask for progress or control. + // - completion: Completion handler returning the account, metadata string, signature string, response, and NKError. func getE2EEMetadata(fileId: String, e2eToken: String?, account: String, @@ -163,25 +227,44 @@ public extension NextcloudKit { } } - // Async wrapper for getE2EEMetadata + /// Asynchronously retrieves E2EE metadata and signature for a specific file. + /// - Parameters: + /// - fileId: The ID of the file to retrieve metadata for. + /// - e2eToken: Optional E2EE token. + /// - account: The Nextcloud account requesting metadata. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the task. + /// - Returns: A tuple containing the account, E2EE metadata, signature, raw response, and NKError. func getE2EEMetadataAsync(fileId: String, - e2eToken: String? = nil, + e2eToken: String?, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (account: String, e2eMetadata: String?, signature: String?, responseData: AFDataResponse?, error: NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, String?, AFDataResponse?, NKError) { await withCheckedContinuation { continuation in - getE2EEMetadata( - fileId: fileId, - e2eToken: e2eToken, - account: account, - options: options, - taskHandler: taskHandler - ) { account, e2eMetadata, signature, responseData, error in - continuation.resume(returning: (account: account, e2eMetadata: e2eMetadata, signature: signature, responseData: responseData, error: error)) + getE2EEMetadata(fileId: fileId, + e2eToken: e2eToken, + account: account, + options: options, + taskHandler: taskHandler) { account, metadata, signature, response, error in + continuation.resume(returning: (account, metadata, signature, response, error)) } } } + // Uploads E2EE metadata for a specific file on the Nextcloud server, using the specified HTTP method. + // The request includes the E2E token and optional metadata and signature. The server may return the + // stored metadata back in the response. + // + // Parameters: + // - fileId: The identifier of the file to update metadata for. + // - e2eToken: Required token used to authorize the E2EE update. + // - e2eMetadata: Optional encrypted metadata payload to be stored. + // - signature: Optional signature for integrity/authentication (added to header). + // - method: The HTTP method to use (e.g., "PUT", "POST"). + // - account: The Nextcloud account performing the request. + // - options: Optional request options (includes version, queue, etc.). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, stored metadata (if any), response, and NKError. func putE2EEMetadata(fileId: String, e2eToken: String, e2eMetadata: String?, @@ -233,22 +316,51 @@ public extension NextcloudKit { } } + /// Asynchronously uploads E2EE metadata for a file using a given method, token and optional signature. + /// - Parameters: + /// - fileId: The ID of the file to update metadata for. + /// - e2eToken: The E2EE token used for authentication. + /// - e2eMetadata: Optional encrypted metadata. + /// - signature: Optional cryptographic signature (added to header). + /// - method: HTTP method to use (e.g., "PUT"). + /// - account: The account performing the operation. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the session task. + /// - Returns: A tuple containing the account, stored metadata (if any), response, and NKError. func putE2EEMetadataAsync(fileId: String, e2eToken: String, e2eMetadata: String?, signature: String?, method: String, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, metadata: String?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: signature, method: method, account: account, options: options) { account, metadata, responseData, error in - continuation.resume(returning: (account: account, metadata: metadata, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + putE2EEMetadata(fileId: fileId, + e2eToken: e2eToken, + e2eMetadata: e2eMetadata, + signature: signature, + method: method, + account: account, + options: options, + taskHandler: taskHandler) { account, metadata, response, error in + continuation.resume(returning: (account, metadata, response, error)) } - }) + } } // MARK: - + // Retrieves the public E2EE certificate (public key) for the given account or a specified user. + // If `user` is nil, the certificate for the current account is returned. + // If `user` is provided, the request fetches the public key of that user using a `users=[...]` query parameter. + // + // Parameters: + // - user: Optional username to fetch the public key for. If nil, fetches the current user's key. + // - account: The Nextcloud account performing the request. + // - options: Optional request options (includes version, task description, queue, etc.). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, the certificate string, the certificate user (if applicable), the raw response, and any NKError. func getE2EECertificate(user: String? = nil, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -300,16 +412,36 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves the E2EE public certificate for the current or specified user. + /// - Parameters: + /// - user: Optional username to query (nil fetches current user). + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options. + /// - taskHandler: Closure to access the session task. + /// - Returns: A tuple with account, current user's certificate, specified user's certificate (if any), response, and NKError. func getE2EECertificateAsync(user: String? = nil, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, certificate: String?, certificateUser: String?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.getE2EECertificate(user: user, account: account, options: options) { account, certificate, certificateUser, responseData, error in - continuation.resume(returning: (account: account, certificate: certificate, certificateUser: certificateUser, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getE2EECertificate(user: user, + account: account, + options: options, + taskHandler: taskHandler) { account, certificate, certificateUser, response, error in + continuation.resume(returning: (account, certificate, certificateUser, response, error)) } - }) + } } + // Retrieves the private E2EE key for the current account from the Nextcloud server. + // This key is typically encrypted and used for decrypting user data locally. + // The endpoint used is versioned via `options.version` (default: "v1"). + // + // Parameters: + // - account: The Nextcloud account requesting the private key. + // - options: Optional request options (includes version, queue, etc.). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, private key string, raw response, and NKError. func getE2EEPrivateKey(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -346,6 +478,33 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves the private E2EE key for the given account. + /// - Parameters: + /// - account: The account requesting the private key. + /// - options: Optional request options. + /// - taskHandler: Closure to access the URLSessionTask. + /// - Returns: A tuple containing the account, private key (if any), response, and NKError. + func getE2EEPrivateKeyAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getE2EEPrivateKey(account: account, + options: options, + taskHandler: taskHandler) { account, key, response, error in + continuation.resume(returning: (account, key, response, error)) + } + } + } + + // Retrieves the server's E2EE public key for the current Nextcloud instance. + // This key is used by clients to encrypt data that will be sent to the server. + // The request targets the `server-key` endpoint and returns the PEM-formatted public key. + // + // Parameters: + // - account: The Nextcloud account performing the request. + // - options: Optional request options (includes version, queue, etc.). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, public key string, raw response, and NKError. func getE2EEPublicKey(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -382,6 +541,34 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves the server’s E2EE public key for the specified account. + /// - Parameters: + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options. + /// - taskHandler: Closure to access the session task. + /// - Returns: A tuple with account, public key (if any), raw response, and NKError. + func getE2EEPublicKeyAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getE2EEPublicKey(account: account, + options: options, + taskHandler: taskHandler) { account, key, response, error in + continuation.resume(returning: (account, key, response, error)) + } + } + } + + // Sends a certificate signing request (CSR) to the server in order to obtain a signed E2EE public certificate. + // The server responds with a signed public key associated with the account. + // The request is sent via HTTP POST to the `/public-key` endpoint. + // + // Parameters: + // - certificate: The CSR (Certificate Signing Request) in string format to be signed by the server. + // - account: The Nextcloud account performing the request. + // - options: Optional request options (e.g., version, queue, headers). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, signed certificate string, response, and NKError. func signE2EECertificate(certificate: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -421,6 +608,37 @@ public extension NextcloudKit { } } + /// Asynchronously requests a signed E2EE public key from the server by submitting a CSR. + /// - Parameters: + /// - certificate: The certificate signing request (CSR) string. + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options. + /// - taskHandler: Closure to access the session task. + /// - Returns: A tuple containing the account, signed public key (if any), response, and NKError. + func signE2EECertificateAsync(certificate: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + signE2EECertificate(certificate: certificate, + account: account, + options: options, + taskHandler: taskHandler) { account, signedCert, response, error in + continuation.resume(returning: (account, signedCert, response, error)) + } + } + } + + // Stores the user's E2EE private key securely on the Nextcloud server. + // This is typically done during initial key setup or key backup. + // The private key is sent as a POST parameter to the `/private-key` endpoint. + // + // Parameters: + // - privateKey: The PEM-formatted private key string to be stored on the server. + // - account: The Nextcloud account performing the operation. + // - options: Optional request options (versioning, queue dispatch, headers, etc.). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, stored private key (as echoed back), response, and NKError. func storeE2EEPrivateKey(privateKey: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -459,6 +677,36 @@ public extension NextcloudKit { } } + /// Asynchronously stores the given E2EE private key for the specified account. + /// - Parameters: + /// - privateKey: The PEM-formatted private key to store. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request options. + /// - taskHandler: Closure to access the session task. + /// - Returns: A tuple with account, echoed private key (if any), response, and NKError. + func storeE2EEPrivateKeyAsync(privateKey: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + storeE2EEPrivateKey(privateKey: privateKey, + account: account, + options: options, + taskHandler: taskHandler) { account, key, response, error in + continuation.resume(returning: (account, key, response, error)) + } + } + } + + // Deletes the currently stored E2EE public certificate from the Nextcloud server. + // This is typically used during key revocation or reinitialization of E2EE. + // The request targets the `public-key` endpoint with the HTTP DELETE method. + // + // Parameters: + // - account: The Nextcloud account requesting the deletion of the certificate. + // - options: Optional request options (e.g., version, dispatch queue, headers). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, raw response, and NKError. func deleteE2EECertificate(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -487,6 +735,33 @@ public extension NextcloudKit { } } + /// Asynchronously deletes the E2EE public certificate for the given account. + /// - Parameters: + /// - account: The Nextcloud account performing the deletion. + /// - options: Optional request options. + /// - taskHandler: Closure to access the session task. + /// - Returns: A tuple containing the account, response, and NKError. + func deleteE2EECertificateAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + deleteE2EECertificate(account: account, + options: options, + taskHandler: taskHandler) { account, response, error in + continuation.resume(returning: (account, response, error)) + } + } + } + + // Deletes the user's E2EE private key stored on the Nextcloud server. + // This operation is typically performed when revoking access to the encrypted data, + // or during account reset scenarios. + // + // Parameters: + // - account: The Nextcloud account requesting the deletion of its private key. + // - options: Optional request options (API version, dispatch queue, headers). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, raw response, and NKError. func deleteE2EEPrivateKey(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -515,4 +790,22 @@ public extension NextcloudKit { } } } + + /// Asynchronously deletes the E2EE private key for the given account. + /// - Parameters: + /// - account: The Nextcloud account performing the deletion. + /// - options: Optional request options. + /// - taskHandler: Closure to access the session task. + /// - Returns: A tuple containing the account, response, and NKError. + func deleteE2EEPrivateKeyAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + deleteE2EEPrivateKey(account: account, + options: options, + taskHandler: taskHandler) { account, response, error in + continuation.resume(returning: (account, response, error)) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+FilesLock.swift b/Sources/NextcloudKit/NextcloudKit+FilesLock.swift index 516399ea..4c977d1d 100644 --- a/Sources/NextcloudKit/NextcloudKit+FilesLock.swift +++ b/Sources/NextcloudKit/NextcloudKit+FilesLock.swift @@ -7,6 +7,17 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Sends a WebDAV LOCK or UNLOCK request for a file on the server, + // depending on the `shouldLock` flag. This is used to prevent or release + // concurrent edits on a file. + // + // Parameters: + // - serverUrlFileName: Fully qualified and encoded URL of the file to lock/unlock. + // - shouldLock: Pass `true` to lock the file, `false` to unlock it. + // - account: The Nextcloud account performing the operation. + // - options: Optional request options (e.g. headers, queue). + // - taskHandler: Closure to access the URLSessionTask. + // - completion: Completion handler returning the account, response, and NKError. func lockUnlockFile(serverUrlFileName: String, shouldLock: Bool, account: String, @@ -37,4 +48,28 @@ public extension NextcloudKit { } } } + + /// Asynchronously locks or unlocks a file depending on `shouldLock`. + /// - Parameters: + /// - serverUrlFileName: Encoded file URL to act on. + /// - shouldLock: Whether to lock (`true`) or unlock (`false`) the file. + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the session task. + /// - Returns: A tuple containing the account, response, and NKError. + func lockUnlockFileAsync(serverUrlFileName: String, + shouldLock: Bool, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + lockUnlockFile(serverUrlFileName: serverUrlFileName, + shouldLock: shouldLock, + account: account, + options: options, + taskHandler: taskHandler) { account, response, error in + continuation.resume(returning: (account, response, error)) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift b/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift index 2f2987b1..3e5e02b6 100644 --- a/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift +++ b/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift @@ -8,6 +8,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Retrieves the list of available group folders for the given Nextcloud account. + // Group folders are shared spaces available across users and groups, + // managed via the groupfolders app. + // + // Parameters: + // - account: The Nextcloud account requesting the list of group folders. + // - options: Optional request options (e.g., API version, custom headers, queue). + // - taskHandler: Closure to access the underlying URLSessionTask. + // - completion: Completion handler returning the account, list of group folders, response, and any NKError. func getGroupfolders(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -46,6 +55,24 @@ public extension NextcloudKit { } } } + + /// Asynchronously retrieves the list of group folders for the specified account. + /// - Parameters: + /// - account: The Nextcloud account requesting group folders. + /// - options: Optional request configuration. + /// - taskHandler: Optional closure to access the session task. + /// - Returns: A tuple containing the account, parsed list of group folders, raw response, and NKError. + func getGroupfoldersAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKGroupfolders]?, AFDataResponse?, NKError) { + await withCheckedContinuation { continuation in + getGroupfolders(account: account, + options: options, + taskHandler: taskHandler) { account, results, responseData, error in + continuation.resume(returning: (account, results, responseData, error)) + } + } + } } public class NKGroupfolders: NSObject { From 8b681221556aa91ed69d1cdf3732526d18dce456 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 11:33:03 +0200 Subject: [PATCH 02/10] async Signed-off-by: Marino Faggiana --- Sources/NextcloudKit/NextcloudKit+API.swift | 121 +++++-- .../NextcloudKit/NextcloudKit+Assistant.swift | 186 +++++++--- .../NextcloudKit+AssistantV2.swift | 145 ++++++-- .../NextcloudKit/NextcloudKit+Comments.swift | 163 ++++++--- .../NextcloudKit/NextcloudKit+Dashboard.swift | 54 ++- .../NextcloudKit/NextcloudKit+Download.swift | 41 ++- Sources/NextcloudKit/NextcloudKit+E2EE.swift | 323 ++++++++++++------ .../NextcloudKit/NextcloudKit+FilesLock.swift | 29 +- .../NextcloudKit+Groupfolders.swift | 25 +- 9 files changed, 797 insertions(+), 290 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+API.swift b/Sources/NextcloudKit/NextcloudKit+API.swift index ed90b941..81fe93f1 100644 --- a/Sources/NextcloudKit/NextcloudKit+API.swift +++ b/Sources/NextcloudKit/NextcloudKit+API.swift @@ -31,6 +31,14 @@ public class NKNotifications: NSObject { } public extension NextcloudKit { + // Checks if the specified server URL is reachable and returns the raw HTTP response. + // Used to verify the availability and responsiveness of a Nextcloud server. + // + // Parameters: + // - serverUrl: Full URL of the Nextcloud server to check. + // - options: Optional request options (e.g. custom headers, queue). + // - taskHandler: Closure to access the URLSessionTask (default is no-op). + // - completion: Completion handler with the raw HTTP response and any NKError. func checkServer(serverUrl: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -50,24 +58,43 @@ public extension NextcloudKit { } } - /// Asynchronously checks the server status using the provided URL and request options. + /// Asynchronously checks the specified server URL and returns the HTTP response and error. /// - Parameters: /// - serverUrl: The URL of the server to check. - /// - options: Optional request options (default: `NKRequestOptions()`). - /// - taskHandler: Optional closure to receive the `URLSessionTask` (default: no-op). - /// - Returns: A tuple containing the optional `AFDataResponse` and an `NKError`. + /// - options: Optional request options. + /// - taskHandler: Optional closure to access the session task. + /// - Returns: A tuple containing the raw response and NKError, with named values. func checkServerAsync(serverUrl: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in - checkServer(serverUrl: serverUrl, options: options, taskHandler: taskHandler) { responseData, error in - continuation.resume(returning: (responseData, error)) + checkServer(serverUrl: serverUrl, + options: options, + taskHandler: taskHandler) { responseData, error in + continuation.resume(returning: ( + responseData: responseData, + error: error + )) } } } // MARK: - + // Executes a generic HTTP request using the given relative endpoint path and HTTP method. + // Commonly used for flexible OCS or WebDAV API calls without dedicated wrappers. + // + // Parameters: + // - endpoint: The relative API path (e.g. "ocs/v2.php/apps/...") to be appended to the base server URL. + // - account: The Nextcloud account initiating the request. + // - method: The HTTP method as a string ("GET", "POST", "DELETE", etc). + // - options: Optional request options such as custom headers, versioning, queue. + // - taskHandler: Optional closure to access the underlying URLSessionTask. + // - completion: Completion handler returning the account, raw response, and any NKError. func generalWithEndpoint(_ endpoint: String, account: String, method: String, @@ -92,32 +119,49 @@ public extension NextcloudKit { } } - /// Asynchronously executes a general network request with the specified endpoint and method. + /// Asynchronously performs a generic request using the specified endpoint and method. /// - Parameters: - /// - endpoint: The endpoint to call (e.g., "/ocs/v2.php/apps/..."). - /// - account: The identifier for the user/account associated with the request. - /// - method: The HTTP method (e.g., "GET", "POST"). - /// - options: Optional request options (default: `NKRequestOptions()`). - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple containing the account, the optional response, and the `NKError`. + /// - endpoint: Relative path to the server API. + /// - account: The account initiating the request. + /// - method: HTTP method string. + /// - options: Optional request configuration. + /// - taskHandler: Closure to access the URLSessionTask. + /// - Returns: A tuple with named values: account, raw response, and error. func generalWithEndpointAsync(_ endpoint: String, account: String, method: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in generalWithEndpoint(endpoint, account: account, method: method, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } // MARK: - + // Retrieves the list of external sites configured in the Nextcloud instance. + // These are typically links to external services or resources displayed in the web UI. + // + // Parameters: + // - account: The Nextcloud account making the request. + // - options: Optional request options for custom headers, versioning, queue, etc. + // - taskHandler: Closure to access the URLSessionTask (default is no-op). + // - completion: Completion handler returning the account, list of external sites, response, and any NKError. func getExternalSite(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -156,20 +200,31 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves external sites for the given account. + /// Asynchronously retrieves the list of external sites for the specified account. /// - Parameters: - /// - account: The identifier for the account. - /// - options: Optional request options (default: `NKRequestOptions()`). - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple with account identifier, external sites list, response data, and NKError. + /// - account: The Nextcloud account making the request. + /// - options: Optional request configuration. + /// - taskHandler: Closure to access the URLSessionTask. + /// - Returns: A tuple containing account, external sites array, raw response, and error. func getExternalSiteAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKExternalSite], AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + externalSite: [NKExternalSite], + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getExternalSite(account: account, options: options, taskHandler: taskHandler) { account, externalSite, responseData, error in - continuation.resume(returning: (account, externalSite, responseData, error)) + continuation.resume(returning: ( + account: account, + externalSite: externalSite, + responseData: responseData, + error: error + )) } } } @@ -381,7 +436,15 @@ public extension NextcloudKit { mimeFallback: Int = 0, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, Int, Int, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + width: Int, + height: Int, + etag: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in downloadPreview(fileId: fileId, width: width, @@ -394,11 +457,17 @@ public extension NextcloudKit { account: account, options: options, taskHandler: taskHandler) { account, w, h, tag, responseData, error in - continuation.resume(returning: (account, w, h, tag, responseData, error)) + continuation.resume(returning: ( + account: account, + width: w, + height: h, + etag: tag, + responseData: responseData, + error: error + )) } } } - func downloadTrashPreview(fileId: String, width: Int = 512, height: Int = 512, diff --git a/Sources/NextcloudKit/NextcloudKit+Assistant.swift b/Sources/NextcloudKit/NextcloudKit+Assistant.swift index 3a4d1d9e..43242eb3 100644 --- a/Sources/NextcloudKit/NextcloudKit+Assistant.swift +++ b/Sources/NextcloudKit/NextcloudKit+Assistant.swift @@ -7,6 +7,14 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Retrieves the list of supported text processing task types from the server. + // These types define the kinds of operations (e.g., summarization, translation) supported by the assistant API. + // + // Parameters: + // - account: The Nextcloud account initiating the request. + // - options: Optional configuration for the HTTP request. + // - taskHandler: Optional closure to access the underlying URLSessionTask. + // - completion: Completion handler providing the account, available task types, response, and NKError. func textProcessingGetTypes(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -40,24 +48,47 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves available text processing task types for the given account. + /// Asynchronously retrieves available text processing task types from the server. /// - Parameters: - /// - account: The account identifier. + /// - account: The Nextcloud account initiating the request. /// - options: Optional request options. - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple with account, list of task types, response data, and error. + /// - taskHandler: Closure to access the session task. + /// - Returns: A tuple with named values for account, list of task types, response, and error. func textProcessingGetTypesAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKTextProcessingTaskType]?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + types: [NKTextProcessingTaskType]?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingGetTypes(account: account, options: options, taskHandler: taskHandler) { account, types, responseData, error in - continuation.resume(returning: (account, types, responseData, error)) + continuation.resume(returning: ( + account: account, + types: types, + responseData: responseData, + error: error + )) } } } + // Schedules a new text processing task on the server (e.g., translation, summary, etc.). + // The request includes the input text, the type of task to execute, and a unique identifier. + // + // Parameters: + // - input: The raw input string to be processed. + // - typeId: The identifier of the task type (e.g., "summarize", "translate"). + // - appId: The application identifier (default is "assistant"). + // - identifier: A client-side unique string to track this task. + // - account: The Nextcloud account executing the request. + // - options: Optional request configuration (headers, queue, etc.). + // - taskHandler: Optional closure to access the URLSessionTask. + // - completion: Completion handler returning the account, resulting task object, response, and any NKError. func textProcessingSchedule(input: String, typeId: String, appId: String = "assistant", @@ -96,23 +127,29 @@ public extension NextcloudKit { } } - /// Asynchronously schedules a text processing task. + /// Asynchronously schedules a text processing task on the server. /// - Parameters: - /// - input: The input string to be processed. - /// - typeId: The identifier of the processing type. - /// - appId: The app identifier (default: "assistant"). - /// - identifier: The task identifier. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, the scheduled task, response data, and error. + /// - input: Input string to process. + /// - typeId: Task type identifier. + /// - appId: Optional app ID, defaults to "assistant". + /// - identifier: Unique task identifier. + /// - account: Nextcloud account. + /// - options: Request configuration. + /// - taskHandler: Optional access to the URLSessionTask. + /// - Returns: A tuple with named values for account, task object, raw response, and error. func textProcessingScheduleAsync(input: String, typeId: String, appId: String = "assistant", identifier: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKTextProcessingTask?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + task: NKTextProcessingTask?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingSchedule(input: input, typeId: typeId, @@ -121,11 +158,25 @@ public extension NextcloudKit { account: account, options: options, taskHandler: taskHandler) { account, task, responseData, error in - continuation.resume(returning: (account, task, responseData, error)) + continuation.resume(returning: ( + account: account, + task: task, + responseData: responseData, + error: error + )) } } } + // Retrieves the current status and data of a previously scheduled text processing task. + // Useful for polling or checking the result of a long-running task by its unique ID. + // + // Parameters: + // - taskId: The server-side ID of the text processing task to retrieve. + // - account: The Nextcloud account making the request. + // - options: Optional request configuration. + // - taskHandler: Optional closure to access the URLSessionTask. + // - completion: Completion handler returning the account, task object, raw response, and NKError. func textProcessingGetTask(taskId: Int, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -160,27 +211,47 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves a specific text processing task by ID. + /// Asynchronously retrieves the details of a specific text processing task. /// - Parameters: - /// - taskId: The unique identifier of the text processing task. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, the task (if found), response data, and error. + /// - taskId: The ID of the task to fetch. + /// - account: The account used for the request. + /// - options: Optional configuration. + /// - taskHandler: Closure to access the session task. + /// - Returns: A tuple with named values for account, task object, response, and error. func textProcessingGetTaskAsync(taskId: Int, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKTextProcessingTask?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + task: NKTextProcessingTask?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingGetTask(taskId: taskId, account: account, options: options, taskHandler: taskHandler) { account, task, responseData, error in - continuation.resume(returning: (account, task, responseData, error)) + continuation.resume(returning: ( + account: account, + task: task, + responseData: responseData, + error: error + )) } } } + // Deletes a specific text processing task on the server. + // This is used to cancel or clean up tasks that are no longer needed. + // + // Parameters: + // - taskId: The ID of the task to be deleted. + // - account: The Nextcloud account making the request. + // - options: Optional request configuration. + // - taskHandler: Optional closure to access the URLSessionTask. + // - completion: Completion handler returning the account, deleted task object, raw response, and NKError. func textProcessingDeleteTask(taskId: Int, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -215,27 +286,47 @@ public extension NextcloudKit { } } - /// Asynchronously deletes a text processing task by its ID. + /// Asynchronously deletes a scheduled text processing task from the server. /// - Parameters: - /// - taskId: The ID of the task to delete. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, the deleted task (if returned), response data, and error. + /// - taskId: ID of the task to delete. + /// - account: Account executing the deletion. + /// - options: Request options. + /// - taskHandler: Callback for the underlying URLSessionTask. + /// - Returns: A tuple with named values for account, deleted task object, response, and error. func textProcessingDeleteTaskAsync(taskId: Int, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKTextProcessingTask?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + task: NKTextProcessingTask?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingDeleteTask(taskId: taskId, account: account, options: options, taskHandler: taskHandler) { account, task, responseData, error in - continuation.resume(returning: (account, task, responseData, error)) + continuation.resume(returning: ( + account: account, + task: task, + responseData: responseData, + error: error + )) } } } + // Retrieves a list of all text processing tasks associated with a specific app ID. + // This includes both pending and completed tasks, useful for tracking the assistant's activity. + // + // Parameters: + // - appId: Identifier of the application requesting the tasks (e.g., "assistant"). + // - account: The Nextcloud account making the request. + // - options: Optional HTTP request configuration. + // - taskHandler: Optional closure to access the URLSessionTask. + // - completion: Completion handler returning the account, task list, raw response, and NKError. func textProcessingTaskList(appId: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -270,23 +361,34 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves the list of text processing tasks for the given app and account. + /// Asynchronously retrieves all text processing tasks associated with a specific app ID. /// - Parameters: - /// - appId: The application identifier (e.g., "assistant"). - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, task list (if any), response data, and error. + /// - appId: The application identifier to filter the task list. + /// - account: The account performing the request. + /// - options: Optional request configuration. + /// - taskHandler: Callback for the URLSessionTask. + /// - Returns: A tuple with named values for account, task list, response, and error. func textProcessingTaskListAsync(appId: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKTextProcessingTask]?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + task: [NKTextProcessingTask]?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingTaskList(appId: appId, account: account, options: options, - taskHandler: taskHandler) { account, taskList, responseData, error in - continuation.resume(returning: (account, taskList, responseData, error)) + taskHandler: taskHandler) { account, task, responseData, error in + continuation.resume(returning: ( + account: account, + task: task, + responseData: responseData, + error: error + )) } } } diff --git a/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift b/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift index e4fade2a..25fda361 100644 --- a/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift +++ b/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift @@ -7,6 +7,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Retrieves the list of supported task types for a specific account and task category. + // Typically used to discover available AI or text processing capabilities. + // + // Parameters: + // - account: The Nextcloud account making the request. + // - supportedTaskType: Type of tasks to retrieve, default is "Text". + // - options: Optional HTTP request configuration. + // - taskHandler: Optional closure to access the URLSessionTask. + // - completion: Completion handler returning the account, list of supported types, raw response, and NKError. func textProcessingGetTypesV2(account: String, supportedTaskType: String = "Text", options: NKRequestOptions = NKRequestOptions(), @@ -45,27 +54,48 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves available task types (v2) for the given account and supported task type. + /// Asynchronously retrieves the supported task types for the given account and category. /// - Parameters: - /// - account: The account identifier. - /// - supportedTaskType: The supported type (e.g. "Text", default: "Text"). - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, list of task types (if any), response data, and error. + /// - account: Account performing the request. + /// - supportedTaskType: The task category to filter by (default: "Text"). + /// - options: Optional configuration. + /// - taskHandler: Callback for the underlying URLSessionTask. + /// - Returns: A tuple with named values for account, supported types, response, and error. func textProcessingGetTypesV2Async(account: String, supportedTaskType: String = "Text", options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [TaskTypeData]?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + types: [TaskTypeData]?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingGetTypesV2(account: account, supportedTaskType: supportedTaskType, options: options, taskHandler: taskHandler) { account, types, responseData, error in - continuation.resume(returning: (account, types, responseData, error)) + continuation.resume(returning: ( + account: account, + types: types, + responseData: responseData, + error: error + )) } } } + // Schedules a new text processing task for a specific account and task type. + // Useful for initiating assistant-based text analysis, generation, or transformation. + // + // Parameters: + // - input: The input text to be processed. + // - taskType: The specific task type to execute (e.g., summarization, sentiment analysis). + // - account: The Nextcloud account initiating the task. + // - options: Optional HTTP request configuration. + // - taskHandler: Optional closure to access the underlying URLSessionTask. + // - completion: Completion handler returning the account, scheduled task, raw response, and NKError. func textProcessingScheduleV2(input: String, taskType: TaskTypeData, account: String, @@ -104,30 +134,50 @@ public extension NextcloudKit { } } - /// Asynchronously schedules a text processing task using V2 API. + /// Asynchronously schedules a new text processing task using the specified task type. /// - Parameters: - /// - input: The input text to process. - /// - taskType: The task type data (e.g., summarization, translation). - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, scheduled task (if any), response data, and error. + /// - input: Input text to be processed. + /// - taskType: Type of task to be executed. + /// - account: The account performing the scheduling. + /// - options: Optional configuration. + /// - taskHandler: Callback to access the associated URLSessionTask. + /// - Returns: A tuple with named values for account, scheduled task, response, and error. func textProcessingScheduleV2Async(input: String, taskType: TaskTypeData, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AssistantTask?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + task: AssistantTask?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingScheduleV2(input: input, taskType: taskType, account: account, options: options, taskHandler: taskHandler) { account, task, responseData, error in - continuation.resume(returning: (account, task, responseData, error)) + continuation.resume(returning: ( + account: account, + task: task, + responseData: responseData, + error: error + )) } } } + // Retrieves all scheduled text processing tasks of a specific type for the given account. + // Useful for listing and tracking tasks like summarization, transcription, or classification. + // + // Parameters: + // - taskType: Identifier of the task type to filter tasks (e.g., "Text"). + // - account: The Nextcloud account performing the request. + // - options: Optional HTTP request configuration. + // - taskHandler: Optional closure to access the underlying URLSessionTask. + // - completion: Completion handler returning the account, list of tasks, raw response, and NKError. func textProcessingGetTasksV2(taskType: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -162,27 +212,47 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves the list of tasks for a given task type using V2 API. + /// Asynchronously retrieves a list of scheduled text processing tasks for a specific type. /// - Parameters: - /// - taskType: The type of tasks to retrieve (e.g., "summary"). - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, list of tasks (if any), response data, and error. + /// - taskType: Type of the tasks to query. + /// - account: The account performing the query. + /// - options: Optional configuration. + /// - taskHandler: Callback to access the associated URLSessionTask. + /// - Returns: A tuple with named values for account, task list, response, and error. func textProcessingGetTasksV2Async(taskType: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, TaskList?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + tasks: TaskList?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingGetTasksV2(taskType: taskType, account: account, options: options, taskHandler: taskHandler) { account, tasks, responseData, error in - continuation.resume(returning: (account, tasks, responseData, error)) + continuation.resume(returning: ( + account: account, + tasks: tasks, + responseData: responseData, + error: error + )) } } } + // Deletes a scheduled text processing task with a specific identifier. + // Useful for canceling tasks that are no longer needed or invalid. + // + // Parameters: + // - taskId: The unique identifier of the task to delete. + // - account: The Nextcloud account executing the deletion. + // - options: Optional HTTP request configuration. + // - taskHandler: Optional closure to access the underlying URLSessionTask. + // - completion: Completion handler returning the account, raw response, and NKError. func textProcessingDeleteTaskV2(taskId: Int64, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -215,23 +285,32 @@ public extension NextcloudKit { } } - /// Asynchronously deletes a text processing task (V2) by its ID. + /// Asynchronously deletes a text processing task by ID for the specified account. /// - Parameters: - /// - taskId: The ID of the task to delete (Int64). - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, response data, and error. + /// - taskId: ID of the task to be deleted. + /// - account: The account performing the operation. + /// - options: Optional configuration. + /// - taskHandler: Callback to access the associated URLSessionTask. + /// - Returns: A tuple with named values for account, response, and error. func textProcessingDeleteTaskV2Async(taskId: Int64, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in textProcessingDeleteTaskV2(taskId: taskId, account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } diff --git a/Sources/NextcloudKit/NextcloudKit+Comments.swift b/Sources/NextcloudKit/NextcloudKit+Comments.swift index 2fcd5aa0..48a27cab 100644 --- a/Sources/NextcloudKit/NextcloudKit+Comments.swift +++ b/Sources/NextcloudKit/NextcloudKit+Comments.swift @@ -6,6 +6,15 @@ import Foundation import Alamofire public extension NextcloudKit { + // Retrieves all comments associated with a specific file from the server. + // This is typically used in collaboration features to display user discussions or annotations. + // + // Parameters: + // - fileId: Identifier of the file whose comments are being retrieved. + // - account: The Nextcloud account requesting the comments. + // - options: Optional request customization (headers, timeout, etc.). + // - taskHandler: Optional closure to access the underlying URLSessionTask. + // - completion: Completion handler returning the account, comment list, raw response, and NKError. func getComments(fileId: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -51,27 +60,48 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves comments for a given file ID. + /// Asynchronously retrieves the list of comments for a given file ID. /// - Parameters: - /// - fileId: The file identifier to fetch comments for. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, list of comments (if any), response data, and error. + /// - fileId: File identifier to fetch comments for. + /// - account: The account executing the request. + /// - options: Optional configuration for the HTTP request. + /// - taskHandler: Callback for accessing the URLSessionTask. + /// - Returns: A tuple with named values for account, comment list, response, and error. func getCommentsAsync(fileId: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKComments]?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + items: [NKComments]?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getComments(fileId: fileId, account: account, options: options, taskHandler: taskHandler) { account, items, responseData, error in - continuation.resume(returning: (account, items, responseData, error)) + continuation.resume(returning: ( + account: account, + items: items, + responseData: responseData, + error: error + )) } } } + // Adds a new comment to a specific file. + // Useful for enabling collaboration or user discussions directly on file items. + // + // Parameters: + // - fileId: Identifier of the file to which the comment will be added. + // - message: The content of the comment to post. + // - account: The Nextcloud account posting the comment. + // - options: Optional HTTP configuration (headers, timeout, etc.). + // - taskHandler: Optional callback to access the URLSessionTask. + // - completion: Completion handler with account, response, and error. func putComments(fileId: String, message: String, account: String, @@ -111,30 +141,50 @@ public extension NextcloudKit { } } - /// Asynchronously adds a comment to a file. + /// Asynchronously posts a new comment to a file. /// - Parameters: - /// - fileId: The file identifier to comment on. - /// - message: The comment message. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, response data, and error. + /// - fileId: The file to comment on. + /// - message: The comment body. + /// - account: The account sending the request. + /// - options: Optional network options. + /// - taskHandler: Callback to monitor the network task. + /// - Returns: A tuple with account, response data, and any resulting error. func putCommentsAsync(fileId: String, message: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in putComments(fileId: fileId, message: message, account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } + // Updates the content of an existing comment on a file. + // Useful for editing or correcting previously posted comments. + // + // Parameters: + // - fileId: Identifier of the file that contains the comment. + // - messageId: Identifier of the specific comment to be updated. + // - message: The new content to replace the old comment. + // - account: The Nextcloud account performing the update. + // - options: Optional HTTP configuration (e.g., headers, timeout). + // - taskHandler: Optional callback to inspect the created URLSessionTask. + // - completion: Completion handler returning account, response, and NKError. func updateComments(fileId: String, messageId: String, message: String, @@ -176,21 +226,26 @@ public extension NextcloudKit { } } - /// Asynchronously updates an existing comment on a file. + /// Asynchronously updates a specific comment on a file. /// - Parameters: - /// - fileId: The file identifier. - /// - messageId: The ID of the comment to update. - /// - message: The updated comment message. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. + /// - fileId: File containing the comment. + /// - messageId: ID of the comment to be updated. + /// - message: New content of the comment. + /// - account: User account executing the update. + /// - options: Optional request configuration. + /// - taskHandler: Callback for accessing the request task. /// - Returns: A tuple with account, response data, and error. func updateCommentsAsync(fileId: String, messageId: String, message: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in updateComments(fileId: fileId, messageId: messageId, @@ -198,7 +253,11 @@ public extension NextcloudKit { account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } @@ -240,26 +299,35 @@ public extension NextcloudKit { } } - /// Asynchronously deletes a specific comment from a file for the given account. + /// Asynchronously deletes a comment from a file. /// - Parameters: - /// - fileId: The identifier of the file containing the comment. - /// - messageId: The ID of the comment to delete. - /// - account: The account performing the request. - /// - options: Optional request options (default is empty). - /// - taskHandler: Closure to access the URLSessionTask (default is empty). - /// - Returns: A tuple containing the account identifier, optional response, and NKError. + /// - fileId: File containing the comment. + /// - messageId: ID of the comment to be deleted. + /// - account: User account performing the deletion. + /// - options: Additional configuration for the HTTP request. + /// - taskHandler: Optional handler for the URLSessionTask. + /// - Returns: A tuple with account, server response, and an NKError. func deleteCommentsAsync(fileId: String, messageId: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in deleteComments(fileId: fileId, messageId: messageId, account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } @@ -312,23 +380,32 @@ public extension NextcloudKit { } } - /// Asynchronously marks all comments on a file as read for the given account. + /// Asynchronously marks all comments on a file as read. /// - Parameters: - /// - fileId: The identifier of the file. - /// - account: The account performing the request. - /// - options: Optional request options (default is empty). - /// - taskHandler: Optional closure to access the URLSessionTask (default is no-op). - /// - Returns: A tuple with the account, optional response, and NKError. + /// - fileId: File whose comments should be marked as read. + /// - account: The account executing the read marking. + /// - options: Optional configuration for the request. + /// - taskHandler: Optional handler for the URLSessionTask. + /// - Returns: A tuple containing the account, response data, and any NKError. func markAsReadCommentsAsync(fileId: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in markAsReadComments(fileId: fileId, account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } diff --git a/Sources/NextcloudKit/NextcloudKit+Dashboard.swift b/Sources/NextcloudKit/NextcloudKit+Dashboard.swift index 712dbc0c..0e1cd182 100644 --- a/Sources/NextcloudKit/NextcloudKit+Dashboard.swift +++ b/Sources/NextcloudKit/NextcloudKit+Dashboard.swift @@ -51,23 +51,34 @@ public extension NextcloudKit { options.queue.async { request(dashboardRequest) } } - /// Asynchronously retrieves the dashboard widgets for the given account. + /// Asynchronously fetches the dashboard widgets available for a specific account. /// - Parameters: - /// - account: The account requesting the widgets. - /// - options: Optional request options (default is empty). - /// - request: Optional closure that receives the internal Alamofire `DataRequest`. - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple with the account, optional widget list, raw response, and NKError. + /// - account: The account from which to fetch the widgets. + /// - options: Optional configuration for the request. + /// - request: Optional handler to capture the `DataRequest`. + /// - taskHandler: Optional handler for the `URLSessionTask`. + /// - Returns: A tuple with the account, list of widgets, raw response, and NKError. func getDashboardWidgetAsync(account: String, options: NKRequestOptions = NKRequestOptions(), request: @escaping (DataRequest?) -> Void = { _ in }, - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NCCDashboardWidget]?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + dashboardWidgets: [NCCDashboardWidget]?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getDashboardWidget(account: account, options: options, request: request, taskHandler: taskHandler) { account, dashboardWidgets, responseData, error in - continuation.resume(returning: (account, dashboardWidgets, responseData, error)) + continuation.resume(returning: ( + account: account, + dashboardWidgets: dashboardWidgets, + responseData: responseData, + error: error + )) } } } @@ -118,26 +129,37 @@ public extension NextcloudKit { options.queue.async { request(dashboardRequest) } } - /// Asynchronously retrieves dashboard application widgets for the given account and item list. + /// Asynchronously fetches dashboard widgets tied to specific applications. /// - Parameters: - /// - items: A comma-separated list of widget types to retrieve. + /// - items: A comma-separated list of app IDs (e.g., "files,calendar"). /// - account: The account performing the request. - /// - options: Optional request options (default is empty). - /// - request: Optional closure to inspect the internal `DataRequest`. - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple with account, list of dashboard applications, raw response, and error. + /// - options: Optional request configuration. + /// - request: Handler for the `DataRequest` (if needed). + /// - taskHandler: Handler for the underlying `URLSessionTask`. + /// - Returns: A tuple with account, dashboard applications, response data, and NKError. func getDashboardWidgetsApplicationAsync(_ items: String, account: String, options: NKRequestOptions = NKRequestOptions(), request: @escaping (DataRequest?) -> Void = { _ in }, - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NCCDashboardApplication]?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + dashboardApplications: [NCCDashboardApplication]?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getDashboardWidgetsApplication(items, account: account, options: options, request: request, taskHandler: taskHandler) { account, dashboardApplications, responseData, error in - continuation.resume(returning: (account, dashboardApplications, responseData, error)) + continuation.resume(returning: ( + account: account, + dashboardApplications: dashboardApplications, + responseData: responseData, + error: error + )) } } } diff --git a/Sources/NextcloudKit/NextcloudKit+Download.swift b/Sources/NextcloudKit/NextcloudKit+Download.swift index d45b4d81..8c88b953 100644 --- a/Sources/NextcloudKit/NextcloudKit+Download.swift +++ b/Sources/NextcloudKit/NextcloudKit+Download.swift @@ -82,23 +82,32 @@ public extension NextcloudKit { options.queue.async { requestHandler(request) } } - /// Asynchronously downloads a file and returns detailed download metadata. + /// Asynchronously downloads a file to the specified local path, with optional progress and task tracking. /// - Parameters: - /// - serverUrlFileName: The remote file path or URL (typically String or URL). - /// - fileNameLocalPath: The local file path where the file will be saved. - /// - account: The account performing the download. - /// - options: Optional request options (default is empty). - /// - requestHandler: Closure to access the `DownloadRequest`. - /// - taskHandler: Closure to access the `URLSessionTask`. - /// - progressHandler: Closure to monitor download progress. - /// - Returns: A tuple with account, ETag, modified date, file size, headers, AFError (if any), and NKError. + /// - serverUrlFileName: A URL or object convertible to a URL string. + /// - fileNameLocalPath: Destination path for the local file. + /// - account: The Nextcloud account used for the request. + /// - options: Optional request configuration. + /// - requestHandler: Handler for accessing the `DownloadRequest`. + /// - taskHandler: Handler for monitoring the `URLSessionTask`. + /// - progressHandler: Progress tracking callback. + /// - Returns: A tuple with account, etag, date, content length, headers, Alamofire error, and internal NKError. func downloadAsync(serverUrlFileName: Any, fileNameLocalPath: String, account: String, options: NKRequestOptions = NKRequestOptions(), requestHandler: @escaping (_ request: DownloadRequest) -> Void = { _ in }, taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, - progressHandler: @escaping (_ progress: Progress) -> Void = { _ in }) async -> (String, String?, Date?, Int64, [AnyHashable: Any]?, AFError?, NKError) { + progressHandler: @escaping (_ progress: Progress) -> Void = { _ in } + ) async -> ( + account: String, + etag: String?, + date: Date?, + length: Int64, + headers: [AnyHashable: Any]?, + afError: AFError?, + nkError: NKError + ) { await withCheckedContinuation { continuation in download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, @@ -106,8 +115,16 @@ public extension NextcloudKit { options: options, requestHandler: requestHandler, taskHandler: taskHandler, - progressHandler: progressHandler) { account, etag, date, length, headers, afError, nKError in - continuation.resume(returning: (account, etag, date, length, headers, afError, nKError)) + progressHandler: progressHandler) { account, etag, date, length, headers, afError, nkError in + continuation.resume(returning: ( + account: account, + etag: etag, + date: date, + length: length, + headers: headers, + afError: afError, + nkError: nkError + )) } } } diff --git a/Sources/NextcloudKit/NextcloudKit+E2EE.swift b/Sources/NextcloudKit/NextcloudKit+E2EE.swift index c669f293..725de6c6 100644 --- a/Sources/NextcloudKit/NextcloudKit+E2EE.swift +++ b/Sources/NextcloudKit/NextcloudKit+E2EE.swift @@ -55,26 +55,35 @@ public extension NextcloudKit { } } - /// Asynchronously marks or unmarks a folder as E2EE for the specified account. + /// Asynchronously marks or unmarks a folder for end-to-end encryption. /// - Parameters: /// - fileId: The ID of the folder. - /// - delete: Whether to remove (`true`) or set (`false`) the E2EE mark. - /// - account: The account performing the request. - /// - options: Optional request options (default is empty). - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple containing the account, raw response, and NKError. + /// - delete: Whether to remove the E2EE marker (true) or set it (false). + /// - account: The Nextcloud account used for the request. + /// - options: Request configuration and context. + /// - taskHandler: Optional monitoring of the underlying URLSessionTask. + /// - Returns: A tuple with account, responseData and NKError. func markE2EEFolderAsync(fileId: String, delete: Bool, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in markE2EEFolder(fileId: fileId, delete: delete, account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } @@ -142,23 +151,29 @@ public extension NextcloudKit { } } - /// Asynchronously locks or unlocks an E2EE folder for the given account using the specified method and token. + /// Asynchronously locks or unlocks a folder for end-to-end encryption. /// - Parameters: - /// - fileId: The ID of the folder to lock/unlock. - /// - e2eToken: Optional E2EE token to lock the folder (nil for unlock). - /// - e2eCounter: Optional counter value (used for token freshness). - /// - method: The HTTP method to use (e.g. "LOCK", "PUT"). - /// - account: The account performing the operation. - /// - options: Optional request options (default is empty). - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with the account, resulting E2EE token (if any), raw response, and NKError. + /// - fileId: The ID of the folder. + /// - e2eToken: Optional encryption token to include in the request. + /// - e2eCounter: Optional counter string to include. + /// - method: HTTP method ("LOCK" or "UNLOCK"). + /// - account: The Nextcloud account used for the request. + /// - options: Request configuration and context. + /// - taskHandler: Optional monitoring of the underlying URLSessionTask. + /// - Returns: A tuple with account, returned e2eToken, responseData and NKError. func lockE2EEFolderAsync(fileId: String, e2eToken: String?, e2eCounter: String?, method: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + e2eToken: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in lockE2EEFolder(fileId: fileId, e2eToken: e2eToken, @@ -166,8 +181,13 @@ public extension NextcloudKit { method: method, account: account, options: options, - taskHandler: taskHandler) { account, e2eToken, responseData, error in - continuation.resume(returning: (account, e2eToken, responseData, error)) + taskHandler: taskHandler) { account, token, responseData, error in + continuation.resume(returning: ( + account: account, + e2eToken: token, + responseData: responseData, + error: error + )) } } } @@ -227,26 +247,39 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves E2EE metadata and signature for a specific file. + /// Asynchronously fetches the E2EE metadata and signature for a given file. /// - Parameters: - /// - fileId: The ID of the file to retrieve metadata for. - /// - e2eToken: Optional E2EE token. - /// - account: The Nextcloud account requesting metadata. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the task. - /// - Returns: A tuple containing the account, E2EE metadata, signature, raw response, and NKError. + /// - fileId: The ID of the file. + /// - e2eToken: Optional encryption token to include. + /// - account: The Nextcloud account used for the request. + /// - options: Request configuration and context. + /// - taskHandler: Optional monitoring of the underlying URLSessionTask. + /// - Returns: A tuple with account, metadata, signature, response data and error result. func getE2EEMetadataAsync(fileId: String, e2eToken: String?, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + e2eMetadata: String?, + signature: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getE2EEMetadata(fileId: fileId, e2eToken: e2eToken, account: account, options: options, - taskHandler: taskHandler) { account, metadata, signature, response, error in - continuation.resume(returning: (account, metadata, signature, response, error)) + taskHandler: taskHandler) { account, metadata, signature, responseData, error in + continuation.resume(returning: ( + account: account, + e2eMetadata: metadata, + signature: signature, + responseData: responseData, + error: error + )) } } } @@ -316,17 +349,17 @@ public extension NextcloudKit { } } - /// Asynchronously uploads E2EE metadata for a file using a given method, token and optional signature. + /// Asynchronously stores E2EE metadata on the server for the specified file. /// - Parameters: - /// - fileId: The ID of the file to update metadata for. - /// - e2eToken: The E2EE token used for authentication. - /// - e2eMetadata: Optional encrypted metadata. - /// - signature: Optional cryptographic signature (added to header). - /// - method: HTTP method to use (e.g., "PUT"). - /// - account: The account performing the operation. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the session task. - /// - Returns: A tuple containing the account, stored metadata (if any), response, and NKError. + /// - fileId: The file identifier. + /// - e2eToken: The encryption token required for authorization. + /// - e2eMetadata: Optional metadata to store. + /// - signature: Optional digital signature to validate the metadata. + /// - method: The HTTP method to be used ("POST", "PUT"). + /// - account: The Nextcloud account to use. + /// - options: Optional request context and headers. + /// - taskHandler: Optional monitoring of the URLSessionTask. + /// - Returns: A tuple with account, metadata, response data, and error result. func putE2EEMetadataAsync(fileId: String, e2eToken: String, e2eMetadata: String?, @@ -334,7 +367,13 @@ public extension NextcloudKit { method: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + metadata: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, @@ -343,8 +382,13 @@ public extension NextcloudKit { method: method, account: account, options: options, - taskHandler: taskHandler) { account, metadata, response, error in - continuation.resume(returning: (account, metadata, response, error)) + taskHandler: taskHandler) { account, metadata, responseData, error in + continuation.resume(returning: ( + account: account, + metadata: metadata, + responseData: responseData, + error: error + )) } } } @@ -412,23 +456,38 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves the E2EE public certificate for the current or specified user. + /// Asynchronously retrieves the public E2EE certificate. + /// If `user` is provided, retrieves the certificate for that user. + /// If `user` is nil, retrieves the certificate for the current session user. /// - Parameters: - /// - user: Optional username to query (nil fetches current user). - /// - account: The Nextcloud account performing the request. - /// - options: Optional request options. - /// - taskHandler: Closure to access the session task. - /// - Returns: A tuple with account, current user's certificate, specified user's certificate (if any), response, and NKError. + /// - user: Optional user ID to fetch the certificate for. + /// - account: The account to use for the request. + /// - options: Optional request context (headers, queue, etc.). + /// - taskHandler: Optional observer for the URLSession task. + /// - Returns: A tuple containing account, current user’s certificate, optional target user’s certificate, response data, and an error if any. func getE2EECertificateAsync(user: String? = nil, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + certificate: String?, + certificateUser: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getE2EECertificate(user: user, account: account, options: options, - taskHandler: taskHandler) { account, certificate, certificateUser, response, error in - continuation.resume(returning: (account, certificate, certificateUser, response, error)) + taskHandler: taskHandler) { account, certificate, certificateUser, responseData, error in + continuation.resume(returning: ( + account: account, + certificate: certificate, + certificateUser: certificateUser, + responseData: responseData, + error: error + )) } } } @@ -478,20 +537,31 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves the private E2EE key for the given account. + /// Asynchronously retrieves the private E2EE key for the current user. /// - Parameters: - /// - account: The account requesting the private key. - /// - options: Optional request options. - /// - taskHandler: Closure to access the URLSessionTask. - /// - Returns: A tuple containing the account, private key (if any), response, and NKError. + /// - account: The Nextcloud account to authenticate the request. + /// - options: Optional request options (API version, headers, etc.). + /// - taskHandler: Optional callback for task creation. + /// - Returns: A tuple containing the account, the private key string (if available), the response, and the error. func getE2EEPrivateKeyAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + privateKey: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getE2EEPrivateKey(account: account, options: options, - taskHandler: taskHandler) { account, key, response, error in - continuation.resume(returning: (account, key, response, error)) + taskHandler: taskHandler) { account, privateKey, responseData, error in + continuation.resume(returning: ( + account: account, + privateKey: privateKey, + responseData: responseData, + error: error + )) } } } @@ -541,20 +611,31 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves the server’s E2EE public key for the specified account. + /// Asynchronously retrieves the server's public key for end-to-end encryption. /// - Parameters: - /// - account: The Nextcloud account performing the request. - /// - options: Optional request options. - /// - taskHandler: Closure to access the session task. - /// - Returns: A tuple with account, public key (if any), raw response, and NKError. + /// - account: The Nextcloud account used for the request. + /// - options: Optional request configuration (API version, headers, etc.). + /// - taskHandler: Optional monitoring of the underlying URLSessionTask. + /// - Returns: A tuple with account, publicKey string, AFDataResponse, and NKError. func getE2EEPublicKeyAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + publicKey: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getE2EEPublicKey(account: account, options: options, - taskHandler: taskHandler) { account, key, response, error in - continuation.resume(returning: (account, key, response, error)) + taskHandler: taskHandler) { account, publicKey, responseData, error in + continuation.resume(returning: ( + account: account, + publicKey: publicKey, + responseData: responseData, + error: error + )) } } } @@ -608,23 +689,34 @@ public extension NextcloudKit { } } - /// Asynchronously requests a signed E2EE public key from the server by submitting a CSR. + /// Asynchronously submits a CSR (Certificate Signing Request) to obtain a signed E2EE certificate. /// - Parameters: - /// - certificate: The certificate signing request (CSR) string. - /// - account: The Nextcloud account performing the request. - /// - options: Optional request options. - /// - taskHandler: Closure to access the session task. - /// - Returns: A tuple containing the account, signed public key (if any), response, and NKError. + /// - certificate: The CSR string to be signed. + /// - account: The Nextcloud account used for the request. + /// - options: Optional request configuration. + /// - taskHandler: Optional monitoring of the URLSessionTask. + /// - Returns: A tuple containing the account, signed certificate, response data, and error. func signE2EECertificateAsync(certificate: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + certificate: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in signE2EECertificate(certificate: certificate, account: account, options: options, - taskHandler: taskHandler) { account, signedCert, response, error in - continuation.resume(returning: (account, signedCert, response, error)) + taskHandler: taskHandler) { account, certificate, responseData, error in + continuation.resume(returning: ( + account: account, + certificate: certificate, + responseData: responseData, + error: error + )) } } } @@ -677,23 +769,34 @@ public extension NextcloudKit { } } - /// Asynchronously stores the given E2EE private key for the specified account. + /// Asynchronously stores the E2EE private key on the server for the specified account. /// - Parameters: - /// - privateKey: The PEM-formatted private key to store. + /// - privateKey: The private key to be saved. /// - account: The Nextcloud account performing the operation. - /// - options: Optional request options. - /// - taskHandler: Closure to access the session task. - /// - Returns: A tuple with account, echoed private key (if any), response, and NKError. + /// - options: Optional request configuration. + /// - taskHandler: Optional monitoring of the URLSessionTask. + /// - Returns: A tuple containing the account, echoed private key, response data, and error. func storeE2EEPrivateKeyAsync(privateKey: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + privateKey: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in storeE2EEPrivateKey(privateKey: privateKey, account: account, options: options, - taskHandler: taskHandler) { account, key, response, error in - continuation.resume(returning: (account, key, response, error)) + taskHandler: taskHandler) { account, privateKey, responseData, error in + continuation.resume(returning: ( + account: account, + privateKey: privateKey, + responseData: responseData, + error: error + )) } } } @@ -735,20 +838,29 @@ public extension NextcloudKit { } } - /// Asynchronously deletes the E2EE public certificate for the given account. + /// Asynchronously deletes the E2EE public certificate from the server for the given account. /// - Parameters: - /// - account: The Nextcloud account performing the deletion. - /// - options: Optional request options. - /// - taskHandler: Closure to access the session task. - /// - Returns: A tuple containing the account, response, and NKError. + /// - account: The Nextcloud account to remove the certificate from. + /// - options: Optional request configuration. + /// - taskHandler: Optional monitoring of the URLSessionTask. + /// - Returns: A tuple containing the account, response data, and error. func deleteE2EECertificateAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in deleteE2EECertificate(account: account, options: options, - taskHandler: taskHandler) { account, response, error in - continuation.resume(returning: (account, response, error)) + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } @@ -791,20 +903,29 @@ public extension NextcloudKit { } } - /// Asynchronously deletes the E2EE private key for the given account. + /// Asynchronously deletes the E2EE private key from the server for the specified account. /// - Parameters: - /// - account: The Nextcloud account performing the deletion. - /// - options: Optional request options. - /// - taskHandler: Closure to access the session task. - /// - Returns: A tuple containing the account, response, and NKError. + /// - account: The Nextcloud account for which the private key will be deleted. + /// - options: Optional request configuration and headers. + /// - taskHandler: Optional monitoring of the URLSessionTask. + /// - Returns: A tuple containing the account, response data, and error. func deleteE2EEPrivateKeyAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in deleteE2EEPrivateKey(account: account, options: options, - taskHandler: taskHandler) { account, response, error in - continuation.resume(returning: (account, response, error)) + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } diff --git a/Sources/NextcloudKit/NextcloudKit+FilesLock.swift b/Sources/NextcloudKit/NextcloudKit+FilesLock.swift index 4c977d1d..fd2267de 100644 --- a/Sources/NextcloudKit/NextcloudKit+FilesLock.swift +++ b/Sources/NextcloudKit/NextcloudKit+FilesLock.swift @@ -49,26 +49,35 @@ public extension NextcloudKit { } } - /// Asynchronously locks or unlocks a file depending on `shouldLock`. + /// Asynchronously locks or unlocks a file on the server via WebDAV. /// - Parameters: - /// - serverUrlFileName: Encoded file URL to act on. - /// - shouldLock: Whether to lock (`true`) or unlock (`false`) the file. - /// - account: The Nextcloud account performing the request. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the session task. - /// - Returns: A tuple containing the account, response, and NKError. + /// - serverUrlFileName: The server-side full URL of the file to lock or unlock. + /// - shouldLock: `true` to lock the file, `false` to unlock it. + /// - account: The Nextcloud account performing the action. + /// - options: Optional request configuration (headers, queue, etc.). + /// - taskHandler: Optional monitoring of the `URLSessionTask`. + /// - Returns: A tuple containing the account, the server response, and any error encountered. func lockUnlockFileAsync(serverUrlFileName: String, shouldLock: Bool, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in lockUnlockFile(serverUrlFileName: serverUrlFileName, shouldLock: shouldLock, account: account, options: options, - taskHandler: taskHandler) { account, response, error in - continuation.resume(returning: (account, response, error)) + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } diff --git a/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift b/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift index 3e5e02b6..49fc007f 100644 --- a/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift +++ b/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift @@ -56,20 +56,31 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves the list of group folders for the specified account. + /// Asynchronously retrieves the list of Groupfolders associated with the given account. /// - Parameters: - /// - account: The Nextcloud account requesting group folders. - /// - options: Optional request configuration. - /// - taskHandler: Optional closure to access the session task. - /// - Returns: A tuple containing the account, parsed list of group folders, raw response, and NKError. + /// - account: The Nextcloud account identifier. + /// - options: Optional request configuration (headers, queue, etc.). + /// - taskHandler: Optional monitoring of the `URLSessionTask`. + /// - Returns: A tuple containing the account, an optional array of `NKGroupfolders`, the response data, and an `NKError`. func getGroupfoldersAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKGroupfolders]?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + results: [NKGroupfolders]?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getGroupfolders(account: account, options: options, taskHandler: taskHandler) { account, results, responseData, error in - continuation.resume(returning: (account, results, responseData, error)) + continuation.resume(returning: ( + account: account, + results: results, + responseData: responseData, + error: error + )) } } } From a501927ed312d944e00fab4c748943da345c63c2 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 11:43:01 +0200 Subject: [PATCH 03/10] async Signed-off-by: Marino Faggiana --- Sources/NextcloudKit/NextcloudKit+API.swift | 553 +++++++++++++++----- 1 file changed, 426 insertions(+), 127 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+API.swift b/Sources/NextcloudKit/NextcloudKit+API.swift index 81fe93f1..97391a86 100644 --- a/Sources/NextcloudKit/NextcloudKit+API.swift +++ b/Sources/NextcloudKit/NextcloudKit+API.swift @@ -249,6 +249,13 @@ public extension NextcloudKit { case failure(NKError) } + // Retrieves the status information of a Nextcloud server. + // + // Parameters: + // - serverUrl: The base URL of the Nextcloud server (e.g., https://cloud.example.com). + // - options: Optional request configuration (e.g., headers, queue, etc.). + // - taskHandler: Callback for the underlying URLSessionTask. + // - completion: Returns the raw response and a `ServerInfoResult` containing server status information or an error. func getServerStatus(serverUrl: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -300,26 +307,42 @@ public extension NextcloudKit { } } - /// Asynchronously checks the server status and parses the result. + /// Asynchronously retrieves the status information of a Nextcloud server. /// - Parameters: - /// - serverUrl: The full URL of the server to check. - /// - options: Optional request options. - /// - taskHandler: Optional closure to get access to the underlying URLSessionTask. - /// - Returns: A tuple containing the response and the parsed `ServerInfoResult`. + /// - serverUrl: The server's base URL (e.g., https://cloud.example.com). + /// - options: Optional request configuration (e.g., version, queue, headers). + /// - taskHandler: Optional callback to monitor the underlying URLSessionTask. + /// - Returns: A tuple containing the AFDataResponse and the ServerInfoResult. func getServerStatusAsync(serverUrl: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (AFDataResponse?, ServerInfoResult) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + responseData: AFDataResponse?, + result: ServerInfoResult + ) { await withCheckedContinuation { continuation in getServerStatus(serverUrl: serverUrl, options: options, taskHandler: taskHandler) { responseData, result in - continuation.resume(returning: (responseData, result)) + continuation.resume(returning: ( + responseData: responseData, + result: result + )) } } } // MARK: - + // Downloads a file preview (thumbnail) from the specified URL for a given Nextcloud account. + // + // Parameters: + // - url: The full URL of the preview image to download. + // - account: The Nextcloud account used for the request. + // - etag: Optional entity tag used for cache validation. + // - options: Optional request configuration (e.g., headers, queue, version). + // - taskHandler: Callback for the underlying `URLSessionTask`. + // - completion: Returns the account, raw response data, and an `NKError` representing the result of the operation. func downloadPreview(url: URL, account: String, etag: String? = nil, @@ -349,30 +372,54 @@ public extension NextcloudKit { } } - /// Asynchronously downloads a preview for a given file URL. + /// Asynchronously downloads a preview image (e.g., thumbnail) from the provided URL. /// - Parameters: - /// - url: The full URL of the file preview to download. - /// - account: The account identifier. - /// - etag: Optional ETag for cache validation. - /// - options: Optional request options. - /// - taskHandler: Optional closure to handle the URLSessionTask. - /// - Returns: A tuple with the account, optional response, and NKError. + /// - url: The full URL of the preview image. + /// - account: The Nextcloud account making the request. + /// - etag: Optional ETag used to validate cache. + /// - options: Additional request options including version, headers, and queues. + /// - taskHandler: Optional handler for monitoring the URLSessionTask. + /// - Returns: A tuple containing the account identifier, response data, and an `NKError` object. func downloadPreviewAsync(url: URL, account: String, etag: String? = nil, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in downloadPreview(url: url, account: account, etag: etag, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } + // Downloads a preview (thumbnail) of a file with specified dimensions and parameters. + // + // Parameters: + // - fileId: The identifier of the file to generate a preview for. + // - width: The desired width of the preview image (default is 1024). + // - height: The desired height of the preview image (default is 1024). + // - etag: Optional entity tag used for caching validation. + // - crop: Indicates whether the image should be cropped (1 = true, default). + // - cropMode: The cropping mode (default is "cover"). + // - forceIcon: If set to 1, forces icon generation (default is 0). + // - mimeFallback: If set to 1, fallback to MIME-type icon if preview is unavailable (default is 0). + // - account: The Nextcloud account performing the operation. + // - options: Optional request configuration (headers, versioning, etc.). + // - taskHandler: Callback for the `URLSessionTask`. + // - completion: Returns the account, final width and height used, etag, response data, and any error encountered. func downloadPreview(fileId: String, width: Int = 1024, height: Int = 1024, @@ -468,6 +515,21 @@ public extension NextcloudKit { } } } + + // Downloads a preview (thumbnail) for a file located in the trashbin. + // + // Parameters: + // - fileId: The identifier of the trashed file. + // - width: Desired width of the preview image (default is 512). + // - height: Desired height of the preview image (default is 512). + // - crop: Indicates whether the image should be cropped (1 = true, default). + // - cropMode: The cropping mode (e.g., "cover"). + // - forceIcon: Forces use of the filetype icon instead of generating a preview (0 = false, default). + // - mimeFallback: Uses MIME-type fallback if preview is unavailable (0 = false, default). + // - account: The Nextcloud account making the request. + // - options: Request customization options (headers, queue, version, etc.). + // - taskHandler: Callback to inspect the underlying URLSessionTask. + // - completion: Returns the account, final width/height, preview response data, and NKError. func downloadTrashPreview(fileId: String, width: Int = 512, height: Int = 512, @@ -501,19 +563,19 @@ public extension NextcloudKit { } } - /// Asynchronously downloads a preview for a trashed file by ID with specified dimensions and flags. + /// Asynchronously downloads a preview of a trashed file using specified rendering options. /// - Parameters: - /// - fileId: The unique identifier of the trashed file. - /// - width: Desired width of the preview (default: 512). - /// - height: Desired height of the preview (default: 512). - /// - crop: Crop flag (default: 1). - /// - cropMode: Crop mode string (default: "cover"). - /// - forceIcon: Force icon flag (default: 0). - /// - mimeFallback: MIME fallback flag (default: 0). - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to get the URLSessionTask. - /// - Returns: A tuple with account, preview dimensions, response, and error. + /// - fileId: The identifier of the trashed file. + /// - width: Desired width of the preview image. + /// - height: Desired height of the preview image. + /// - crop: Whether to crop the image (1 = true, 0 = false). + /// - cropMode: Cropping mode to apply (e.g., "cover"). + /// - forceIcon: Whether to return an icon instead of a generated preview. + /// - mimeFallback: Whether to fallback to MIME-type icon if no preview is available. + /// - account: Account making the preview request. + /// - options: Optional request configuration (queue, headers, etc.). + /// - taskHandler: Handler to observe the URLSessionTask. + /// - Returns: A tuple with account, final width and height used, responseData, and NKError. func downloadTrashPreviewAsync(fileId: String, width: Int = 512, height: Int = 512, @@ -523,7 +585,14 @@ public extension NextcloudKit { mimeFallback: Int = 0, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, Int, Int, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + width: Int, + height: Int, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in downloadTrashPreview(fileId: fileId, width: width, @@ -534,12 +603,30 @@ public extension NextcloudKit { mimeFallback: mimeFallback, account: account, options: options, - taskHandler: taskHandler) { account, w, h, responseData, error in - continuation.resume(returning: (account, w, h, responseData, error)) + taskHandler: taskHandler) { account, resolvedWidth, resolvedHeight, responseData, error in + continuation.resume(returning: ( + account: account, + width: resolvedWidth, + height: resolvedHeight, + responseData: responseData, + error: error + )) } } } + // Downloads a user's avatar image from the server and optionally stores it locally. + // + // Parameters: + // - user: The user identifier for whom the avatar is requested. + // - fileNameLocalPath: The local file path where the avatar image will be saved. + // - sizeImage: The size of the avatar to request (in pixels). + // - avatarSizeRounded: If greater than 0, the avatar will be rounded to this size (in pixels). + // - etag: Optional ETag string to validate the cache. + // - account: The Nextcloud account performing the operation. + // - options: Optional request options (queue, headers, etc.). + // - taskHandler: Callback for the underlying URLSessionTask. + // - completion: Returns the account, avatar image, original image, ETag, response data, and NKError. func downloadAvatar(user: String, fileNameLocalPath: String, sizeImage: Int, @@ -643,15 +730,15 @@ public extension NextcloudKit { /// Asynchronously downloads an avatar image for the specified user. /// - Parameters: - /// - user: Username whose avatar is being requested. - /// - fileNameLocalPath: Local file path to cache or save the avatar. - /// - sizeImage: Size of the avatar image. - /// - avatarSizeRounded: Optional rounding size for avatar (default: 0). - /// - etag: Optional ETag for caching. - /// - account: Account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, processed avatar image, original image, ETag, response, and error. + /// - user: The username associated with the avatar. + /// - fileNameLocalPath: Path on disk to save the avatar. + /// - sizeImage: Desired size (in pixels) of the avatar image. + /// - avatarSizeRounded: Optional rounding for avatar (e.g., 128px). + /// - etag: Optional ETag for cache validation. + /// - account: The Nextcloud account to perform the download. + /// - options: Request configuration (queue, headers, etc.). + /// - taskHandler: Optional observer for the download task. + /// - Returns: A tuple with account, final avatar image, original image, resulting ETag, response and NKError. func downloadAvatarAsync(user: String, fileNameLocalPath: String, sizeImage: Int, @@ -659,7 +746,15 @@ public extension NextcloudKit { etag: String?, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, UIImage?, UIImage?, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + imageAvatar: UIImage?, + imageOriginal: UIImage?, + etag: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in downloadAvatar(user: user, fileNameLocalPath: fileNameLocalPath, @@ -669,11 +764,26 @@ public extension NextcloudKit { account: account, options: options, taskHandler: taskHandler) { account, imageAvatar, imageOriginal, etag, responseData, error in - continuation.resume(returning: (account, imageAvatar, imageOriginal, etag, responseData, error)) + continuation.resume(returning: ( + account: account, + imageAvatar: imageAvatar, + imageOriginal: imageOriginal, + etag: etag, + responseData: responseData, + error: error + )) } } } + // Downloads generic raw content from a given server URL using the specified account. + // + // Parameters: + // - serverUrl: The full URL string of the content to be downloaded. + // - account: The Nextcloud account to use for the request. + // - options: Optional configuration including headers, queue, and version. + // - taskHandler: Optional callback for monitoring the URLSessionTask. + // - completion: Returns the account, response data, and NKError representing the outcome. func downloadContent(serverUrl: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -699,29 +809,46 @@ public extension NextcloudKit { } } - /// Asynchronously downloads raw content from the specified server URL. + /// Asynchronously downloads raw content from a specified URL. /// - Parameters: - /// - serverUrl: The full URL to download content from. - /// - account: The account identifier associated with the request. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple with account identifier, response, and NKError. + /// - serverUrl: The direct URL of the content to download. + /// - account: The Nextcloud account used to authenticate the request. + /// - options: Request customization such as headers, queue, etc. + /// - taskHandler: Optional monitoring for the URLSession task. + /// - Returns: A tuple containing the account, response data, and resulting NKError. func downloadContentAsync(serverUrl: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in downloadContent(serverUrl: serverUrl, account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } // MARK: - + // Retrieves user profile metadata for a specific user in the Nextcloud instance. + // + // Parameters: + // - account: The account used to perform the request. + // - userId: The user identifier whose metadata is being retrieved. + // - options: Additional request configuration (e.g., headers, API version, execution queue). + // - taskHandler: Optional callback invoked with the underlying URLSessionTask. + // - completion: Returns the account, parsed user profile (`NKUserProfile`), response metadata, and any `NKError` encountered. func getUserMetadata(account: String, userId: String, options: NKRequestOptions = NKRequestOptions(), @@ -757,27 +884,45 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves user metadata for the specified account and user ID. + /// Asynchronously retrieves the metadata for a specific user profile. /// - Parameters: - /// - account: The account identifier. - /// - userId: The target user ID for metadata lookup. - /// - options: Optional request options. - /// - taskHandler: Optional closure to handle the `URLSessionTask`. - /// - Returns: A tuple with account, user profile metadata, response data, and error. + /// - account: The Nextcloud account making the request. + /// - userId: The ID of the user whose metadata is being requested. + /// - options: Optional request configuration (headers, version, etc.). + /// - taskHandler: Optional handler for observing the URLSessionTask. + /// - Returns: A tuple with the account, user profile, response data, and resulting error. func getUserMetadataAsync(account: String, userId: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKUserProfile?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + userProfile: NKUserProfile?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getUserMetadata(account: account, userId: userId, options: options, taskHandler: taskHandler) { account, userProfile, responseData, error in - continuation.resume(returning: (account, userProfile, responseData, error)) + continuation.resume(returning: ( + account: account, + userProfile: userProfile, + responseData: responseData, + error: error + )) } } } + // Fetches the metadata of the currently authenticated user. + // + // Parameters: + // - account: The Nextcloud account performing the request. + // - options: Additional request configuration (e.g., custom headers, API version, execution queue). + // - taskHandler: Optional callback invoked with the underlying URLSessionTask. + // - completion: Returns the account, parsed user profile (`NKUserProfile`), response metadata, and any `NKError` encountered. func getUserProfile(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -812,20 +957,31 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves the current user's profile for the given account. + /// Asynchronously fetches the profile metadata of the currently logged-in user. /// - Parameters: - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple with account, user profile, response data, and error. + /// - account: The Nextcloud account making the request. + /// - options: Optional request configuration (e.g. headers, version, etc.). + /// - taskHandler: Optional handler for observing the URLSessionTask. + /// - Returns: A tuple containing the account, user profile object, full response data, and any NKError. func getUserProfileAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, NKUserProfile?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + userProfile: NKUserProfile?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getUserProfile(account: account, options: options, taskHandler: taskHandler) { account, userProfile, responseData, error in - continuation.resume(returning: (account, userProfile, responseData, error)) + continuation.resume(returning: ( + account: account, + userProfile: userProfile, + responseData: responseData, + error: error + )) } } } @@ -876,6 +1032,15 @@ public extension NextcloudKit { } // MARK: - + // Checks the remote wipe status for a specific account and token. + // + // Parameters: + // - serverUrl: The base server URL to perform the request. + // - token: The authentication or wipe token to validate. + // - account: The Nextcloud account performing the request. + // - options: Optional configuration for the request (e.g., headers, version, queue). + // - taskHandler: Optional callback to observe the underlying URLSessionTask. + // - completion: Returns the account, wipe status (true if a wipe is required), raw response data, and NKError if any. func getRemoteWipeStatus(serverUrl: String, token: String, account: String, @@ -911,30 +1076,50 @@ public extension NextcloudKit { } } - /// Asynchronously checks if a remote wipe has been requested for the given account and token. + /// Asynchronously checks the remote wipe status for the given account and token. /// - Parameters: - /// - serverUrl: Full URL of the server. - /// - token: Unique token associated with the device/session. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, wipe flag, response data, and NKError. + /// - serverUrl: Base server URL used for the API request. + /// - token: Token used to query remote wipe status. + /// - account: Nextcloud account identifier. + /// - options: Request options such as headers, version, and dispatch queue. + /// - taskHandler: Callback for observing the URLSessionTask, if needed. + /// - Returns: A tuple with the account, wipe status flag, response data, and NKError. func getRemoteWipeStatusAsync(serverUrl: String, token: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, Bool, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + wipe: Bool, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getRemoteWipeStatus(serverUrl: serverUrl, token: token, account: account, options: options, taskHandler: taskHandler) { account, wipe, responseData, error in - continuation.resume(returning: (account, wipe, responseData, error)) + continuation.resume(returning: ( + account: account, + wipe: wipe, + responseData: responseData, + error: error + )) } } } + // Notifies the server that the remote wipe operation has been completed. + // + // Parameters: + // - serverUrl: The base server URL used to send the wipe completion notification. + // - token: The remote wipe token associated with the account. + // - account: The Nextcloud account that performed the wipe. + // - options: Optional configuration for request (headers, queue, version, etc.). + // - taskHandler: Callback for the underlying URLSessionTask if monitoring is needed. + // - completion: Returns the account, raw response data, and NKError. func setRemoteWipeCompletition(serverUrl: String, token: String, account: String, @@ -968,32 +1153,53 @@ public extension NextcloudKit { } } - /// Asynchronously notifies the server that the remote wipe process has been completed for the given token. + /// Asynchronously notifies the server that remote wipe has been completed for the given account and token. /// - Parameters: - /// - serverUrl: Full URL of the server. - /// - token: Unique token associated with the device/session. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, response data, and NKError. + /// - serverUrl: The base URL of the Nextcloud server. + /// - token: Remote wipe token associated with the account. + /// - account: Identifier of the Nextcloud account. + /// - options: Configuration object for headers, versioning, and dispatching. + /// - taskHandler: Optional observer for the created URLSessionTask. + /// - Returns: A tuple with account, raw response data, and NKError. func setRemoteWipeCompletitionAsync(serverUrl: String, token: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in setRemoteWipeCompletition(serverUrl: serverUrl, token: token, account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } // MARK: - + // Retrieves a list of activities for the current account. + // + // Parameters: + // - since: The timestamp (as Unix epoch) to fetch activities after. + // - limit: The maximum number of activities to retrieve. + // - objectId: Optional object ID to filter activities (e.g., file ID). + // - objectType: Optional object type to filter (e.g., "files"). + // - previews: Whether to include preview data for activities. + // - account: The Nextcloud account requesting the activity feed. + // - options: Optional request configuration (headers, queue, version, etc.). + // - taskHandler: Callback for the underlying URLSessionTask. + // - completion: Returns the account, array of NKActivity objects, the timestamp of the first known activity, last returned activity, raw response, and NKError. func getActivity(since: Int, limit: Int, objectId: String?, @@ -1090,17 +1296,18 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves user activity from the server. + /// Asynchronously fetches the list of activities from the server. + /// /// - Parameters: - /// - since: Timestamp (UNIX) after which to retrieve activities. + /// - since: Epoch timestamp for filtering activities (only newer ones will be returned). /// - limit: Maximum number of activities to retrieve. - /// - objectId: Optional filter for object ID. - /// - objectType: Optional filter for object type. - /// - previews: Whether to include previews in the response. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple with account, activity list, first known timestamp, last given timestamp, response data, and error. + /// - objectId: Optional object ID to filter (e.g., file or folder ID). + /// - objectType: Optional object type (e.g., "files"). + /// - previews: Whether to include thumbnails/previews for the activities. + /// - account: The Nextcloud account to use for authentication. + /// - options: Request customization including queue and headers. + /// - taskHandler: Optional callback for URLSession task monitoring. + /// - Returns: A tuple containing account, activities array, first known activity timestamp, last given activity timestamp, full response, and error. func getActivityAsync(since: Int, limit: Int, objectId: String?, @@ -1108,7 +1315,15 @@ public extension NextcloudKit { previews: Bool, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKActivity], Int, Int, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + activities: [NKActivity], + activityFirstKnown: Int, + activityLastGiven: Int, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getActivity(since: since, limit: limit, @@ -1118,13 +1333,27 @@ public extension NextcloudKit { account: account, options: options, taskHandler: taskHandler) { account, activities, firstKnown, lastGiven, responseData, error in - continuation.resume(returning: (account, activities, firstKnown, lastGiven, responseData, error)) + continuation.resume(returning: ( + account: account, + activities: activities, + activityFirstKnown: firstKnown, + activityLastGiven: lastGiven, + responseData: responseData, + error: error + )) } } } // MARK: - + // Retrieves all notifications associated with the current account. + // + // Parameters: + // - account: The Nextcloud account from which to retrieve notifications. + // - options: Optional request configuration (headers, queue, version, etc.). + // - taskHandler: Callback for the underlying URLSessionTask. + // - completion: Returns the account, list of NKNotifications, raw response data, and NKError. func getNotifications(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -1192,24 +1421,46 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves notifications for the specified account. + /// Asynchronously fetches notifications for the given account. + /// /// - Parameters: - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, notifications array, response data, and error. + /// - account: The Nextcloud account used to authenticate the request. + /// - options: Request configuration including queue and headers. + /// - taskHandler: Optional callback to monitor the URLSessionTask. + /// - Returns: A tuple containing the account, notifications array (optional), response data (optional), and the resulting NKError. func getNotificationsAsync(account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, [NKNotifications]?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + notifications: [NKNotifications]?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getNotifications(account: account, options: options, taskHandler: taskHandler) { account, notifications, responseData, error in - continuation.resume(returning: (account, notifications, responseData, error)) + continuation.resume(returning: ( + account: account, + notifications: notifications, + responseData: responseData, + error: error + )) } } } + // Performs an action on a specific notification by ID (e.g., mark as read or delete). + // + // Parameters: + // - serverUrl: Optional custom server URL override. If nil, the default account URL is used. + // - idNotification: The ID of the notification to act upon. + // - method: The HTTP method to use for the action (e.g., "DELETE" or "POST"). + // - account: The account associated with the notification. + // - options: Optional request configuration (headers, queue, version, etc.). + // - taskHandler: Callback for the underlying URLSessionTask. + // - completion: Returns the account, raw response data, and NKError result. func setNotification(serverUrl: String?, idNotification: Int, method: String, @@ -1247,21 +1498,27 @@ public extension NextcloudKit { } } - /// Asynchronously performs an action on a notification (e.g. mark as read, delete). + /// Asynchronously sets or deletes a notification by its ID. + /// /// - Parameters: - /// - serverUrl: Optional server URL (can be `nil` to use default). - /// - idNotification: The ID of the notification to act upon. - /// - method: HTTP method to use (e.g. "DELETE", "POST"). - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the `URLSessionTask`. - /// - Returns: A tuple with account, response data, and NKError. + /// - serverUrl: Optional server URL override for the request. + /// - idNotification: The unique identifier of the notification to process. + /// - method: HTTP method to execute ("POST", "DELETE", etc.). + /// - account: The account context for the operation. + /// - options: Request options including queue, headers, etc. + /// - taskHandler: Optional callback to monitor the task. + /// - Returns: A tuple containing the account, response data, and NKError. func setNotificationAsync(serverUrl: String?, idNotification: Int, method: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in setNotification(serverUrl: serverUrl, idNotification: idNotification, @@ -1269,13 +1526,25 @@ public extension NextcloudKit { account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } // MARK: - + // Fetches a direct download URL for a given file ID. + // + // Parameters: + // - fileId: The unique identifier of the file to download. + // - account: The account used to perform the request. + // - options: Optional request configuration (headers, queue, version, etc.). + // - taskHandler: Callback triggered with the URLSessionTask created. + // - completion: Returns the account, the direct download URL (if available), raw response data, and NKError result. func getDirectDownload(fileId: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -1309,29 +1578,49 @@ public extension NextcloudKit { } } - /// Asynchronously retrieves the direct download URL for a given file ID. + /// Asynchronously retrieves the direct download link for a specified file. + /// /// - Parameters: - /// - fileId: The unique identifier of the file. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, direct download URL, response, and error. + /// - fileId: The file identifier for which to get the direct download URL. + /// - account: The account to use for the request. + /// - options: Optional request settings (e.g., headers, versioning). + /// - taskHandler: Callback to observe the URLSessionTask. + /// - Returns: A tuple containing the account, the direct download URL, the raw response, and NKError. func getDirectDownloadAsync(fileId: String, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, String?, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + url: String?, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in getDirectDownload(fileId: fileId, account: account, options: options, taskHandler: taskHandler) { account, url, responseData, error in - continuation.resume(returning: (account, url, responseData, error)) + continuation.resume(returning: ( + account: account, + url: url, + responseData: responseData, + error: error + )) } } } // MARK: - + // Sends client diagnostics data to the remote server. + // + // Parameters: + // - data: The raw diagnostic payload to be sent. + // - account: The account used for the request. + // - options: Optional request configuration (e.g., headers, queue, version). + // - taskHandler: Callback triggered with the underlying URLSessionTask. + // - completion: Returns the account, raw response data, and NKError result. func sendClientDiagnosticsRemoteOperation(data: Data, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -1368,23 +1657,33 @@ public extension NextcloudKit { } } - /// Asynchronously sends client diagnostics data to the server. + /// Asynchronously sends diagnostic data to the server. + /// /// - Parameters: - /// - data: Diagnostic payload to be sent. - /// - account: The account identifier. - /// - options: Optional request options. - /// - taskHandler: Optional closure to access the URLSessionTask. - /// - Returns: A tuple with account, response data, and NKError. + /// - data: Raw diagnostic information to upload. + /// - account: The account associated with the request. + /// - options: Optional request configuration parameters. + /// - taskHandler: Callback for tracking the associated URLSessionTask. + /// - Returns: A tuple containing the account, the response data, and the NKError result. func sendClientDiagnosticsRemoteOperationAsync(data: Data, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (String, AFDataResponse?, NKError) { + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in sendClientDiagnosticsRemoteOperation(data: data, account: account, options: options, taskHandler: taskHandler) { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } } } From 229337dbdb547dd399e846b57e54b96e122d314a Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 11:50:57 +0200 Subject: [PATCH 04/10] async Signed-off-by: Marino Faggiana --- .../NextcloudKit/NextcloudKit+Livephoto.swift | 42 ++- Sources/NextcloudKit/NextcloudKit+Login.swift | 140 ++++++++++ .../NextcloudKit/NextcloudKit+NCText.swift | 175 +++++++++++- .../NextcloudKit+PushNotification.swift | 261 ++++++++++++------ 4 files changed, 514 insertions(+), 104 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+Livephoto.swift b/Sources/NextcloudKit/NextcloudKit+Livephoto.swift index 313f3bc4..c77a965e 100644 --- a/Sources/NextcloudKit/NextcloudKit+Livephoto.swift +++ b/Sources/NextcloudKit/NextcloudKit+Livephoto.swift @@ -6,6 +6,15 @@ import Foundation import Alamofire public extension NextcloudKit { + // Associates a Live Photo video file with a photo on the server. + // + // Parameters: + // - serverUrlfileNamePath: The full server path to the original photo. + // - livePhotoFile: The local path to the Live Photo video file (.mov). + // - account: The account performing the operation. + // - options: Optional request configuration (e.g., headers, queue, version). + // - taskHandler: Callback for tracking the underlying URLSessionTask. + // - completion: Returns the account, raw response data, and NKError result. func setLivephoto(serverUrlfileNamePath: String, livePhotoFile: String, account: String, @@ -46,14 +55,37 @@ public extension NextcloudKit { } } + /// Asynchronously attaches a Live Photo video file to an existing image on the server. + /// + /// - Parameters: + /// - serverUrlfileNamePath: The full server-side path of the target image. + /// - livePhotoFile: Local file path of the Live Photo (.mov). + /// - account: The Nextcloud account to use for the request. + /// - options: Optional request context and headers. + /// - taskHandler: Optional callback to observe the URLSessionTask. + /// - Returns: A tuple with the account, response data, and NKError result. func setLivephotoAsync(serverUrlfileNamePath: String, livePhotoFile: String, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.setLivephoto(serverUrlfileNamePath: serverUrlfileNamePath, livePhotoFile: livePhotoFile, account: account, options: options) { account, responseData, error in - continuation.resume(returning: (account: account, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + setLivephoto(serverUrlfileNamePath: serverUrlfileNamePath, + livePhotoFile: livePhotoFile, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } - }) + } } } diff --git a/Sources/NextcloudKit/NextcloudKit+Login.swift b/Sources/NextcloudKit/NextcloudKit+Login.swift index 575111f7..8721738c 100644 --- a/Sources/NextcloudKit/NextcloudKit+Login.swift +++ b/Sources/NextcloudKit/NextcloudKit+Login.swift @@ -8,6 +8,17 @@ import SwiftyJSON public extension NextcloudKit { // MARK: - App Password + + // Retrieves an app password (token) for the given user credentials and server URL. + // + // Parameters: + // - url: The base server URL (e.g., https://cloud.example.com). + // - user: The username for authentication. + // - password: The user's password. + // - userAgent: Optional user-agent string to include in the request. + // - options: Optional request configuration (headers, queue, etc.). + // - taskHandler: Callback for observing the underlying URLSessionTask. + // - completion: Returns the token string (if any), raw response data, and NKError result. func getAppPassword(url: String, user: String, password: String, @@ -47,6 +58,54 @@ public extension NextcloudKit { } } + /// Asynchronously fetches an app password for the provided user credentials. + /// + /// - Parameters: + /// - url: The base URL of the Nextcloud server. + /// - user: The user login name. + /// - password: The user’s password. + /// - userAgent: Optional custom user agent for the request. + /// - options: Optional request configuration. + /// - taskHandler: Callback to observe the task, if needed. + /// - Returns: A tuple containing the token, response data, and error result. + func getAppPasswordAsync(url: String, + user: String, + password: String, + userAgent: String? = nil, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + token: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getAppPassword(url: url, + user: user, + password: password, + userAgent: userAgent, + options: options, + taskHandler: taskHandler) { token, responseData, error in + continuation.resume(returning: ( + token: token, + responseData: responseData, + error: error + )) + } + } + } + + // Deletes the app password (token) for a specific account using basic authentication. + // + // Parameters: + // - serverUrl: The full server URL (e.g., https://cloud.example.com). + // - username: The username associated with the app password. + // - password: The password or app password used for authentication. + // - userAgent: Optional user-agent string for the request. + // - account: The logical account identifier used in the app. + // - options: Optional request configuration (headers, queues, etc.). + // - taskHandler: Callback to observe the underlying URLSessionTask. + // - completion: Returns the raw response and a possible NKError result. func deleteAppPassword(serverUrl: String, username: String, password: String, @@ -87,6 +146,44 @@ public extension NextcloudKit { } } + /// Asynchronously deletes the current app password/token from the server. + /// + /// - Parameters: + /// - serverUrl: Full URL of the Nextcloud server. + /// - username: The user identifier. + /// - password: The password or token used for deletion authorization. + /// - userAgent: Optional string to customize the User-Agent header. + /// - account: Logical account identifier. + /// - options: Configuration options for the request. + /// - taskHandler: Optional callback for observing the URLSessionTask. + /// - Returns: A tuple containing the response and a possible error. + func deleteAppPasswordAsync(serverUrl: String, + username: String, + password: String, + userAgent: String? = nil, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + deleteAppPassword(serverUrl: serverUrl, + username: username, + password: password, + userAgent: userAgent, + account: account, + options: options, + taskHandler: taskHandler) { responseData, error in + continuation.resume(returning: ( + responseData: responseData, + error: error + )) + } + } + } + // MARK: - Login Flow V2 /// @@ -155,6 +252,14 @@ public extension NextcloudKit { } } + // Polls the login flow V2 endpoint to retrieve login credentials (OAuth-style). + // + // Parameters: + // - token: The login flow token to poll for. + // - endpoint: The base URL endpoint (e.g., https://cloud.example.com). + // - options: Optional request configuration (version, headers, queues, etc.). + // - taskHandler: Callback to observe the underlying URLSessionTask. + // - completion: Returns the discovered server URL, loginName, appPassword, the raw response data, and any NKError. func getLoginFlowV2Poll(token: String, endpoint: String, options: NKRequestOptions = NKRequestOptions(), @@ -187,4 +292,39 @@ public extension NextcloudKit { } } } + + /// Asynchronously polls the login flow V2 endpoint for login credentials. + /// + /// - Parameters: + /// - token: The token used in the login flow process. + /// - endpoint: Full base endpoint URL to call the polling API. + /// - options: Request configuration such as version, headers, queue. + /// - taskHandler: Optional callback to observe the underlying URLSessionTask. + /// - Returns: A tuple with server URL, login name, app password, raw response, and NKError. + func getLoginFlowV2PollAsync(token: String, + endpoint: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + server: String?, + loginName: String?, + appPassword: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getLoginFlowV2Poll(token: token, + endpoint: endpoint, + options: options, + taskHandler: taskHandler) { server, loginName, appPassword, responseData, error in + continuation.resume(returning: ( + server: server, + loginName: loginName, + appPassword: appPassword, + responseData: responseData, + error: error + )) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+NCText.swift b/Sources/NextcloudKit/NextcloudKit+NCText.swift index 2f8426fd..1925e54f 100644 --- a/Sources/NextcloudKit/NextcloudKit+NCText.swift +++ b/Sources/NextcloudKit/NextcloudKit+NCText.swift @@ -7,6 +7,13 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Retrieves the list of editors and creators for collaborative text editing. + // + // Parameters: + // - account: The account from which to fetch the editor details. + // - options: Optional request configuration such as headers, queue, or API version. + // - taskHandler: Callback to track the underlying URLSessionTask. + // - completion: Returns the account, array of editors, array of creators, the raw response data, and NKError. func textObtainEditorDetails(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -50,18 +57,48 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves details of users involved in collaborative editing (editors and creators). + /// + /// - Parameters: + /// - account: The Nextcloud account from which the information is retrieved. + /// - options: Configuration for the request, including headers and execution queue. + /// - taskHandler: Optional callback to monitor the underlying network task. + /// - Returns: A tuple containing the account, list of editors, list of creators, raw response, and NKError. func textObtainEditorDetailsAsync(account: String, - options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (account: String, editors: [NKEditorDetailsEditor]?, creators: [NKEditorDetailsCreator]?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation { continuation in + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + editors: [NKEditorDetailsEditor]?, + creators: [NKEditorDetailsCreator]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in textObtainEditorDetails(account: account, options: options, taskHandler: taskHandler) { account, editors, creators, responseData, error in - continuation.resume(returning: (account, editors, creators, responseData, error)) + continuation.resume(returning: ( + account: account, + editors: editors, + creators: creators, + responseData: responseData, + error: error + )) } } } + // Opens a file using the specified text editor and returns the access URL. + // + // Parameters: + // - fileNamePath: The path of the file to open on the server. + // - fileId: Optional file identifier used to reference the file more precisely. + // - editor: The identifier of the text editor to use. + // - account: The account initiating the file open request. + // - options: Optional configuration for the request (headers, API version, etc.). + // - taskHandler: Callback triggered with the underlying URLSessionTask. + // - completion: Returns the account, the resulting file editor URL, raw response data, and an NKError. func textOpenFile(fileNamePath: String, fileId: String? = nil, editor: String, @@ -98,6 +135,52 @@ public extension NextcloudKit { } } + /// Asynchronously opens a file in the specified text editor and retrieves the access URL. + /// + /// - Parameters: + /// - fileNamePath: Path of the file on the server. + /// - fileId: Optional file ID to assist in uniquely identifying the file. + /// - editor: Identifier of the text editor to be used. + /// - account: Account performing the operation. + /// - options: Configuration options for the request. + /// - taskHandler: Optional monitoring for the underlying URLSessionTask. + /// - Returns: A tuple containing the account, resulting URL, raw response data, and NKError. + func textOpenFileAsync(fileNamePath: String, + fileId: String? = nil, + editor: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + url: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + textOpenFile(fileNamePath: fileNamePath, + fileId: fileId, + editor: editor, + account: account, + options: options, + taskHandler: taskHandler) { account, url, responseData, error in + continuation.resume(returning: ( + account: account, + url: url, + responseData: responseData, + error: error + )) + } + } + } + + // Retrieves the list of available editor templates for the given account. + // + // Parameters: + // - account: The account requesting the list of templates. + // - options: Optional request configuration such as headers, queue, or API version. + // - taskHandler: Callback triggered with the underlying URLSessionTask. + // - completion: Returns the account, an optional array of NKEditorTemplate, the raw response, and an NKError. func textGetListOfTemplates(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -137,15 +220,47 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves a list of editor templates for the specified account. + /// + /// - Parameters: + /// - account: The account requesting the templates. + /// - options: Request configuration options (queue, headers, etc.). + /// - taskHandler: Optional callback to monitor the underlying URLSessionTask. + /// - Returns: A tuple containing the account, list of templates (if any), raw response, and error information. func textGetListOfTemplatesAsync(account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, templates: [NKEditorTemplate]?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - textGetListOfTemplates(account: account) { account, templates, responseData, error in - continuation.resume(returning: (account: account, templates: templates, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + templates: [NKEditorTemplate]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + textGetListOfTemplates(account: account, + options: options, + taskHandler: taskHandler) { account, templates, responseData, error in + continuation.resume(returning: ( + account: account, + templates: templates, + responseData: responseData, + error: error + )) } - }) + } } + // Creates a new file using a specific editor, creator, and template. + // + // Parameters: + // - fileNamePath: The full destination path where the new file will be created. + // - editorId: The identifier of the editor to use (e.g., "richdocuments"). + // - creatorId: The identifier of the creator (e.g., "document", "spreadsheet"). + // - templateId: The identifier of the template to use for this file. + // - account: The account performing the operation. + // - options: Optional request configuration (headers, queue, version, etc.). + // - taskHandler: Callback to monitor the underlying URLSessionTask. + // - completion: Returns the account, the resulting file URL (if any), the raw response, and NKError. func textCreateFile(fileNamePath: String, editorId: String, creatorId: String, @@ -184,4 +299,46 @@ public extension NextcloudKit { } } } + + /// Asynchronously creates a new file from a template using the specified editor and creator. + /// + /// - Parameters: + /// - fileNamePath: Destination path where the new file will be saved. + /// - editorId: The editor's unique identifier (e.g., "richdocuments"). + /// - creatorId: The creator's identifier (e.g., "document"). + /// - templateId: The template to use for the new file. + /// - account: The Nextcloud account used for the operation. + /// - options: Optional request settings (e.g., headers, queue, etc.). + /// - taskHandler: Optional callback to observe the URLSessionTask. + /// - Returns: A tuple containing the account, the resulting file URL, raw response data, and NKError. + func textCreateFileAsync(fileNamePath: String, + editorId: String, + creatorId: String, + templateId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + url: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + textCreateFile(fileNamePath: fileNamePath, + editorId: editorId, + creatorId: creatorId, + templateId: templateId, + account: account, + options: options, + taskHandler: taskHandler) { account, url, responseData, error in + continuation.resume(returning: ( + account: account, + url: url, + responseData: responseData, + error: error + )) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+PushNotification.swift b/Sources/NextcloudKit/NextcloudKit+PushNotification.swift index 5435b31a..5338b679 100644 --- a/Sources/NextcloudKit/NextcloudKit+PushNotification.swift +++ b/Sources/NextcloudKit/NextcloudKit+PushNotification.swift @@ -7,6 +7,17 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Subscribes the current device to push notifications. + // + // Parameters: + // - serverUrl: The base server URL for the Nextcloud instance. + // - pushTokenHash: Hashed device push token, used for identification. + // - devicePublicKey: The public key of the device for encryption/authentication. + // - proxyServerUrl: The URL of the proxy push server. + // - account: The Nextcloud account performing the subscription. + // - options: Optional request configuration (headers, version, etc.). + // - taskHandler: Callback to monitor the `URLSessionTask`. + // - completion: Returns the account, device identifier, push signature, public key, response data, and NKError. func subscribingPushNotification(serverUrl: String, pushTokenHash: String, devicePublicKey: String, @@ -50,13 +61,24 @@ public extension NextcloudKit { } } - func subscribingPushNotificationAsync( - serverUrl: String, - pushTokenHash: String, - devicePublicKey: String, - proxyServerUrl: String, - account: String, - options: NKRequestOptions = NKRequestOptions() + /// Asynchronously subscribes a device to push notifications on the server. + /// + /// - Parameters: + /// - serverUrl: Base URL of the Nextcloud server. + /// - pushTokenHash: Hashed representation of the device push token. + /// - devicePublicKey: Public key for the device used for secure messaging. + /// - proxyServerUrl: URL to the push proxy server. + /// - account: The Nextcloud account performing the request. + /// - options: Request customization (e.g., queue, headers). + /// - taskHandler: Optional URLSession task observer. + /// - Returns: A tuple containing the account, device identifier, signature, public key, response data, and NKError. + func subscribingPushNotificationAsync(serverUrl: String, + pushTokenHash: String, + devicePublicKey: String, + proxyServerUrl: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } ) async -> ( account: String, deviceIdentifier: String?, @@ -66,30 +88,33 @@ public extension NextcloudKit { error: NKError ) { await withCheckedContinuation { continuation in - subscribingPushNotification( - serverUrl: serverUrl, - pushTokenHash: pushTokenHash, - devicePublicKey: devicePublicKey, - proxyServerUrl: proxyServerUrl, - account: account, - options: options, - taskHandler: { _ in }, - completion: { account, deviceIdentifier, signature, publicKey, responseData, error in - continuation.resume( - returning: ( - account, - deviceIdentifier, - signature, - publicKey, - responseData, - error - ) - ) - } - ) + subscribingPushNotification(serverUrl: serverUrl, + pushTokenHash: pushTokenHash, + devicePublicKey: devicePublicKey, + proxyServerUrl: proxyServerUrl, + account: account, + options: options, + taskHandler: taskHandler) { account, deviceIdentifier, signature, publicKey, responseData, error in + continuation.resume(returning: ( + account: account, + deviceIdentifier: deviceIdentifier, + signature: signature, + publicKey: publicKey, + responseData: responseData, + error: error + )) + } } } + // Unsubscribes the current device from push notifications. + // + // Parameters: + // - serverUrl: The base server URL of the Nextcloud instance. + // - account: The Nextcloud account performing the unsubscription. + // - options: Optional request configuration (headers, queue, etc.). + // - taskHandler: Callback to monitor the `URLSessionTask`. + // - completion: Returns the account, raw response data, and NKError. func unsubscribingPushNotification(serverUrl: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -116,34 +141,49 @@ public extension NextcloudKit { } } - func unsubscribingPushNotificationAsync( - serverUrl: String, - account: String, - options: NKRequestOptions = NKRequestOptions() + /// Asynchronously unsubscribes a device from push notifications. + /// + /// - Parameters: + /// - serverUrl: Base URL of the Nextcloud server. + /// - account: The Nextcloud account performing the request. + /// - options: Request customization (e.g., headers, queue, version). + /// - taskHandler: Optional observer for the underlying `URLSessionTask`. + /// - Returns: A tuple containing the account, response data, and NKError. + func unsubscribingPushNotificationAsync(serverUrl: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } ) async -> ( account: String, responseData: AFDataResponse?, error: NKError ) { await withCheckedContinuation { continuation in - unsubscribingPushNotification( - serverUrl: serverUrl, - account: account, - options: options, - taskHandler: { _ in }, - completion: { account, responseData, error in - continuation.resume( - returning: ( - account, - responseData, - error - ) - ) - } - ) + unsubscribingPushNotification(serverUrl: serverUrl, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) + } } } + // Subscribes a device to the push proxy server for receiving push notifications. + // + // Parameters: + // - proxyServerUrl: The URL of the push proxy server. + // - pushToken: The token representing the push notification subscription. + // - deviceIdentifier: A unique identifier for the device. + // - signature: A signature to validate the subscription. + // - publicKey: The public key associated with the device. + // - account: The Nextcloud account performing the subscription. + // - options: Optional request customization. + // - taskHandler: Callback for tracking the underlying URLSessionTask. + // - completion: Returns the account, raw response data, and NKError. func subscribingPushProxy(proxyServerUrl: String, pushToken: String, deviceIdentifier: String, @@ -181,33 +221,60 @@ public extension NextcloudKit { } } - func subscribingPushProxyAsync( - proxyServerUrl: String, - pushToken: String, - deviceIdentifier: String, - signature: String, - publicKey: String, + /// Asynchronously subscribes a device to the push proxy for push notifications. + /// + /// - Parameters: + /// - proxyServerUrl: URL of the push proxy server. + /// - pushToken: Token representing the device's push subscription. + /// - deviceIdentifier: Unique identifier for the device. + /// - signature: Digital signature for verification. + /// - publicKey: Public key associated with the subscription. + /// - account: The Nextcloud account performing the operation. + /// - options: Request customization (headers, queue, etc.). + /// - taskHandler: Callback for monitoring the URLSessionTask. + /// - Returns: A tuple containing the account, response data, and NKError. + func subscribingPushProxyAsync(proxyServerUrl: String, + pushToken: String, + deviceIdentifier: String, + signature: String, + publicKey: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, - responseData: AFDataResponse?, - error: NKError) { + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in - subscribingPushProxy( - proxyServerUrl: proxyServerUrl, - pushToken: pushToken, - deviceIdentifier: deviceIdentifier, - signature: signature, - publicKey: publicKey, - account: account, - options: options, - taskHandler: { _ in }, - completion: { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) - } - ) + subscribingPushProxy(proxyServerUrl: proxyServerUrl, + pushToken: pushToken, + deviceIdentifier: deviceIdentifier, + signature: signature, + publicKey: publicKey, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) + } } } + // Unsubscribes a device from the push proxy server. + // + // Parameters: + // - proxyServerUrl: The URL of the push proxy server. + // - deviceIdentifier: A unique identifier for the device. + // - signature: A cryptographic signature to authenticate the request. + // - publicKey: The public key associated with the device. + // - account: The Nextcloud account initiating the request. + // - options: Optional configuration for the request (queue, headers, version, etc.). + // - taskHandler: Callback triggered when the underlying URLSessionTask is created. + // - completion: Completion handler with account, response data, and NKError result. func unsubscribingPushProxy(proxyServerUrl: String, deviceIdentifier: String, signature: String, @@ -243,29 +310,43 @@ public extension NextcloudKit { } } - func unsubscribingPushProxyAsync( - proxyServerUrl: String, - deviceIdentifier: String, - signature: String, - publicKey: String, + /// Asynchronously unsubscribes a device from the push proxy server. + /// + /// - Parameters: + /// - proxyServerUrl: The URL of the push proxy server. + /// - deviceIdentifier: A unique identifier for the device. + /// - signature: A cryptographic signature for validation. + /// - publicKey: Public key used for authentication. + /// - account: The Nextcloud account performing the unsubscription. + /// - options: Optional configuration for headers, queue, etc. + /// - taskHandler: Optional callback for monitoring the URLSessionTask. + /// - Returns: A tuple with the account, the raw AF response data, and an NKError result. + func unsubscribingPushProxyAsync(proxyServerUrl: String, + deviceIdentifier: String, + signature: String, + publicKey: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( account: String, - options: NKRequestOptions = NKRequestOptions() - ) async -> (account: String, - responseData: AFDataResponse?, - error: NKError) { + responseData: AFDataResponse?, + error: NKError + ) { await withCheckedContinuation { continuation in - unsubscribingPushProxy( - proxyServerUrl: proxyServerUrl, - deviceIdentifier: deviceIdentifier, - signature: signature, - publicKey: publicKey, - account: account, - options: options, - taskHandler: { _ in }, - completion: { account, responseData, error in - continuation.resume(returning: (account, responseData, error)) - } - ) + unsubscribingPushProxy(proxyServerUrl: proxyServerUrl, + deviceIdentifier: deviceIdentifier, + signature: signature, + publicKey: publicKey, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) + } } } } From 628f44bb0c034f714803609f9e69fd6a510cf7ee Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 11:56:39 +0200 Subject: [PATCH 05/10] async Signed-off-by: Marino Faggiana --- .../NextcloudKit+RecommendedFiles.swift | 43 ++++- .../NextcloudKit+Richdocuments.swift | 169 +++++++++++++++++- .../NextcloudKit/NextcloudKit+Search.swift | 107 ++++++++--- 3 files changed, 280 insertions(+), 39 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+RecommendedFiles.swift b/Sources/NextcloudKit/NextcloudKit+RecommendedFiles.swift index 1935cde8..4e27a69c 100644 --- a/Sources/NextcloudKit/NextcloudKit+RecommendedFiles.swift +++ b/Sources/NextcloudKit/NextcloudKit+RecommendedFiles.swift @@ -7,6 +7,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Retrieves a list of recommended files from the server. + // + // Parameters: + // - account: The Nextcloud account used to perform the request. + // - options: Optional configuration for headers, queue, versioning, etc. + // - request: Optional callback to observe or manipulate the underlying DataRequest. + // - taskHandler: Callback triggered when the URLSessionTask is created. + // - completion: Completion handler returning the account, the list of recommendations, + // the raw response data, and an NKError result. func getRecommendedFiles(account: String, options: NKRequestOptions = NKRequestOptions(), request: @escaping (DataRequest?) -> Void = { _ in }, @@ -48,12 +57,36 @@ public extension NextcloudKit { options.queue.async { request(tosRequest) } } + /// Asynchronously fetches a list of recommended files for the given account. + /// + /// - Parameters: + /// - account: The Nextcloud account requesting the recommendations. + /// - options: Optional configuration for queue, headers, etc. + /// - request: Optional callback to capture the DataRequest object. + /// - taskHandler: Optional handler for the URLSessionTask. + /// - Returns: A tuple containing the account, list of recommended files, raw response data, and NKError result. func getRecommendedFilesAsync(account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, recommendations: [NKRecommendation]?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.getRecommendedFiles(account: account, options: options) { account, recommendations, responseData, error in - continuation.resume(returning: (account: account, recommendations: recommendations, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + request: @escaping (DataRequest?) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + recommendations: [NKRecommendation]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getRecommendedFiles(account: account, + options: options, + request: request, + taskHandler: taskHandler) { account, recommendations, responseData, error in + continuation.resume(returning: ( + account: account, + recommendations: recommendations, + responseData: responseData, + error: error + )) } - }) + } } } diff --git a/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift b/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift index 58005003..b3dc161d 100644 --- a/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift +++ b/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift @@ -7,6 +7,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Requests a URL for editing or viewing a file via the Richdocuments (Collabora/OnlyOffice) app. + // + // Parameters: + // - fileID: The unique identifier of the file for which the document URL is requested. + // - account: The Nextcloud account performing the request. + // - options: Optional configuration such as custom headers, queue, or API version. + // - taskHandler: Callback invoked when the underlying URLSessionTask is created. + // - completion: Completion handler returning the account, document URL (if available), + // the raw HTTP response, and an NKError object. func createUrlRichdocuments(fileID: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -40,6 +49,47 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves the URL for opening a file in Richdocuments (e.g., Collabora or OnlyOffice). + /// + /// - Parameters: + /// - fileID: The identifier of the target file. + /// - account: The Nextcloud account used for the operation. + /// - options: Request configuration (headers, queue, version, etc.). + /// - taskHandler: Optional handler to observe the URLSessionTask. + /// - Returns: A tuple containing the account, the richdocument URL (if any), the raw response data, and any NKError. + func createUrlRichdocumentsAsync(fileID: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + url: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + createUrlRichdocuments(fileID: fileID, + account: account, + options: options, + taskHandler: taskHandler) { account, url, responseData, error in + continuation.resume(returning: ( + account: account, + url: url, + responseData: responseData, + error: error + )) + } + } + } + + // Retrieves the list of Richdocuments templates of a given type (e.g., "document", "spreadsheet"). + // + // Parameters: + // - typeTemplate: The type of template to retrieve (e.g., "document", "presentation"). + // - account: The Nextcloud account performing the request. + // - options: Optional configuration (headers, queue, API version, etc.). + // - taskHandler: Callback invoked when the underlying URLSessionTask is created. + // - completion: Completion handler returning the account, array of templates, response data, and NKError. func getTemplatesRichdocuments(typeTemplate: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -84,16 +134,48 @@ public extension NextcloudKit { } } + /// Asynchronously fetches Richdocuments templates filtered by type. + /// + /// - Parameters: + /// - typeTemplate: The type of template to retrieve (e.g., "document"). + /// - account: The Nextcloud account for which templates are requested. + /// - options: Optional request configuration. + /// - taskHandler: Optional handler to observe the `URLSessionTask`. + /// - Returns: A tuple containing the account, array of templates, raw response data, and any NKError. func getTemplatesRichdocumentsAsync(typeTemplate: String, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, templates: [NKRichdocumentsTemplate]?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.getTemplatesRichdocuments(typeTemplate: typeTemplate, account: account, options: options) { account, templates, responseData, error in - continuation.resume(returning: (account: account, templates: templates, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + templates: [NKRichdocumentsTemplate]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getTemplatesRichdocuments(typeTemplate: typeTemplate, + account: account, + options: options, + taskHandler: taskHandler) { account, templates, responseData, error in + continuation.resume(returning: ( + account: account, + templates: templates, + responseData: responseData, + error: error + )) } - }) + } } + // Creates a new Richdocuments file using a specific template. + // + // Parameters: + // - path: The target path where the new document should be created. + // - templateId: The ID of the Richdocuments template to use. + // - account: The Nextcloud account performing the request. + // - options: Optional request configuration (headers, queue, API version, etc.). + // - taskHandler: Callback invoked when the underlying URLSessionTask is created. + // - completion: Completion handler returning the account, resulting file URL, raw response, and NKError. func createRichdocuments(path: String, templateId: String, account: String, @@ -128,6 +210,50 @@ public extension NextcloudKit { } } + /// Asynchronously creates a new Richdocuments file from a given template. + /// + /// - Parameters: + /// - path: Destination path for the new document. + /// - templateId: Template ID used to generate the new file. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request parameters. + /// - taskHandler: Optional monitoring of the underlying task. + /// - Returns: A tuple with account, resulting URL (if successful), raw response, and error result. + func createRichdocumentsAsync(path: String, + templateId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + url: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + createRichdocuments(path: path, + templateId: templateId, + account: account, + options: options, + taskHandler: taskHandler) { account, url, responseData, error in + continuation.resume(returning: ( + account: account, + url: url, + responseData: responseData, + error: error + )) + } + } + } + + // Creates a new Richdocuments file based on a default asset (no template). + // + // Parameters: + // - path: The destination path where the asset will be created. + // - account: The Nextcloud account initiating the creation. + // - options: Optional configuration for the request (e.g. headers, queue, API version). + // - taskHandler: Callback invoked when the underlying URLSessionTask is created. + // - completion: Completion handler returning account, resulting file URL, raw response data, and NKError. func createAssetRichdocuments(path: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -156,4 +282,37 @@ public extension NextcloudKit { } } } + + /// Asynchronously creates a Richdocuments asset file at a specified path. + /// + /// - Parameters: + /// - path: Target path for the asset document. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request customization. + /// - taskHandler: Optional monitoring of the underlying task. + /// - Returns: A tuple with account, resulting URL, raw response, and error. + func createAssetRichdocumentsAsync(path: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + url: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + createAssetRichdocuments(path: path, + account: account, + options: options, + taskHandler: taskHandler) { account, url, responseData, error in + continuation.resume(returning: ( + account: account, + url: url, + responseData: responseData, + error: error + )) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+Search.swift b/Sources/NextcloudKit/NextcloudKit+Search.swift index 13b7b05e..b1313266 100644 --- a/Sources/NextcloudKit/NextcloudKit+Search.swift +++ b/Sources/NextcloudKit/NextcloudKit+Search.swift @@ -8,20 +8,21 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - /// Available NC >= 20 - /// Search many different datasources in the cloud and combine them into one result. - /// - /// - Warning: Providers are requested concurrently. Not filtering will result in a high network load. - /// - /// - SeeAlso: - /// [Nextcloud Search API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html) - /// - /// - Parameters: - /// - term: The search term - /// - options: Additional request options - /// - filter: Filter search provider that should be searched. Default is all available provider.. - /// - update: Callback, notifying that a search provider return its result. Does not include previous results. - /// - completion: Callback, notifying that all search providers have been searched. The search is done. Includes all search results. + // Available NC >= 20 + // Performs a unified search using multiple providers and returns results asynchronously. + // + // Parameters: + // - term: The search term to query. + // - timeout: The individual request timeout per provider. + // - timeoutProvider: The maximum time allowed for each provider before being cancelled. + // - account: The Nextcloud account performing the search. + // - options: Optional configuration for the request (headers, queue, etc.). + // - filter: A closure to filter which `NKSearchProvider` are enabled. + // - request: Callback to access and inspect the underlying `DataRequest?`. + // - taskHandler: Callback triggered when a `URLSessionTask` is created. + // - providers: Callback providing the list of providers that will be queried. + // - update: Called for every result update from a provider. + // - completion: Called when all providers are finished, returns the response and status. func unifiedSearch(term: String, timeout: TimeInterval = 30, timeoutProvider: TimeInterval = 60, @@ -76,21 +77,69 @@ public extension NextcloudKit { request(requestUnifiedSearch) } - /// Available NC >= 20 - /// Search many different datasources in the cloud and combine them into one result. - /// - /// - SeeAlso: - /// [Nextcloud Search API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html) - /// - /// - Parameters: - /// - id: provider id - /// - term: The search term - /// - limit: limit (pagination) - /// - cursor: cursor (pagination) - /// - options: Additional request options - /// - timeout: Filter search provider that should be searched. Default is all available provider.. - /// - update: Callback, notifying that a search provider return its result. Does not include previous results. - /// - completion: Callback, notifying that all search results. + // Asynchronously performs a unified search and returns the final search response. + // + // - Parameters: + // - term: The string to search for. + // - timeout: Per-provider timeout in seconds. + // - timeoutProvider: Overall timeout for a provider. + // - account: The account used to authenticate the request. + // - options: Optional parameters for the search. + // - filter: Closure to filter the search providers. + // - request: Callback with the underlying `DataRequest?`. + // - taskHandler: Monitors the task creation. + // - providers: Callback that reports which providers are used. + // - update: Callback triggered as results come in from providers. + // - Returns: Final completion with account, raw response data, and NKError. + func unifiedSearchAsync(term: String, + timeout: TimeInterval = 30, + timeoutProvider: TimeInterval = 60, + account: String, + options: NKRequestOptions = NKRequestOptions(), + filter: @escaping (NKSearchProvider) -> Bool = { _ in true }, + request: @escaping (DataRequest?) -> Void, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + providers: @escaping (_ account: String, _ searchProviders: [NKSearchProvider]?) -> Void, + update: @escaping (_ account: String, _ searchResult: NKSearchResult?, _ provider: NKSearchProvider, _ error: NKError) -> Void + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + unifiedSearch(term: term, + timeout: timeout, + timeoutProvider: timeoutProvider, + account: account, + options: options, + filter: filter, + request: request, + taskHandler: taskHandler, + providers: providers, + update: update) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) + } + } + } + + // Available NC >= 20 + // Performs a search using a specified provider with pagination and timeout support. + // + // Parameters: + // - id: The identifier of the search provider to use. + // - term: The search term. + // - limit: Optional maximum number of results to return. + // - cursor: Optional pagination cursor for subsequent requests. + // - timeout: The timeout interval for the search request. + // - account: The Nextcloud account performing the search. + // - options: Optional request configuration such as headers and queue. + // - taskHandler: Callback to observe the underlying URLSessionTask. + // - completion: Completion handler returning the account, search results, raw response, and NKError. + // - Returns: The underlying DataRequest object if the request was started, otherwise nil. func searchProvider(_ id: String, term: String, limit: Int? = nil, From 7e3dcffed69a777fd61f78df4e84292adb9a2da0 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 14:29:47 +0200 Subject: [PATCH 06/10] async Signed-off-by: Marino Faggiana --- .../NextcloudKit/NextcloudKit+Search.swift | 45 +++ .../NextcloudKit+ShareDownloadLimit.swift | 77 ++++ .../NextcloudKit/NextcloudKit+Upload.swift | 176 ++++++++- .../NextcloudKit+UserStatus.swift | 334 +++++++++++++++++- 4 files changed, 618 insertions(+), 14 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+Search.swift b/Sources/NextcloudKit/NextcloudKit+Search.swift index b1313266..cfbf0cb5 100644 --- a/Sources/NextcloudKit/NextcloudKit+Search.swift +++ b/Sources/NextcloudKit/NextcloudKit+Search.swift @@ -197,6 +197,51 @@ public extension NextcloudKit { return requestSearchProvider } + + // Asynchronously performs a search request using the specified provider. + // + // Parameters: + // - id: The identifier of the search provider to use. + // - term: The search query string. + // - limit: Optional limit for number of results. + // - cursor: Optional pagination cursor. + // - timeout: The timeout for the request. + // - account: The Nextcloud account performing the request. + // - options: Optional configuration options for the request. + // - taskHandler: Callback to observe the created task. + // Returns: A tuple containing the account, search result, response data, and error. + func searchProviderAsync(_ id: String, + term: String, + limit: Int? = nil, + cursor: Int? = nil, + timeout: TimeInterval = 60, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + searchResult: NKSearchResult?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + _ = searchProvider(id, + term: term, + limit: limit, + cursor: cursor, + timeout: timeout, + account: account, + options: options, + taskHandler: taskHandler) { account, result, responseData, error in + continuation.resume(returning: ( + account: account, + searchResult: result, + responseData: responseData, + error: error + )) + } + } + } } public class NKSearchResult: NSObject { diff --git a/Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift b/Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift index fb23d2ca..0018f6dc 100644 --- a/Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift +++ b/Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift @@ -11,6 +11,14 @@ public extension NextcloudKit { "ocs/v2.php/apps/files_downloadlimit/api/v1/\(token)/limit" } + // Retrieves the current download limit for a shared file based on its public share token. + // + // Parameters: + // - account: The Nextcloud account identifier. + // - token: The public share token associated with the file or folder. + // - completion: A closure returning: + // - NKDownloadLimit?: The current download limit information, or `nil` if not available. + // - NKError: An object representing success or error during the request. func getDownloadLimit(account: String, token: String, completion: @escaping (NKDownloadLimit?, NKError) -> Void) { let endpoint = makeEndpoint(with: token) let options = NKRequestOptions() @@ -76,6 +84,36 @@ public extension NextcloudKit { } } + // Retrieves the current download limit for a shared file using its public token. + // + // Parameters: + // - account: The account associated with the Nextcloud session. + // - token: The public share token used to identify the shared file. + // + // Returns: A tuple containing: + // - downloadLimit: The current NKDownloadLimit object if available. + // - error: The NKError representing success or failure of the request. + func getDownloadLimitAsync(account: String, token: String) async -> ( + downloadLimit: NKDownloadLimit?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getDownloadLimit(account: account, token: token) { limit, error in + continuation.resume(returning: ( + downloadLimit: limit, + error: error + )) + } + } + } + + // Removes the download limit for a shared file using its public share token. + // + // Parameters: + // - account: The Nextcloud account identifier. + // - token: The public share token associated with the file or folder. + // - completion: A closure returning: + // - NKError: An object representing the success or failure of the request. func removeShareDownloadLimit(account: String, token: String, completion: @escaping (_ error: NKError) -> Void) { let endpoint = makeEndpoint(with: token) let options = NKRequestOptions() @@ -108,6 +146,29 @@ public extension NextcloudKit { } } + // Asynchronously removes the download limit for a public shared file or folder. + // + // Parameters: + // - account: The Nextcloud account used for the request. + // - token: The public token representing the shared resource. + // + // Returns: An NKError that indicates the outcome of the operation. + func removeShareDownloadLimitAsync(account: String, token: String) async -> NKError { + await withCheckedContinuation { continuation in + removeShareDownloadLimit(account: account, token: token) { error in + continuation.resume(returning: error) + } + } + } + + // Sets a download limit for a public shared file or folder. + // + // Parameters: + // - account: The Nextcloud account associated with the request. + // - token: The public share token identifying the shared resource. + // - limit: The new download limit to be set. + // - completion: A closure returning: + // - error: An NKError representing the success or failure of the operation. func setShareDownloadLimit(account: String, token: String, limit: Int, completion: @escaping (_ error: NKError) -> Void) { let endpoint = makeEndpoint(with: token) let options = NKRequestOptions() @@ -145,4 +206,20 @@ public extension NextcloudKit { } } } + + // Asynchronously sets a download limit for a public shared file or folder. + // + // Parameters: + // - account: The Nextcloud account used for the request. + // - token: The public share token of the resource. + // - limit: The maximum number of downloads to allow. + // + // Returns: An NKError indicating whether the operation was successful. + func setShareDownloadLimitAsync(account: String, token: String, limit: Int) async -> NKError { + await withCheckedContinuation { continuation in + setShareDownloadLimit(account: account, token: token, limit: limit) { error in + continuation.resume(returning: error) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+Upload.swift b/Sources/NextcloudKit/NextcloudKit+Upload.swift index 05aebc41..8c94677e 100644 --- a/Sources/NextcloudKit/NextcloudKit+Upload.swift +++ b/Sources/NextcloudKit/NextcloudKit+Upload.swift @@ -7,6 +7,27 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Uploads a file to the Nextcloud server. + // + // Parameters: + // - serverUrlFileName: The remote server URL or path where the file will be uploaded. + // - fileNameLocalPath: The local file path to be uploaded. + // - dateCreationFile: Optional creation date to include in headers (X-OC-CTime). + // - dateModificationFile: Optional modification date to include in headers (X-OC-MTime). + // - overwrite: If true, the remote file will be overwritten if it already exists. + // - account: The account associated with the upload session. + // - options: Optional configuration for the request (headers, queue, timeout, etc.). + // - requestHandler: Called with the created UploadRequest. + // - taskHandler: Called with the underlying URLSessionTask when it's created. + // - progressHandler: Called periodically with upload progress. + // - completionHandler: Called at the end of the upload with: + // - account: The account used, + // - ocId: The server-side file identifier, + // - etag: The entity tag for versioning, + // - date: The server date of the operation, + // - size: The total uploaded size in bytes, + // - headers: The response headers, + // - nkError: The result status. func upload(serverUrlFileName: Any, fileNameLocalPath: String, dateCreationFile: Date? = nil, @@ -88,17 +109,88 @@ public extension NextcloudKit { options.queue.async { requestHandler(request) } } - /// - Parameters: - /// - directory: The local directory where is the file to be split - /// - fileName: The name of the file to be splites - /// - date: If exist the date of file - /// - creationDate: If exist the creation date of file - /// - serverUrl: The serverURL where the file will be deposited once reassembled - /// - chunkFolder: The name of temp folder, usually NSUUID().uuidString - /// - filesChunk: The struct it will contain all file names with the increment size still to be sent. - /// Example filename: "3","4","5" .... size: 30000000, 40000000, 43000000 - /// - chunkSizeInMB: Size in MB of chunk + // Asynchronously uploads a file to the Nextcloud server. + // + // - Parameters are the same as the synchronous version. + // + // - Returns: A tuple with: + // - account: The account used for the upload. + // - ocId: The remote file identifier returned by the server. + // - etag: The file etag returned by the server. + // - date: The server timestamp. + // - size: The size of the uploaded file in bytes. + // - headers: The raw HTTP response headers. + // - error: The NKError result of the upload. + func uploadAsync(serverUrlFileName: Any, + fileNameLocalPath: String, + dateCreationFile: Date? = nil, + dateModificationFile: Date? = nil, + overwrite: Bool = false, + account: String, + options: NKRequestOptions = NKRequestOptions(), + requestHandler: @escaping (_ request: UploadRequest) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + progressHandler: @escaping (_ progress: Progress) -> Void = { _ in } + ) async -> ( + account: String, + ocId: String?, + etag: String?, + date: Date?, + size: Int64, + headers: [AnyHashable: Any]?, + error: NKError + ) { + await withCheckedContinuation { continuation in + upload(serverUrlFileName: serverUrlFileName, + fileNameLocalPath: fileNameLocalPath, + dateCreationFile: dateCreationFile, + dateModificationFile: dateModificationFile, + overwrite: overwrite, + account: account, + options: options, + requestHandler: requestHandler, + taskHandler: taskHandler, + progressHandler: progressHandler) { account, ocId, etag, date, size, headers, error in + continuation.resume(returning: ( + account: account, + ocId: ocId, + etag: etag, + date: date, + size: size, + headers: headers, + error: error + )) + } + } + } + // Uploads a file in multiple chunks to the Nextcloud server using TUS-like behavior. + // + // Parameters: + // - directory: The local directory containing the original file. + // - fileChunksOutputDirectory: Optional custom output directory for chunks (default is same as `directory`). + // - fileName: Name of the original file to split and upload. + // - destinationFileName: Optional custom filename to be used on the server. + // - date: The modification date to be set on the uploaded file. + // - creationDate: The creation date to be set on the uploaded file. + // - serverUrl: The destination server path. + // - chunkFolder: A temporary folder name (usually a UUID). + // - filesChunk: List of chunk identifiers and their expected sizes. + // - chunkSize: Size of each chunk in bytes. + // - account: The Nextcloud account used for authentication. + // - options: Request options (headers, queue, etc.). + // - numChunks: Callback invoked with total number of chunks. + // - counterChunk: Callback invoked with the index of the chunk being uploaded. + // - start: Called when chunk upload begins, with the full chunk list. + // - requestHandler: Handler to inspect the upload request. + // - taskHandler: Handler to inspect the upload task. + // - progressHandler: Progress callback with expected bytes, transferred bytes, and fraction completed. + // - uploaded: Called each time a chunk is successfully uploaded. + // - completion: Called when all chunks are uploaded and reassembled. Returns: + // - account: The user account used. + // - filesChunk: Remaining chunks (if any). + // - file: The final `NKFile` metadata for the uploaded file. + // - error: Upload result as `NKError`. func uploadChunk(directory: String, fileChunksOutputDirectory: String? = nil, fileName: String, @@ -119,7 +211,6 @@ public extension NextcloudKit { progressHandler: @escaping (_ totalBytesExpected: Int64, _ totalBytes: Int64, _ fractionCompleted: Double) -> Void = { _, _, _ in }, uploaded: @escaping (_ fileChunk: (fileName: String, size: Int64)) -> Void = { _ in }, completion: @escaping (_ account: String, _ filesChunk: [(fileName: String, size: Int64)]?, _ file: NKFile?, _ error: NKError) -> Void) { - guard let nkSession = nkCommonInstance.nksessions.session(forAccount: account) else { return completion(account, nil, nil, .urlError) } @@ -260,4 +351,67 @@ public extension NextcloudKit { } } } + + // Asynchronously uploads a file in chunks and assembles it on the Nextcloud server. + // + // - Parameters: Same as the sync version. + // - Returns: A tuple containing: + // - account: The user account used. + // - remainingChunks: Remaining chunks if any failed (or nil if success). + // - file: The final file metadata object. + // - error: Upload result as `NKError`. + func uploadChunkAsync(directory: String, + fileChunksOutputDirectory: String? = nil, + fileName: String, + destinationFileName: String? = nil, + date: Date?, + creationDate: Date?, + serverUrl: String, + chunkFolder: String, + filesChunk: [(fileName: String, size: Int64)], + chunkSize: Int, + account: String, + options: NKRequestOptions = NKRequestOptions(), + numChunks: @escaping (_ num: Int) -> Void = { _ in }, + counterChunk: @escaping (_ counter: Int) -> Void = { _ in }, + start: @escaping (_ filesChunk: [(fileName: String, size: Int64)]) -> Void = { _ in }, + requestHandler: @escaping (_ request: UploadRequest) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + progressHandler: @escaping (_ totalBytesExpected: Int64, _ totalBytes: Int64, _ fractionCompleted: Double) -> Void = { _, _, _ in }, + uploaded: @escaping (_ fileChunk: (fileName: String, size: Int64)) -> Void = { _ in } + ) async -> ( + account: String, + remainingChunks: [(fileName: String, size: Int64)]?, + file: NKFile?, + error: NKError + ) { + await withCheckedContinuation { continuation in + uploadChunk(directory: directory, + fileChunksOutputDirectory: fileChunksOutputDirectory, + fileName: fileName, + destinationFileName: destinationFileName, + date: date, + creationDate: creationDate, + serverUrl: serverUrl, + chunkFolder: chunkFolder, + filesChunk: filesChunk, + chunkSize: chunkSize, + account: account, + options: options, + numChunks: numChunks, + counterChunk: counterChunk, + start: start, + requestHandler: requestHandler, + taskHandler: taskHandler, + progressHandler: progressHandler, + uploaded: uploaded) { account, remaining, file, error in + continuation.resume(returning: ( + account: account, + remainingChunks: remaining, + file: file, + error: error + )) + } + } + } } diff --git a/Sources/NextcloudKit/NextcloudKit+UserStatus.swift b/Sources/NextcloudKit/NextcloudKit+UserStatus.swift index 06465885..2a88f83f 100644 --- a/Sources/NextcloudKit/NextcloudKit+UserStatus.swift +++ b/Sources/NextcloudKit/NextcloudKit+UserStatus.swift @@ -7,6 +7,25 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + // Retrieves the user status from the Nextcloud server. + // + // Parameters: + // - userId: Optional user ID to query (if nil, fetches the status for the authenticated user). + // - account: The Nextcloud account identifier. + // - options: Optional request options (headers, queue, version, etc.). + // - taskHandler: Callback for monitoring the `URLSessionTask`. + // - completion: Returns multiple values: + // - account: The user account used. + // - clearAt: Optional expiration `Date` of the status. + // - icon: Optional status icon name. + // - message: Optional status message. + // - messageId: Optional ID of the predefined message. + // - messageIsPredefined: Indicates whether the message is predefined. + // - status: Optional raw status value. + // - statusIsUserDefined: Indicates if the status was set manually by the user. + // - userId: The actual user ID returned by the server. + // - responseData: Raw response data from the server. + // - error: Result as `NKError`. func getUserStatus(userId: String? = nil, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -55,20 +74,58 @@ public extension NextcloudKit { } } + // Asynchronously retrieves the user status from the Nextcloud server. + // + // - Parameters: Same as the sync version. + // - Returns: A tuple with explicitly named values describing the user status. func getUserStatusAsync(userId: String? = nil, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (account: String, clearAt: Date?, icon: String?, message: String?, messageId: String?, messageIsPredefined: Bool, status: String?, statusIsUserDefined: Bool, userId: String?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation { continuation in + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + clearAt: Date?, + icon: String?, + message: String?, + messageId: String?, + messageIsPredefined: Bool, + status: String?, + statusIsUserDefined: Bool, + userId: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in getUserStatus(userId: userId, account: account, options: options, taskHandler: taskHandler) { account, clearAt, icon, message, messageId, messageIsPredefined, status, statusIsUserDefined, userId, responseData, error in - continuation.resume(returning: (account, clearAt, icon, message, messageId, messageIsPredefined, status, statusIsUserDefined, userId, responseData, error)) + continuation.resume(returning: ( + account: account, + clearAt: clearAt, + icon: icon, + message: message, + messageId: messageId, + messageIsPredefined: messageIsPredefined, + status: status, + statusIsUserDefined: statusIsUserDefined, + userId: userId, + responseData: responseData, + error: error + )) } } } + + // Sets the current user status on the Nextcloud server. + // + // Parameters: + // - status: The raw status value to be set (e.g. "online", "away", etc.). + // - account: The Nextcloud account performing the operation. + // - options: Optional request configuration. + // - taskHandler: Callback for the underlying `URLSessionTask`. + // - completion: Returns the account, the raw response data, and any resulting NKError. func setUserStatus(status: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -104,6 +161,46 @@ public extension NextcloudKit { } } + /// Asynchronously sets the current user status on the Nextcloud server. + /// + /// - Parameters: Same as the sync version. + /// - Returns: A tuple with the account, responseData, and NKError. + func setUserStatusAsync(status: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + setUserStatus(status: status, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) + } + } + } + + + /// Sets a predefined custom message for the user's status on the Nextcloud server. + /// + /// - Parameters: + /// - messageId: The identifier of the predefined message to be set. + /// - clearAt: A UNIX timestamp (in seconds) after which the message should expire (use `0` for no expiration). + /// - account: The account identifier used to authenticate the request. + /// - options: Optional request configuration, including headers, queue, and API version. + /// - taskHandler: Callback invoked with the `URLSessionTask` when the request is created. + /// - completion: Completion handler called with: + /// - account: The account used in the operation. + /// - responseData: The raw server response. + /// - error: A `NKError` indicating success or failure. func setCustomMessagePredefined(messageId: String, clearAt: Double, account: String, @@ -144,6 +241,53 @@ public extension NextcloudKit { } } + // Asynchronously sets a predefined custom message with optional expiration. + // + // Parameters: + // - messageId: The identifier of the predefined message to set. + // - clearAt: Expiration timestamp (UNIX time) after which the message is cleared (optional, use 0 to skip). + // - account: The Nextcloud account performing the operation. + // - options: Optional request configuration (headers, queue, etc.). + // - taskHandler: Callback for monitoring the underlying URLSessionTask. + // - Returns: A tuple containing the account identifier, the raw response, and any resulting NKError. + func setCustomMessagePredefinedAsync(messageId: String, + clearAt: Double, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + setCustomMessagePredefined(messageId: messageId, + clearAt: clearAt, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) + } + } + } + + // Sets a custom user-defined status message on the Nextcloud server. + // + // Parameters: + // - statusIcon: Optional icon name representing the status. + // - message: The custom status message string to display to other users. + // - clearAt: Expiration timestamp (in UNIX time format) for the status message; use 0 to disable automatic clearing. + // - account: The Nextcloud account identifier on which to apply the status. + // - options: Optional request configuration such as headers, queue, or task description. + // - taskHandler: Closure invoked when the URLSessionTask is created, used for task tracking or debugging. + // - completion: Completion handler returning: + // - account: The account identifier used. + // - responseData: The raw Alamofire response data (if any). + // - error: An `NKError` indicating success or failure. func setCustomMessageUserDefined(statusIcon: String?, message: String, clearAt: Double, @@ -188,6 +332,54 @@ public extension NextcloudKit { } } + // Asynchronously sets a custom user-defined status message. + // + // Parameters: + // - statusIcon: Optional icon to display with the message. + // - message: The custom status message string. + // - clearAt: Timestamp (UNIX time) when the message should expire (use 0 to skip). + // - account: The Nextcloud account performing the operation. + // - options: Request options such as headers, task description, queue. + // - taskHandler: Callback for URLSessionTask monitoring. + // + // Returns: A tuple containing account, responseData, and any resulting NKError. + func setCustomMessageUserDefinedAsync(statusIcon: String?, + message: String, + clearAt: Double, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + setCustomMessageUserDefined(statusIcon: statusIcon, + message: message, + clearAt: clearAt, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) + } + } + } + + // Clears any custom or predefined user status message currently set on the Nextcloud server. + // + // Parameters: + // - account: The Nextcloud account identifier whose status message should be cleared. + // - options: Optional request configuration such as custom headers, dispatch queue, or task description. + // - taskHandler: Closure called when the `URLSessionTask` is created, useful for debugging or tracking purposes. + // - completion: Completion handler returning: + // - account: The account identifier used. + // - responseData: The raw Alamofire response object, if available. + // - error: An `NKError` representing the result of the operation (success or failure). func clearMessage(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -220,6 +412,50 @@ public extension NextcloudKit { } } + // Asynchronously clears any user status message (custom or predefined) on the Nextcloud server. + // + // Parameters: + // - account: The Nextcloud account identifier whose status message will be cleared. + // - options: Optional `NKRequestOptions` to customize the request (e.g., headers, queue). + // - taskHandler: Callback triggered upon creation of the `URLSessionTask`. + // + // Returns: A tuple containing: + // - account: The account identifier used for the operation. + // - responseData: The raw `AFDataResponse` object returned by Alamofire. + // - error: The resulting `NKError`, either `.success` or a failure case. + func clearMessageAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + clearMessage(account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) + } + } + } + + // Retrieves the list of predefined user statuses (e.g., "Available", "Away", "Do not disturb") from the Nextcloud server. + // + // Parameters: + // - account: The Nextcloud account identifier performing the request. + // - options: Optional `NKRequestOptions` to customize the request (e.g., custom headers, queue). + // - taskHandler: Callback triggered when the `URLSessionTask` is created. + // + // Returns: A tuple containing: + // - account: The account identifier used for the request. + // - userStatuses: An optional array of predefined `NKUserStatus` objects. + // - responseData: Raw `AFDataResponse` from Alamofire. + // - error: Resulting `NKError` describing success or failure. func getUserStatusPredefinedStatuses(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -268,6 +504,57 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves the predefined user statuses available on the Nextcloud server. + /// + /// These predefined statuses are managed by the server and include standardized status types + /// (e.g. "online", "away", "do not disturb") which can be selected by users. + /// + /// Parameters: + /// - account: The identifier of the Nextcloud account making the request. + /// - options: Optional request configuration (headers, queue, API version, etc.). + /// - taskHandler: A closure that is called when the URLSessionTask is created. + /// + /// Returns: A tuple containing: + /// - account: The account used for the request. + /// - userStatuses: An optional array of `NKUserStatus` representing the predefined statuses. + /// - responseData: The raw HTTP response returned from the server. + /// - error: The result of the request as an `NKError` object. + func getUserStatusPredefinedStatusesAsync(account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + userStatuses: [NKUserStatus]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getUserStatusPredefinedStatuses(account: account, + options: options, + taskHandler: taskHandler) { account, userStatuses, responseData, error in + continuation.resume(returning: ( + account: account, + userStatuses: userStatuses, + responseData: responseData, + error: error + )) + } + } + } + + /// Retrieves a list of user statuses from the Nextcloud server. + /// + /// - Parameters: + /// - limit: The maximum number of statuses to retrieve. + /// - offset: The number of statuses to skip before starting to collect the results. + /// - account: The account identifier used to perform the request. + /// - options: Optional request configuration (headers, queue, etc.). + /// - taskHandler: Callback invoked with the `URLSessionTask` when the request is created. + /// - completion: Completion handler called with: + /// - account: The account used in the operation. + /// - userStatuses: An array of `NKUserStatus` objects, or `nil` if an error occurred. + /// - responseData: The raw server response. + /// - error: A `NKError` indicating success or failure. func getUserStatusRetrieveStatuses(limit: Int, offset: Int, account: String, @@ -319,4 +606,45 @@ public extension NextcloudKit { } } } + + /// Asynchronously retrieves a list of user statuses from the Nextcloud server. + /// + /// - Parameters: + /// - limit: The maximum number of statuses to retrieve. + /// - offset: The number of statuses to skip before collecting results. + /// - account: The account identifier used to perform the request. + /// - options: Optional request configuration (headers, queue, etc.). + /// - taskHandler: Callback invoked with the `URLSessionTask` when the request is created. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the request. + /// - userStatuses: An array of `NKUserStatus` objects, or `nil` if an error occurred. + /// - responseData: The raw server response. + /// - error: A `NKError` describing the result. + func getUserStatusRetrieveStatusesAsync(limit: Int, + offset: Int, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + userStatuses: [NKUserStatus]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getUserStatusRetrieveStatuses(limit: limit, + offset: offset, + account: account, + options: options, + taskHandler: taskHandler) { account, userStatuses, responseData, error in + continuation.resume(returning: ( + account: account, + userStatuses: userStatuses, + responseData: responseData, + error: error + )) + } + } + } } From a2a0fac4f6757bfb2d19980f95d35c8cdeefdb78 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 14:46:01 +0200 Subject: [PATCH 07/10] doc Signed-off-by: Marino Faggiana --- Sources/NextcloudKit/NextcloudKit+API.swift | 306 +++++++++--------- .../NextcloudKit/NextcloudKit+Assistant.swift | 96 +++--- .../NextcloudKit+AssistantV2.swift | 74 ++--- .../NextcloudKit/NextcloudKit+Comments.swift | 98 +++--- .../NextcloudKit/NextcloudKit+Dashboard.swift | 38 +-- .../NextcloudKit/NextcloudKit+Download.swift | 24 +- Sources/NextcloudKit/NextcloudKit+E2EE.swift | 230 ++++++------- .../NextcloudKit/NextcloudKit+FilesLock.swift | 22 +- .../NextcloudKit+Groupfolders.swift | 18 +- .../NextcloudKit/NextcloudKit+Hovercard.swift | 39 +++ .../NextcloudKit/NextcloudKit+Livephoto.swift | 18 +- Sources/NextcloudKit/NextcloudKit+Login.swift | 102 ++++-- 12 files changed, 573 insertions(+), 492 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+API.swift b/Sources/NextcloudKit/NextcloudKit+API.swift index 97391a86..a56c89a9 100644 --- a/Sources/NextcloudKit/NextcloudKit+API.swift +++ b/Sources/NextcloudKit/NextcloudKit+API.swift @@ -31,14 +31,14 @@ public class NKNotifications: NSObject { } public extension NextcloudKit { - // Checks if the specified server URL is reachable and returns the raw HTTP response. - // Used to verify the availability and responsiveness of a Nextcloud server. - // - // Parameters: - // - serverUrl: Full URL of the Nextcloud server to check. - // - options: Optional request options (e.g. custom headers, queue). - // - taskHandler: Closure to access the URLSessionTask (default is no-op). - // - completion: Completion handler with the raw HTTP response and any NKError. + /// Checks if the specified server URL is reachable and returns the raw HTTP response. + /// Used to verify the availability and responsiveness of a Nextcloud server. + /// + /// Parameters: + /// - serverUrl: Full URL of the Nextcloud server to check. + /// - options: Optional request options (e.g. custom headers, queue). + /// - taskHandler: Closure to access the URLSessionTask (default is no-op). + /// - completion: Completion handler with the raw HTTP response and any NKError. func checkServer(serverUrl: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -85,16 +85,16 @@ public extension NextcloudKit { // MARK: - - // Executes a generic HTTP request using the given relative endpoint path and HTTP method. - // Commonly used for flexible OCS or WebDAV API calls without dedicated wrappers. - // - // Parameters: - // - endpoint: The relative API path (e.g. "ocs/v2.php/apps/...") to be appended to the base server URL. - // - account: The Nextcloud account initiating the request. - // - method: The HTTP method as a string ("GET", "POST", "DELETE", etc). - // - options: Optional request options such as custom headers, versioning, queue. - // - taskHandler: Optional closure to access the underlying URLSessionTask. - // - completion: Completion handler returning the account, raw response, and any NKError. + /// Executes a generic HTTP request using the given relative endpoint path and HTTP method. + /// Commonly used for flexible OCS or WebDAV API calls without dedicated wrappers. + /// + /// Parameters: + /// - endpoint: The relative API path (e.g. "ocs/v2.php/apps/...") to be appended to the base server URL. + /// - account: The Nextcloud account initiating the request. + /// - method: The HTTP method as a string ("GET", "POST", "DELETE", etc). + /// - options: Optional request options such as custom headers, versioning, queue. + /// - taskHandler: Optional closure to access the underlying URLSessionTask. + /// - completion: Completion handler returning the account, raw response, and any NKError. func generalWithEndpoint(_ endpoint: String, account: String, method: String, @@ -154,14 +154,14 @@ public extension NextcloudKit { // MARK: - - // Retrieves the list of external sites configured in the Nextcloud instance. - // These are typically links to external services or resources displayed in the web UI. - // - // Parameters: - // - account: The Nextcloud account making the request. - // - options: Optional request options for custom headers, versioning, queue, etc. - // - taskHandler: Closure to access the URLSessionTask (default is no-op). - // - completion: Completion handler returning the account, list of external sites, response, and any NKError. + /// Retrieves the list of external sites configured in the Nextcloud instance. + /// These are typically links to external services or resources displayed in the web UI. + /// + /// Parameters: + /// - account: The Nextcloud account making the request. + /// - options: Optional request options for custom headers, versioning, queue, etc. + /// - taskHandler: Closure to access the URLSessionTask (default is no-op). + /// - completion: Completion handler returning the account, list of external sites, response, and any NKError. func getExternalSite(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -249,13 +249,13 @@ public extension NextcloudKit { case failure(NKError) } - // Retrieves the status information of a Nextcloud server. - // - // Parameters: - // - serverUrl: The base URL of the Nextcloud server (e.g., https://cloud.example.com). - // - options: Optional request configuration (e.g., headers, queue, etc.). - // - taskHandler: Callback for the underlying URLSessionTask. - // - completion: Returns the raw response and a `ServerInfoResult` containing server status information or an error. + /// Retrieves the status information of a Nextcloud server. + /// + /// Parameters: + /// - serverUrl: The base URL of the Nextcloud server (e.g., https://cloud.example.com). + /// - options: Optional request configuration (e.g., headers, queue, etc.). + /// - taskHandler: Callback for the underlying URLSessionTask. + /// - completion: Returns the raw response and a `ServerInfoResult` containing server status information or an error. func getServerStatus(serverUrl: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -334,15 +334,15 @@ public extension NextcloudKit { // MARK: - - // Downloads a file preview (thumbnail) from the specified URL for a given Nextcloud account. - // - // Parameters: - // - url: The full URL of the preview image to download. - // - account: The Nextcloud account used for the request. - // - etag: Optional entity tag used for cache validation. - // - options: Optional request configuration (e.g., headers, queue, version). - // - taskHandler: Callback for the underlying `URLSessionTask`. - // - completion: Returns the account, raw response data, and an `NKError` representing the result of the operation. + /// Downloads a file preview (thumbnail) from the specified URL for a given Nextcloud account. + /// + /// Parameters: + /// - url: The full URL of the preview image to download. + /// - account: The Nextcloud account used for the request. + /// - etag: Optional entity tag used for cache validation. + /// - options: Optional request configuration (e.g., headers, queue, version). + /// - taskHandler: Callback for the underlying `URLSessionTask`. + /// - completion: Returns the account, raw response data, and an `NKError` representing the result of the operation. func downloadPreview(url: URL, account: String, etag: String? = nil, @@ -405,21 +405,21 @@ public extension NextcloudKit { } } - // Downloads a preview (thumbnail) of a file with specified dimensions and parameters. - // - // Parameters: - // - fileId: The identifier of the file to generate a preview for. - // - width: The desired width of the preview image (default is 1024). - // - height: The desired height of the preview image (default is 1024). - // - etag: Optional entity tag used for caching validation. - // - crop: Indicates whether the image should be cropped (1 = true, default). - // - cropMode: The cropping mode (default is "cover"). - // - forceIcon: If set to 1, forces icon generation (default is 0). - // - mimeFallback: If set to 1, fallback to MIME-type icon if preview is unavailable (default is 0). - // - account: The Nextcloud account performing the operation. - // - options: Optional request configuration (headers, versioning, etc.). - // - taskHandler: Callback for the `URLSessionTask`. - // - completion: Returns the account, final width and height used, etag, response data, and any error encountered. + /// Downloads a preview (thumbnail) of a file with specified dimensions and parameters. + /// + /// Parameters: + /// - fileId: The identifier of the file to generate a preview for. + /// - width: The desired width of the preview image (default is 1024). + /// - height: The desired height of the preview image (default is 1024). + /// - etag: Optional entity tag used for caching validation. + /// - crop: Indicates whether the image should be cropped (1 = true, default). + /// - cropMode: The cropping mode (default is "cover"). + /// - forceIcon: If set to 1, forces icon generation (default is 0). + /// - mimeFallback: If set to 1, fallback to MIME-type icon if preview is unavailable (default is 0). + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request configuration (headers, versioning, etc.). + /// - taskHandler: Callback for the `URLSessionTask`. + /// - completion: Returns the account, final width and height used, etag, response data, and any error encountered. func downloadPreview(fileId: String, width: Int = 1024, height: Int = 1024, @@ -516,20 +516,20 @@ public extension NextcloudKit { } } - // Downloads a preview (thumbnail) for a file located in the trashbin. - // - // Parameters: - // - fileId: The identifier of the trashed file. - // - width: Desired width of the preview image (default is 512). - // - height: Desired height of the preview image (default is 512). - // - crop: Indicates whether the image should be cropped (1 = true, default). - // - cropMode: The cropping mode (e.g., "cover"). - // - forceIcon: Forces use of the filetype icon instead of generating a preview (0 = false, default). - // - mimeFallback: Uses MIME-type fallback if preview is unavailable (0 = false, default). - // - account: The Nextcloud account making the request. - // - options: Request customization options (headers, queue, version, etc.). - // - taskHandler: Callback to inspect the underlying URLSessionTask. - // - completion: Returns the account, final width/height, preview response data, and NKError. + /// Downloads a preview (thumbnail) for a file located in the trashbin. + /// + /// Parameters: + /// - fileId: The identifier of the trashed file. + /// - width: Desired width of the preview image (default is 512). + /// - height: Desired height of the preview image (default is 512). + /// - crop: Indicates whether the image should be cropped (1 = true, default). + /// - cropMode: The cropping mode (e.g., "cover"). + /// - forceIcon: Forces use of the filetype icon instead of generating a preview (0 = false, default). + /// - mimeFallback: Uses MIME-type fallback if preview is unavailable (0 = false, default). + /// - account: The Nextcloud account making the request. + /// - options: Request customization options (headers, queue, version, etc.). + /// - taskHandler: Callback to inspect the underlying URLSessionTask. + /// - completion: Returns the account, final width/height, preview response data, and NKError. func downloadTrashPreview(fileId: String, width: Int = 512, height: Int = 512, @@ -615,18 +615,18 @@ public extension NextcloudKit { } } - // Downloads a user's avatar image from the server and optionally stores it locally. - // - // Parameters: - // - user: The user identifier for whom the avatar is requested. - // - fileNameLocalPath: The local file path where the avatar image will be saved. - // - sizeImage: The size of the avatar to request (in pixels). - // - avatarSizeRounded: If greater than 0, the avatar will be rounded to this size (in pixels). - // - etag: Optional ETag string to validate the cache. - // - account: The Nextcloud account performing the operation. - // - options: Optional request options (queue, headers, etc.). - // - taskHandler: Callback for the underlying URLSessionTask. - // - completion: Returns the account, avatar image, original image, ETag, response data, and NKError. + /// Downloads a user's avatar image from the server and optionally stores it locally. + /// + /// Parameters: + /// - user: The user identifier for whom the avatar is requested. + /// - fileNameLocalPath: The local file path where the avatar image will be saved. + /// - sizeImage: The size of the avatar to request (in pixels). + /// - avatarSizeRounded: If greater than 0, the avatar will be rounded to this size (in pixels). + /// - etag: Optional ETag string to validate the cache. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request options (queue, headers, etc.). + /// - taskHandler: Callback for the underlying URLSessionTask. + /// - completion: Returns the account, avatar image, original image, ETag, response data, and NKError. func downloadAvatar(user: String, fileNameLocalPath: String, sizeImage: Int, @@ -776,14 +776,14 @@ public extension NextcloudKit { } } - // Downloads generic raw content from a given server URL using the specified account. - // - // Parameters: - // - serverUrl: The full URL string of the content to be downloaded. - // - account: The Nextcloud account to use for the request. - // - options: Optional configuration including headers, queue, and version. - // - taskHandler: Optional callback for monitoring the URLSessionTask. - // - completion: Returns the account, response data, and NKError representing the outcome. + /// Downloads generic raw content from a given server URL using the specified account. + /// + /// Parameters: + /// - serverUrl: The full URL string of the content to be downloaded. + /// - account: The Nextcloud account to use for the request. + /// - options: Optional configuration including headers, queue, and version. + /// - taskHandler: Optional callback for monitoring the URLSessionTask. + /// - completion: Returns the account, response data, and NKError representing the outcome. func downloadContent(serverUrl: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -841,14 +841,14 @@ public extension NextcloudKit { // MARK: - - // Retrieves user profile metadata for a specific user in the Nextcloud instance. - // - // Parameters: - // - account: The account used to perform the request. - // - userId: The user identifier whose metadata is being retrieved. - // - options: Additional request configuration (e.g., headers, API version, execution queue). - // - taskHandler: Optional callback invoked with the underlying URLSessionTask. - // - completion: Returns the account, parsed user profile (`NKUserProfile`), response metadata, and any `NKError` encountered. + /// Retrieves user profile metadata for a specific user in the Nextcloud instance. + /// + /// Parameters: + /// - account: The account used to perform the request. + /// - userId: The user identifier whose metadata is being retrieved. + /// - options: Additional request configuration (e.g., headers, API version, execution queue). + /// - taskHandler: Optional callback invoked with the underlying URLSessionTask. + /// - completion: Returns the account, parsed user profile (`NKUserProfile`), response metadata, and any `NKError` encountered. func getUserMetadata(account: String, userId: String, options: NKRequestOptions = NKRequestOptions(), @@ -916,13 +916,13 @@ public extension NextcloudKit { } } - // Fetches the metadata of the currently authenticated user. - // - // Parameters: - // - account: The Nextcloud account performing the request. - // - options: Additional request configuration (e.g., custom headers, API version, execution queue). - // - taskHandler: Optional callback invoked with the underlying URLSessionTask. - // - completion: Returns the account, parsed user profile (`NKUserProfile`), response metadata, and any `NKError` encountered. + /// Fetches the metadata of the currently authenticated user. + /// + /// Parameters: + /// - account: The Nextcloud account performing the request. + /// - options: Additional request configuration (e.g., custom headers, API version, execution queue). + /// - taskHandler: Optional callback invoked with the underlying URLSessionTask. + /// - completion: Returns the account, parsed user profile (`NKUserProfile`), response metadata, and any `NKError` encountered. func getUserProfile(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -1032,15 +1032,15 @@ public extension NextcloudKit { } // MARK: - - // Checks the remote wipe status for a specific account and token. - // - // Parameters: - // - serverUrl: The base server URL to perform the request. - // - token: The authentication or wipe token to validate. - // - account: The Nextcloud account performing the request. - // - options: Optional configuration for the request (e.g., headers, version, queue). - // - taskHandler: Optional callback to observe the underlying URLSessionTask. - // - completion: Returns the account, wipe status (true if a wipe is required), raw response data, and NKError if any. + /// Checks the remote wipe status for a specific account and token. + /// + /// Parameters: + /// - serverUrl: The base server URL to perform the request. + /// - token: The authentication or wipe token to validate. + /// - account: The Nextcloud account performing the request. + /// - options: Optional configuration for the request (e.g., headers, version, queue). + /// - taskHandler: Optional callback to observe the underlying URLSessionTask. + /// - completion: Returns the account, wipe status (true if a wipe is required), raw response data, and NKError if any. func getRemoteWipeStatus(serverUrl: String, token: String, account: String, @@ -1111,15 +1111,15 @@ public extension NextcloudKit { } } - // Notifies the server that the remote wipe operation has been completed. - // - // Parameters: - // - serverUrl: The base server URL used to send the wipe completion notification. - // - token: The remote wipe token associated with the account. - // - account: The Nextcloud account that performed the wipe. - // - options: Optional configuration for request (headers, queue, version, etc.). - // - taskHandler: Callback for the underlying URLSessionTask if monitoring is needed. - // - completion: Returns the account, raw response data, and NKError. + /// Notifies the server that the remote wipe operation has been completed. + /// + /// Parameters: + /// - serverUrl: The base server URL used to send the wipe completion notification. + /// - token: The remote wipe token associated with the account. + /// - account: The Nextcloud account that performed the wipe. + /// - options: Optional configuration for request (headers, queue, version, etc.). + /// - taskHandler: Callback for the underlying URLSessionTask if monitoring is needed. + /// - completion: Returns the account, raw response data, and NKError. func setRemoteWipeCompletition(serverUrl: String, token: String, account: String, @@ -1188,18 +1188,18 @@ public extension NextcloudKit { // MARK: - - // Retrieves a list of activities for the current account. - // - // Parameters: - // - since: The timestamp (as Unix epoch) to fetch activities after. - // - limit: The maximum number of activities to retrieve. - // - objectId: Optional object ID to filter activities (e.g., file ID). - // - objectType: Optional object type to filter (e.g., "files"). - // - previews: Whether to include preview data for activities. - // - account: The Nextcloud account requesting the activity feed. - // - options: Optional request configuration (headers, queue, version, etc.). - // - taskHandler: Callback for the underlying URLSessionTask. - // - completion: Returns the account, array of NKActivity objects, the timestamp of the first known activity, last returned activity, raw response, and NKError. + /// Retrieves a list of activities for the current account. + /// + /// Parameters: + /// - since: The timestamp (as Unix epoch) to fetch activities after. + /// - limit: The maximum number of activities to retrieve. + /// - objectId: Optional object ID to filter activities (e.g., file ID). + /// - objectType: Optional object type to filter (e.g., "files"). + /// - previews: Whether to include preview data for activities. + /// - account: The Nextcloud account requesting the activity feed. + /// - options: Optional request configuration (headers, queue, version, etc.). + /// - taskHandler: Callback for the underlying URLSessionTask. + /// - completion: Returns the account, array of NKActivity objects, the timestamp of the first known activity, last returned activity, raw response, and NKError. func getActivity(since: Int, limit: Int, objectId: String?, @@ -1347,13 +1347,13 @@ public extension NextcloudKit { // MARK: - - // Retrieves all notifications associated with the current account. - // - // Parameters: - // - account: The Nextcloud account from which to retrieve notifications. - // - options: Optional request configuration (headers, queue, version, etc.). - // - taskHandler: Callback for the underlying URLSessionTask. - // - completion: Returns the account, list of NKNotifications, raw response data, and NKError. + /// Retrieves all notifications associated with the current account. + /// + /// Parameters: + /// - account: The Nextcloud account from which to retrieve notifications. + /// - options: Optional request configuration (headers, queue, version, etc.). + /// - taskHandler: Callback for the underlying URLSessionTask. + /// - completion: Returns the account, list of NKNotifications, raw response data, and NKError. func getNotifications(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -1451,16 +1451,16 @@ public extension NextcloudKit { } } - // Performs an action on a specific notification by ID (e.g., mark as read or delete). - // - // Parameters: - // - serverUrl: Optional custom server URL override. If nil, the default account URL is used. - // - idNotification: The ID of the notification to act upon. - // - method: The HTTP method to use for the action (e.g., "DELETE" or "POST"). - // - account: The account associated with the notification. - // - options: Optional request configuration (headers, queue, version, etc.). - // - taskHandler: Callback for the underlying URLSessionTask. - // - completion: Returns the account, raw response data, and NKError result. + /// Performs an action on a specific notification by ID (e.g., mark as read or delete). + /// + /// Parameters: + /// - serverUrl: Optional custom server URL override. If nil, the default account URL is used. + /// - idNotification: The ID of the notification to act upon. + /// - method: The HTTP method to use for the action (e.g., "DELETE" or "POST"). + /// - account: The account associated with the notification. + /// - options: Optional request configuration (headers, queue, version, etc.). + /// - taskHandler: Callback for the underlying URLSessionTask. + /// - completion: Returns the account, raw response data, and NKError result. func setNotification(serverUrl: String?, idNotification: Int, method: String, diff --git a/Sources/NextcloudKit/NextcloudKit+Assistant.swift b/Sources/NextcloudKit/NextcloudKit+Assistant.swift index 43242eb3..1b9bdf6a 100644 --- a/Sources/NextcloudKit/NextcloudKit+Assistant.swift +++ b/Sources/NextcloudKit/NextcloudKit+Assistant.swift @@ -7,14 +7,14 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Retrieves the list of supported text processing task types from the server. - // These types define the kinds of operations (e.g., summarization, translation) supported by the assistant API. - // - // Parameters: - // - account: The Nextcloud account initiating the request. - // - options: Optional configuration for the HTTP request. - // - taskHandler: Optional closure to access the underlying URLSessionTask. - // - completion: Completion handler providing the account, available task types, response, and NKError. + /// Retrieves the list of supported text processing task types from the server. + /// These types define the kinds of operations (e.g., summarization, translation) supported by the assistant API. + /// + /// Parameters: + /// - account: The Nextcloud account initiating the request. + /// - options: Optional configuration for the HTTP request. + /// - taskHandler: Optional closure to access the underlying URLSessionTask. + /// - completion: Completion handler providing the account, available task types, response, and NKError. func textProcessingGetTypes(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -77,18 +77,18 @@ public extension NextcloudKit { } } - // Schedules a new text processing task on the server (e.g., translation, summary, etc.). - // The request includes the input text, the type of task to execute, and a unique identifier. - // - // Parameters: - // - input: The raw input string to be processed. - // - typeId: The identifier of the task type (e.g., "summarize", "translate"). - // - appId: The application identifier (default is "assistant"). - // - identifier: A client-side unique string to track this task. - // - account: The Nextcloud account executing the request. - // - options: Optional request configuration (headers, queue, etc.). - // - taskHandler: Optional closure to access the URLSessionTask. - // - completion: Completion handler returning the account, resulting task object, response, and any NKError. + /// Schedules a new text processing task on the server (e.g., translation, summary, etc.). + /// The request includes the input text, the type of task to execute, and a unique identifier. + /// + /// Parameters: + /// - input: The raw input string to be processed. + /// - typeId: The identifier of the task type (e.g., "summarize", "translate"). + /// - appId: The application identifier (default is "assistant"). + /// - identifier: A client-side unique string to track this task. + /// - account: The Nextcloud account executing the request. + /// - options: Optional request configuration (headers, queue, etc.). + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, resulting task object, response, and any NKError. func textProcessingSchedule(input: String, typeId: String, appId: String = "assistant", @@ -168,15 +168,15 @@ public extension NextcloudKit { } } - // Retrieves the current status and data of a previously scheduled text processing task. - // Useful for polling or checking the result of a long-running task by its unique ID. - // - // Parameters: - // - taskId: The server-side ID of the text processing task to retrieve. - // - account: The Nextcloud account making the request. - // - options: Optional request configuration. - // - taskHandler: Optional closure to access the URLSessionTask. - // - completion: Completion handler returning the account, task object, raw response, and NKError. + /// Retrieves the current status and data of a previously scheduled text processing task. + /// Useful for polling or checking the result of a long-running task by its unique ID. + /// + /// Parameters: + /// - taskId: The server-side ID of the text processing task to retrieve. + /// - account: The Nextcloud account making the request. + /// - options: Optional request configuration. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, task object, raw response, and NKError. func textProcessingGetTask(taskId: Int, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -243,15 +243,15 @@ public extension NextcloudKit { } } - // Deletes a specific text processing task on the server. - // This is used to cancel or clean up tasks that are no longer needed. - // - // Parameters: - // - taskId: The ID of the task to be deleted. - // - account: The Nextcloud account making the request. - // - options: Optional request configuration. - // - taskHandler: Optional closure to access the URLSessionTask. - // - completion: Completion handler returning the account, deleted task object, raw response, and NKError. + /// Deletes a specific text processing task on the server. + /// This is used to cancel or clean up tasks that are no longer needed. + /// + /// Parameters: + /// - taskId: The ID of the task to be deleted. + /// - account: The Nextcloud account making the request. + /// - options: Optional request configuration. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, deleted task object, raw response, and NKError. func textProcessingDeleteTask(taskId: Int, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -318,15 +318,15 @@ public extension NextcloudKit { } } - // Retrieves a list of all text processing tasks associated with a specific app ID. - // This includes both pending and completed tasks, useful for tracking the assistant's activity. - // - // Parameters: - // - appId: Identifier of the application requesting the tasks (e.g., "assistant"). - // - account: The Nextcloud account making the request. - // - options: Optional HTTP request configuration. - // - taskHandler: Optional closure to access the URLSessionTask. - // - completion: Completion handler returning the account, task list, raw response, and NKError. + /// Retrieves a list of all text processing tasks associated with a specific app ID. + /// This includes both pending and completed tasks, useful for tracking the assistant's activity. + /// + /// Parameters: + /// - appId: Identifier of the application requesting the tasks (e.g., "assistant"). + /// - account: The Nextcloud account making the request. + /// - options: Optional HTTP request configuration. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, task list, raw response, and NKError. func textProcessingTaskList(appId: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -393,5 +393,3 @@ public extension NextcloudKit { } } } - - diff --git a/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift b/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift index 25fda361..1f544c76 100644 --- a/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift +++ b/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift @@ -7,15 +7,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Retrieves the list of supported task types for a specific account and task category. - // Typically used to discover available AI or text processing capabilities. - // - // Parameters: - // - account: The Nextcloud account making the request. - // - supportedTaskType: Type of tasks to retrieve, default is "Text". - // - options: Optional HTTP request configuration. - // - taskHandler: Optional closure to access the URLSessionTask. - // - completion: Completion handler returning the account, list of supported types, raw response, and NKError. + /// Retrieves the list of supported task types for a specific account and task category. + /// Typically used to discover available AI or text processing capabilities. + /// + /// Parameters: + /// - account: The Nextcloud account making the request. + /// - supportedTaskType: Type of tasks to retrieve, default is "Text". + /// - options: Optional HTTP request configuration. + /// - taskHandler: Optional closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, list of supported types, raw response, and NKError. func textProcessingGetTypesV2(account: String, supportedTaskType: String = "Text", options: NKRequestOptions = NKRequestOptions(), @@ -86,16 +86,16 @@ public extension NextcloudKit { } } - // Schedules a new text processing task for a specific account and task type. - // Useful for initiating assistant-based text analysis, generation, or transformation. - // - // Parameters: - // - input: The input text to be processed. - // - taskType: The specific task type to execute (e.g., summarization, sentiment analysis). - // - account: The Nextcloud account initiating the task. - // - options: Optional HTTP request configuration. - // - taskHandler: Optional closure to access the underlying URLSessionTask. - // - completion: Completion handler returning the account, scheduled task, raw response, and NKError. + /// Schedules a new text processing task for a specific account and task type. + /// Useful for initiating assistant-based text analysis, generation, or transformation. + /// + /// Parameters: + /// - input: The input text to be processed. + /// - taskType: The specific task type to execute (e.g., summarization, sentiment analysis). + /// - account: The Nextcloud account initiating the task. + /// - options: Optional HTTP request configuration. + /// - taskHandler: Optional closure to access the underlying URLSessionTask. + /// - completion: Completion handler returning the account, scheduled task, raw response, and NKError. func textProcessingScheduleV2(input: String, taskType: TaskTypeData, account: String, @@ -169,15 +169,15 @@ public extension NextcloudKit { } } - // Retrieves all scheduled text processing tasks of a specific type for the given account. - // Useful for listing and tracking tasks like summarization, transcription, or classification. - // - // Parameters: - // - taskType: Identifier of the task type to filter tasks (e.g., "Text"). - // - account: The Nextcloud account performing the request. - // - options: Optional HTTP request configuration. - // - taskHandler: Optional closure to access the underlying URLSessionTask. - // - completion: Completion handler returning the account, list of tasks, raw response, and NKError. + /// Retrieves all scheduled text processing tasks of a specific type for the given account. + /// Useful for listing and tracking tasks like summarization, transcription, or classification. + /// + /// Parameters: + /// - taskType: Identifier of the task type to filter tasks (e.g., "Text"). + /// - account: The Nextcloud account performing the request. + /// - options: Optional HTTP request configuration. + /// - taskHandler: Optional closure to access the underlying URLSessionTask. + /// - completion: Completion handler returning the account, list of tasks, raw response, and NKError. func textProcessingGetTasksV2(taskType: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -244,15 +244,15 @@ public extension NextcloudKit { } } - // Deletes a scheduled text processing task with a specific identifier. - // Useful for canceling tasks that are no longer needed or invalid. - // - // Parameters: - // - taskId: The unique identifier of the task to delete. - // - account: The Nextcloud account executing the deletion. - // - options: Optional HTTP request configuration. - // - taskHandler: Optional closure to access the underlying URLSessionTask. - // - completion: Completion handler returning the account, raw response, and NKError. + /// Deletes a scheduled text processing task with a specific identifier. + /// Useful for canceling tasks that are no longer needed or invalid. + /// + /// Parameters: + /// - taskId: The unique identifier of the task to delete. + /// - account: The Nextcloud account executing the deletion. + /// - options: Optional HTTP request configuration. + /// - taskHandler: Optional closure to access the underlying URLSessionTask. + /// - completion: Completion handler returning the account, raw response, and NKError. func textProcessingDeleteTaskV2(taskId: Int64, account: String, options: NKRequestOptions = NKRequestOptions(), diff --git a/Sources/NextcloudKit/NextcloudKit+Comments.swift b/Sources/NextcloudKit/NextcloudKit+Comments.swift index 48a27cab..25d25a2d 100644 --- a/Sources/NextcloudKit/NextcloudKit+Comments.swift +++ b/Sources/NextcloudKit/NextcloudKit+Comments.swift @@ -6,15 +6,15 @@ import Foundation import Alamofire public extension NextcloudKit { - // Retrieves all comments associated with a specific file from the server. - // This is typically used in collaboration features to display user discussions or annotations. - // - // Parameters: - // - fileId: Identifier of the file whose comments are being retrieved. - // - account: The Nextcloud account requesting the comments. - // - options: Optional request customization (headers, timeout, etc.). - // - taskHandler: Optional closure to access the underlying URLSessionTask. - // - completion: Completion handler returning the account, comment list, raw response, and NKError. + /// Retrieves all comments associated with a specific file from the server. + /// This is typically used in collaboration features to display user discussions or annotations. + /// + /// - Parameters: + /// - fileId: Identifier of the file whose comments are being retrieved. + /// - account: The Nextcloud account requesting the comments. + /// - options: Optional request customization (headers, timeout, etc.). + /// - taskHandler: Optional closure to access the underlying URLSessionTask. + /// - completion: Completion handler returning the account, comment list, raw response, and NKError. func getComments(fileId: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -92,16 +92,16 @@ public extension NextcloudKit { } } - // Adds a new comment to a specific file. - // Useful for enabling collaboration or user discussions directly on file items. - // - // Parameters: - // - fileId: Identifier of the file to which the comment will be added. - // - message: The content of the comment to post. - // - account: The Nextcloud account posting the comment. - // - options: Optional HTTP configuration (headers, timeout, etc.). - // - taskHandler: Optional callback to access the URLSessionTask. - // - completion: Completion handler with account, response, and error. + /// Adds a new comment to a specific file. + /// Useful for enabling collaboration or user discussions directly on file items. + /// + /// - Parameters: + /// - fileId: Identifier of the file to which the comment will be added. + /// - message: The content of the comment to post. + /// - account: The Nextcloud account posting the comment. + /// - options: Optional HTTP configuration (headers, timeout, etc.). + /// - taskHandler: Optional callback to access the URLSessionTask. + /// - completion: Completion handler with account, response, and error. func putComments(fileId: String, message: String, account: String, @@ -174,17 +174,17 @@ public extension NextcloudKit { } } - // Updates the content of an existing comment on a file. - // Useful for editing or correcting previously posted comments. - // - // Parameters: - // - fileId: Identifier of the file that contains the comment. - // - messageId: Identifier of the specific comment to be updated. - // - message: The new content to replace the old comment. - // - account: The Nextcloud account performing the update. - // - options: Optional HTTP configuration (e.g., headers, timeout). - // - taskHandler: Optional callback to inspect the created URLSessionTask. - // - completion: Completion handler returning account, response, and NKError. + /// Updates the content of an existing comment on a file. + /// Useful for editing or correcting previously posted comments. + /// + /// - Parameters: + /// - fileId: Identifier of the file that contains the comment. + /// - messageId: Identifier of the specific comment to be updated. + /// - message: The new content to replace the old comment. + /// - account: The Nextcloud account performing the update. + /// - options: Optional HTTP configuration (e.g., headers, timeout). + /// - taskHandler: Optional callback to inspect the created URLSessionTask. + /// - completion: Completion handler returning account, response, and NKError. func updateComments(fileId: String, messageId: String, message: String, @@ -262,16 +262,16 @@ public extension NextcloudKit { } } - // Deletes a specific comment from a file on the server for a given Nextcloud account. - // It performs an HTTP request (typically DELETE) and returns the result through a completion handler. - // - // Parameters: - // - fileId: The identifier of the file the comment belongs to. - // - messageId: The identifier of the comment to be deleted. - // - account: The Nextcloud account performing the operation. - // - options: Optional request options such as custom headers or retry policy (default is empty). - // - taskHandler: A closure to access the underlying URLSessionTask, useful for progress or cancellation. - // - completion: Completion handler returning the account, the raw response (if any), and an NKError. + /// Deletes a specific comment from a file on the server for a given Nextcloud account. + /// It performs an HTTP request (typically DELETE) and returns the result through a completion handler. + /// + /// - Parameters: + /// - fileId: The identifier of the file the comment belongs to. + /// - messageId: The identifier of the comment to be deleted. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request options such as custom headers or retry policy (default is empty). + /// - taskHandler: A closure to access the underlying URLSessionTask, useful for progress or cancellation. + /// - completion: Completion handler returning the account, the raw response (if any), and an NKError. func deleteComments(fileId: String, messageId: String, account: String, @@ -332,15 +332,15 @@ public extension NextcloudKit { } } - // Marks all comments on a given file as read for the specified Nextcloud account. - // It performs an HTTP request (likely POST or PUT) to update the read status on the server. - // - // Parameters: - // - fileId: The identifier of the file whose comments should be marked as read. - // - account: The Nextcloud account performing the operation. - // - options: Optional request options (default is empty). - // - taskHandler: A closure to access the underlying URLSessionTask (default is no-op). - // - completion: Completion handler returning the account, the raw response, and any NKError. + /// Marks all comments on a given file as read for the specified Nextcloud account. + /// It performs an HTTP request (likely POST or PUT) to update the read status on the server. + /// + /// - Parameters: + /// - fileId: The identifier of the file whose comments should be marked as read. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request options (default is empty). + /// - taskHandler: A closure to access the underlying URLSessionTask (default is no-op). + /// - completion: Completion handler returning the account, the raw response, and any NKError. func markAsReadComments(fileId: String, account: String, options: NKRequestOptions = NKRequestOptions(), diff --git a/Sources/NextcloudKit/NextcloudKit+Dashboard.swift b/Sources/NextcloudKit/NextcloudKit+Dashboard.swift index 0e1cd182..0f9c15e5 100644 --- a/Sources/NextcloudKit/NextcloudKit+Dashboard.swift +++ b/Sources/NextcloudKit/NextcloudKit+Dashboard.swift @@ -7,15 +7,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Retrieves the list of dashboard widgets available for the specified Nextcloud account. - // This typically calls the dashboard API endpoint and returns a list of `NCCDashboardWidget` items. - // - // Parameters: - // - account: The Nextcloud account performing the request. - // - options: Optional request options such as custom headers or retry policy (default is empty). - // - request: A closure that receives the underlying Alamofire `DataRequest`, useful for inspection or mutation. - // - taskHandler: A closure to access the `URLSessionTask` for progress or cancellation control. - // - completion: Completion handler returning the account, list of widgets, the raw response, and any NKError. + /// Retrieves the list of dashboard widgets available for the specified Nextcloud account. + /// This typically calls the dashboard API endpoint and returns a list of `NCCDashboardWidget` items. + /// + /// Parameters: + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options such as custom headers or retry policy (default is empty). + /// - request: A closure that receives the underlying Alamofire `DataRequest`, useful for inspection or mutation. + /// - taskHandler: A closure to access the `URLSessionTask` for progress or cancellation control. + /// - completion: Completion handler returning the account, list of widgets, the raw response, and any NKError. func getDashboardWidget(account: String, options: NKRequestOptions = NKRequestOptions(), request: @escaping (DataRequest?) -> Void = { _ in }, @@ -83,16 +83,16 @@ public extension NextcloudKit { } } - // Retrieves the list of dashboard application widgets for the specified account and item string. - // This is typically used to fetch available dashboard apps filtered by `items` (e.g., "weather,tasks"). - // - // Parameters: - // - items: A comma-separated string representing widget types or categories to fetch. - // - account: The Nextcloud account performing the request. - // - options: Optional request options (default is empty). - // - request: A closure that receives the underlying Alamofire `DataRequest`, useful for inspection or mutation. - // - taskHandler: A closure to access the `URLSessionTask` for progress or cancellation. - // - completion: Completion handler returning the account, list of applications, response, and error. + /// Retrieves the list of dashboard application widgets for the specified account and item string. + /// This is typically used to fetch available dashboard apps filtered by `items` (e.g., "weather,tasks"). + /// + /// Parameters: + /// - items: A comma-separated string representing widget types or categories to fetch. + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options (default is empty). + /// - request: A closure that receives the underlying Alamofire `DataRequest`, useful for inspection or mutation. + /// - taskHandler: A closure to access the `URLSessionTask` for progress or cancellation. + /// - completion: Completion handler returning the account, list of applications, response, and error. func getDashboardWidgetsApplication(_ items: String, account: String, options: NKRequestOptions = NKRequestOptions(), diff --git a/Sources/NextcloudKit/NextcloudKit+Download.swift b/Sources/NextcloudKit/NextcloudKit+Download.swift index 8c88b953..0a3f9972 100644 --- a/Sources/NextcloudKit/NextcloudKit+Download.swift +++ b/Sources/NextcloudKit/NextcloudKit+Download.swift @@ -7,18 +7,18 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Downloads a remote file and stores it at a local path for the specified Nextcloud account. - // It provides detailed progress, headers, and metadata such as ETag, last modified date, and content length. - // - // Parameters: - // - serverUrlFileName: A value representing the remote file URL or path (typically String or URL). - // - fileNameLocalPath: The local filesystem path where the file should be saved. - // - account: The Nextcloud account performing the download. - // - options: Optional request options (default is empty). - // - requestHandler: Closure to access the Alamofire `DownloadRequest` (for customization, inspection, etc.). - // - taskHandler: Closure to access the underlying `URLSessionTask` (e.g. for progress or cancellation). - // - progressHandler: Closure that receives periodic progress updates. - // - completionHandler: Completion closure returning metadata: account, ETag, modification date, content length, headers, AFError, and NKError. + /// Downloads a remote file and stores it at a local path for the specified Nextcloud account. + /// It provides detailed progress, headers, and metadata such as ETag, last modified date, and content length. + /// + /// Parameters: + /// - serverUrlFileName: A value representing the remote file URL or path (typically String or URL). + /// - fileNameLocalPath: The local filesystem path where the file should be saved. + /// - account: The Nextcloud account performing the download. + /// - options: Optional request options (default is empty). + /// - requestHandler: Closure to access the Alamofire `DownloadRequest` (for customization, inspection, etc.). + /// - taskHandler: Closure to access the underlying `URLSessionTask` (e.g. for progress or cancellation). + /// - progressHandler: Closure that receives periodic progress updates. + /// - completionHandler: Completion closure returning metadata: account, ETag, modification date, content length, headers, AFError, and NKError. func download(serverUrlFileName: Any, fileNameLocalPath: String, account: String, diff --git a/Sources/NextcloudKit/NextcloudKit+E2EE.swift b/Sources/NextcloudKit/NextcloudKit+E2EE.swift index 725de6c6..92343616 100644 --- a/Sources/NextcloudKit/NextcloudKit+E2EE.swift +++ b/Sources/NextcloudKit/NextcloudKit+E2EE.swift @@ -7,16 +7,16 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Marks or unmarks a folder as End-to-End Encrypted (E2EE) for a given Nextcloud account. - // Depending on the `delete` flag, this function either enables or disables the E2EE status for the folder. - // - // Parameters: - // - fileId: The identifier of the folder to mark/unmark. - // - delete: If `true`, removes the E2EE mark; if `false`, adds the E2EE mark. - // - account: The Nextcloud account performing the operation. - // - options: Optional request options (default is empty). - // - taskHandler: Closure to access the `URLSessionTask` (default is no-op). - // - completion: Completion handler returning the account, raw response, and any NKError. + /// Marks or unmarks a folder as End-to-End Encrypted (E2EE) for a given Nextcloud account. + /// Depending on the `delete` flag, this function either enables or disables the E2EE status for the folder. + /// + /// - Parameters: + /// - fileId: The identifier of the folder to mark/unmark. + /// - delete: If `true`, removes the E2EE mark; if `false`, adds the E2EE mark. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request options (default is empty). + /// - taskHandler: Closure to access the `URLSessionTask` (default is no-op). + /// - completion: Completion handler returning the account, raw response, and any NKError. func markE2EEFolder(fileId: String, delete: Bool, account: String, @@ -88,19 +88,19 @@ public extension NextcloudKit { } } - // Locks or unlocks a folder for End-to-End Encryption (E2EE) using a provided token and counter. - // Depending on the HTTP `method` (e.g. "LOCK", "UNLOCK", "PUT"), the operation will either lock the folder, - // refresh the E2EE token, or perform another action defined by the server API. - // - // Parameters: - // - fileId: The identifier of the folder to lock or unlock. - // - e2eToken: Optional E2EE token used to lock the folder (nil if unlocking). - // - e2eCounter: Optional counter value for token freshness or verification. - // - method: The HTTP method to use for the request (e.g., "LOCK", "PUT", etc.). - // - account: The Nextcloud account performing the request. - // - options: Optional request options (default is empty). - // - taskHandler: Closure to access the `URLSessionTask` (default is no-op). - // - completion: Completion handler returning the account, updated E2EE token, raw response, and any NKError. + /// Locks or unlocks a folder for End-to-End Encryption (E2EE) using a provided token and counter. + /// Depending on the HTTP `method` (e.g. "LOCK", "UNLOCK", "PUT"), the operation will either lock the folder, + /// refresh the E2EE token, or perform another action defined by the server API. + /// + /// - Parameters: + /// - fileId: The identifier of the folder to lock or unlock. + /// - e2eToken: Optional E2EE token used to lock the folder (nil if unlocking). + /// - e2eCounter: Optional counter value for token freshness or verification. + /// - method: The HTTP method to use for the request (e.g., "LOCK", "PUT", etc.). + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options (default is empty). + /// - taskHandler: Closure to access the `URLSessionTask` (default is no-op). + /// - completion: Completion handler returning the account, updated E2EE token, raw response, and any NKError. func lockE2EEFolder(fileId: String, e2eToken: String?, e2eCounter: String?, @@ -192,18 +192,18 @@ public extension NextcloudKit { } } - // Retrieves E2EE metadata and signature for a specific file from the Nextcloud E2EE API. - // It supports different API versions via the `options.version` property (default is "v1"). - // This request is authenticated and validated, and returns both metadata and signature - // (from header `X-NC-E2EE-SIGNATURE`) if the operation is successful. - // - // Parameters: - // - fileId: The file identifier to retrieve metadata for. - // - e2eToken: Optional E2EE token used for authorization or context. - // - account: The Nextcloud account performing the request. - // - options: Optional request options (includes version, queue, task description, etc.). - // - taskHandler: Closure to access the URLSessionTask for progress or control. - // - completion: Completion handler returning the account, metadata string, signature string, response, and NKError. + /// Retrieves E2EE metadata and signature for a specific file from the Nextcloud E2EE API. + /// It supports different API versions via the `options.version` property (default is "v1"). + /// This request is authenticated and validated, and returns both metadata and signature + /// (from header `X-NC-E2EE-SIGNATURE`) if the operation is successful. + /// + /// - Parameters: + /// - fileId: The file identifier to retrieve metadata for. + /// - e2eToken: Optional E2EE token used for authorization or context. + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options (includes version, queue, task description, etc.). + /// - taskHandler: Closure to access the URLSessionTask for progress or control. + /// - completion: Completion handler returning the account, metadata string, signature string, response, and NKError. func getE2EEMetadata(fileId: String, e2eToken: String?, account: String, @@ -284,20 +284,20 @@ public extension NextcloudKit { } } - // Uploads E2EE metadata for a specific file on the Nextcloud server, using the specified HTTP method. - // The request includes the E2E token and optional metadata and signature. The server may return the - // stored metadata back in the response. - // - // Parameters: - // - fileId: The identifier of the file to update metadata for. - // - e2eToken: Required token used to authorize the E2EE update. - // - e2eMetadata: Optional encrypted metadata payload to be stored. - // - signature: Optional signature for integrity/authentication (added to header). - // - method: The HTTP method to use (e.g., "PUT", "POST"). - // - account: The Nextcloud account performing the request. - // - options: Optional request options (includes version, queue, etc.). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, stored metadata (if any), response, and NKError. + /// Uploads E2EE metadata for a specific file on the Nextcloud server, using the specified HTTP method. + /// The request includes the E2E token and optional metadata and signature. The server may return the + /// stored metadata back in the response. + /// + /// - Parameters: + /// - fileId: The identifier of the file to update metadata for. + /// - e2eToken: Required token used to authorize the E2EE update. + /// - e2eMetadata: Optional encrypted metadata payload to be stored. + /// - signature: Optional signature for integrity/authentication (added to header). + /// - method: The HTTP method to use (e.g., "PUT", "POST"). + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options (includes version, queue, etc.). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, stored metadata (if any), response, and NKError. func putE2EEMetadata(fileId: String, e2eToken: String, e2eMetadata: String?, @@ -395,16 +395,16 @@ public extension NextcloudKit { // MARK: - - // Retrieves the public E2EE certificate (public key) for the given account or a specified user. - // If `user` is nil, the certificate for the current account is returned. - // If `user` is provided, the request fetches the public key of that user using a `users=[...]` query parameter. - // - // Parameters: - // - user: Optional username to fetch the public key for. If nil, fetches the current user's key. - // - account: The Nextcloud account performing the request. - // - options: Optional request options (includes version, task description, queue, etc.). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, the certificate string, the certificate user (if applicable), the raw response, and any NKError. + /// Retrieves the public E2EE certificate (public key) for the given account or a specified user. + /// If `user` is nil, the certificate for the current account is returned. + /// If `user` is provided, the request fetches the public key of that user using a `users=[...]` query parameter. + /// + /// - Parameters: + /// - user: Optional username to fetch the public key for. If nil, fetches the current user's key. + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options (includes version, task description, queue, etc.). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, the certificate string, the certificate user (if applicable), the raw response, and any NKError. func getE2EECertificate(user: String? = nil, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -492,15 +492,15 @@ public extension NextcloudKit { } } - // Retrieves the private E2EE key for the current account from the Nextcloud server. - // This key is typically encrypted and used for decrypting user data locally. - // The endpoint used is versioned via `options.version` (default: "v1"). - // - // Parameters: - // - account: The Nextcloud account requesting the private key. - // - options: Optional request options (includes version, queue, etc.). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, private key string, raw response, and NKError. + /// Retrieves the private E2EE key for the current account from the Nextcloud server. + /// This key is typically encrypted and used for decrypting user data locally. + /// The endpoint used is versioned via `options.version` (default: "v1"). + /// + /// - Parameters: + /// - account: The Nextcloud account requesting the private key. + /// - options: Optional request options (includes version, queue, etc.). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, private key string, raw response, and NKError. func getE2EEPrivateKey(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -566,15 +566,15 @@ public extension NextcloudKit { } } - // Retrieves the server's E2EE public key for the current Nextcloud instance. - // This key is used by clients to encrypt data that will be sent to the server. - // The request targets the `server-key` endpoint and returns the PEM-formatted public key. - // - // Parameters: - // - account: The Nextcloud account performing the request. - // - options: Optional request options (includes version, queue, etc.). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, public key string, raw response, and NKError. + /// Retrieves the server's E2EE public key for the current Nextcloud instance. + /// This key is used by clients to encrypt data that will be sent to the server. + /// The request targets the `server-key` endpoint and returns the PEM-formatted public key. + /// + /// - Parameters: + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options (includes version, queue, etc.). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, public key string, raw response, and NKError. func getE2EEPublicKey(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -640,16 +640,16 @@ public extension NextcloudKit { } } - // Sends a certificate signing request (CSR) to the server in order to obtain a signed E2EE public certificate. - // The server responds with a signed public key associated with the account. - // The request is sent via HTTP POST to the `/public-key` endpoint. - // - // Parameters: - // - certificate: The CSR (Certificate Signing Request) in string format to be signed by the server. - // - account: The Nextcloud account performing the request. - // - options: Optional request options (e.g., version, queue, headers). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, signed certificate string, response, and NKError. + /// Sends a certificate signing request (CSR) to the server in order to obtain a signed E2EE public certificate. + /// The server responds with a signed public key associated with the account. + /// The request is sent via HTTP POST to the `/public-key` endpoint. + /// + /// - Parameters: + /// - certificate: The CSR (Certificate Signing Request) in string format to be signed by the server. + /// - account: The Nextcloud account performing the request. + /// - options: Optional request options (e.g., version, queue, headers). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, signed certificate string, response, and NKError. func signE2EECertificate(certificate: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -721,16 +721,16 @@ public extension NextcloudKit { } } - // Stores the user's E2EE private key securely on the Nextcloud server. - // This is typically done during initial key setup or key backup. - // The private key is sent as a POST parameter to the `/private-key` endpoint. - // - // Parameters: - // - privateKey: The PEM-formatted private key string to be stored on the server. - // - account: The Nextcloud account performing the operation. - // - options: Optional request options (versioning, queue dispatch, headers, etc.). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, stored private key (as echoed back), response, and NKError. + /// Stores the user's E2EE private key securely on the Nextcloud server. + /// This is typically done during initial key setup or key backup. + /// The private key is sent as a POST parameter to the `/private-key` endpoint. + /// + /// - Parameters: + /// - privateKey: The PEM-formatted private key string to be stored on the server. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request options (versioning, queue dispatch, headers, etc.). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, stored private key (as echoed back), response, and NKError. func storeE2EEPrivateKey(privateKey: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -801,15 +801,15 @@ public extension NextcloudKit { } } - // Deletes the currently stored E2EE public certificate from the Nextcloud server. - // This is typically used during key revocation or reinitialization of E2EE. - // The request targets the `public-key` endpoint with the HTTP DELETE method. - // - // Parameters: - // - account: The Nextcloud account requesting the deletion of the certificate. - // - options: Optional request options (e.g., version, dispatch queue, headers). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, raw response, and NKError. + /// Deletes the currently stored E2EE public certificate from the Nextcloud server. + /// This is typically used during key revocation or reinitialization of E2EE. + /// The request targets the `public-key` endpoint with the HTTP DELETE method. + /// + /// - Parameters: + /// - account: The Nextcloud account requesting the deletion of the certificate. + /// - options: Optional request options (e.g., version, dispatch queue, headers). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, raw response, and NKError. func deleteE2EECertificate(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -865,15 +865,15 @@ public extension NextcloudKit { } } - // Deletes the user's E2EE private key stored on the Nextcloud server. - // This operation is typically performed when revoking access to the encrypted data, - // or during account reset scenarios. - // - // Parameters: - // - account: The Nextcloud account requesting the deletion of its private key. - // - options: Optional request options (API version, dispatch queue, headers). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, raw response, and NKError. + /// Deletes the user's E2EE private key stored on the Nextcloud server. + /// This operation is typically performed when revoking access to the encrypted data, + /// or during account reset scenarios. + /// + /// - Parameters: + /// - account: The Nextcloud account requesting the deletion of its private key. + /// - options: Optional request options (API version, dispatch queue, headers). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, raw response, and NKError. func deleteE2EEPrivateKey(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, diff --git a/Sources/NextcloudKit/NextcloudKit+FilesLock.swift b/Sources/NextcloudKit/NextcloudKit+FilesLock.swift index fd2267de..215d4e96 100644 --- a/Sources/NextcloudKit/NextcloudKit+FilesLock.swift +++ b/Sources/NextcloudKit/NextcloudKit+FilesLock.swift @@ -7,17 +7,17 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Sends a WebDAV LOCK or UNLOCK request for a file on the server, - // depending on the `shouldLock` flag. This is used to prevent or release - // concurrent edits on a file. - // - // Parameters: - // - serverUrlFileName: Fully qualified and encoded URL of the file to lock/unlock. - // - shouldLock: Pass `true` to lock the file, `false` to unlock it. - // - account: The Nextcloud account performing the operation. - // - options: Optional request options (e.g. headers, queue). - // - taskHandler: Closure to access the URLSessionTask. - // - completion: Completion handler returning the account, response, and NKError. + /// Sends a WebDAV LOCK or UNLOCK request for a file on the server, + /// depending on the `shouldLock` flag. This is used to prevent or release + /// concurrent edits on a file. + /// + /// Parameters: + /// - serverUrlFileName: Fully qualified and encoded URL of the file to lock/unlock. + /// - shouldLock: Pass `true` to lock the file, `false` to unlock it. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request options (e.g. headers, queue). + /// - taskHandler: Closure to access the URLSessionTask. + /// - completion: Completion handler returning the account, response, and NKError. func lockUnlockFile(serverUrlFileName: String, shouldLock: Bool, account: String, diff --git a/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift b/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift index 49fc007f..cb877563 100644 --- a/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift +++ b/Sources/NextcloudKit/NextcloudKit+Groupfolders.swift @@ -8,15 +8,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Retrieves the list of available group folders for the given Nextcloud account. - // Group folders are shared spaces available across users and groups, - // managed via the groupfolders app. - // - // Parameters: - // - account: The Nextcloud account requesting the list of group folders. - // - options: Optional request options (e.g., API version, custom headers, queue). - // - taskHandler: Closure to access the underlying URLSessionTask. - // - completion: Completion handler returning the account, list of group folders, response, and any NKError. + /// Retrieves the list of available group folders for the given Nextcloud account. + /// Group folders are shared spaces available across users and groups, + /// managed via the groupfolders app. + /// + /// Parameters: + /// - account: The Nextcloud account requesting the list of group folders. + /// - options: Optional request options (e.g., API version, custom headers, queue). + /// - taskHandler: Closure to access the underlying URLSessionTask. + /// - completion: Completion handler returning the account, list of group folders, response, and any NKError. func getGroupfolders(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, diff --git a/Sources/NextcloudKit/NextcloudKit+Hovercard.swift b/Sources/NextcloudKit/NextcloudKit+Hovercard.swift index 9c582f83..e0939897 100644 --- a/Sources/NextcloudKit/NextcloudKit+Hovercard.swift +++ b/Sources/NextcloudKit/NextcloudKit+Hovercard.swift @@ -7,6 +7,13 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + /// Retrieves the hovercard information for a specific user from the Nextcloud server. + /// - Parameters: + /// - userId: The identifier of the user whose hovercard is being requested. + /// - account: The Nextcloud account used to perform the request. + /// - options: Optional request options for customizing the API call. + /// - taskHandler: Closure for observing the underlying `URLSessionTask`. + /// - completion: Completion handler returning the account, the `NKHovercard` result, raw response data, and any error encountered. func getHovercard(for userId: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -41,6 +48,38 @@ public extension NextcloudKit { } } } + + /// Asynchronously retrieves the hovercard information for a specific user from the Nextcloud server. + /// - Parameters: + /// - userId: The identifier of the user whose hovercard is being requested. + /// - account: The Nextcloud account used to perform the request. + /// - options: Optional request options for customizing the API call. + /// - taskHandler: Closure for observing the underlying `URLSessionTask`. + /// - Returns: A tuple containing the account, the `NKHovercard` result, raw response data, and any error encountered. + func getHovercardAsync(for userId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + result: NKHovercard?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getHovercard(for: userId, + account: account, + options: options, + taskHandler: taskHandler) { account, result, responseData, error in + continuation.resume(returning: ( + account: account, + result: result, + responseData: responseData, + error: error + )) + } + } + } } public class NKHovercard: NSObject { diff --git a/Sources/NextcloudKit/NextcloudKit+Livephoto.swift b/Sources/NextcloudKit/NextcloudKit+Livephoto.swift index c77a965e..c3d50552 100644 --- a/Sources/NextcloudKit/NextcloudKit+Livephoto.swift +++ b/Sources/NextcloudKit/NextcloudKit+Livephoto.swift @@ -6,15 +6,15 @@ import Foundation import Alamofire public extension NextcloudKit { - // Associates a Live Photo video file with a photo on the server. - // - // Parameters: - // - serverUrlfileNamePath: The full server path to the original photo. - // - livePhotoFile: The local path to the Live Photo video file (.mov). - // - account: The account performing the operation. - // - options: Optional request configuration (e.g., headers, queue, version). - // - taskHandler: Callback for tracking the underlying URLSessionTask. - // - completion: Returns the account, raw response data, and NKError result. + /// Associates a Live Photo video file with a photo on the server. + /// + /// Parameters: + /// - serverUrlfileNamePath: The full server path to the original photo. + /// - livePhotoFile: The local path to the Live Photo video file (.mov). + /// - account: The account performing the operation. + /// - options: Optional request configuration (e.g., headers, queue, version). + /// - taskHandler: Callback for tracking the underlying URLSessionTask. + /// - completion: Returns the account, raw response data, and NKError result. func setLivephoto(serverUrlfileNamePath: String, livePhotoFile: String, account: String, diff --git a/Sources/NextcloudKit/NextcloudKit+Login.swift b/Sources/NextcloudKit/NextcloudKit+Login.swift index 8721738c..f6e1e9ef 100644 --- a/Sources/NextcloudKit/NextcloudKit+Login.swift +++ b/Sources/NextcloudKit/NextcloudKit+Login.swift @@ -9,16 +9,16 @@ import SwiftyJSON public extension NextcloudKit { // MARK: - App Password - // Retrieves an app password (token) for the given user credentials and server URL. - // - // Parameters: - // - url: The base server URL (e.g., https://cloud.example.com). - // - user: The username for authentication. - // - password: The user's password. - // - userAgent: Optional user-agent string to include in the request. - // - options: Optional request configuration (headers, queue, etc.). - // - taskHandler: Callback for observing the underlying URLSessionTask. - // - completion: Returns the token string (if any), raw response data, and NKError result. + /// Retrieves an app password (token) for the given user credentials and server URL. + /// + /// Parameters: + /// - url: The base server URL (e.g., https://cloud.example.com). + /// - user: The username for authentication. + /// - password: The user's password. + /// - userAgent: Optional user-agent string to include in the request. + /// - options: Optional request configuration (headers, queue, etc.). + /// - taskHandler: Callback for observing the underlying URLSessionTask. + /// - completion: Returns the token string (if any), raw response data, and NKError result. func getAppPassword(url: String, user: String, password: String, @@ -95,17 +95,17 @@ public extension NextcloudKit { } } - // Deletes the app password (token) for a specific account using basic authentication. - // - // Parameters: - // - serverUrl: The full server URL (e.g., https://cloud.example.com). - // - username: The username associated with the app password. - // - password: The password or app password used for authentication. - // - userAgent: Optional user-agent string for the request. - // - account: The logical account identifier used in the app. - // - options: Optional request configuration (headers, queues, etc.). - // - taskHandler: Callback to observe the underlying URLSessionTask. - // - completion: Returns the raw response and a possible NKError result. + /// Deletes the app password (token) for a specific account using basic authentication. + /// + /// Parameters: + /// - serverUrl: The full server URL (e.g., https://cloud.example.com). + /// - username: The username associated with the app password. + /// - password: The password or app password used for authentication. + /// - userAgent: Optional user-agent string for the request. + /// - account: The logical account identifier used in the app. + /// - options: Optional request configuration (headers, queues, etc.). + /// - taskHandler: Callback to observe the underlying URLSessionTask. + /// - completion: Returns the raw response and a possible NKError result. func deleteAppPassword(serverUrl: String, username: String, password: String, @@ -219,6 +219,19 @@ public extension NextcloudKit { } } + /// Starts the Login Flow v2 process by requesting a login token and associated parameters from the server. + /// + /// - Parameters: + /// - serverUrl: The base URL of the Nextcloud server used to initiate the login flow. + /// - options: An optional `NKRequestOptions` object containing configuration such as API version, custom headers, and execution queue. + /// - taskHandler: A closure that provides the `URLSessionTask` used for the request. Useful for monitoring or cancellation. + /// + /// - Completion: + /// - token: The login token used for polling the login status. + /// - endpoint: The endpoint URL to be polled to check login completion. + /// - login: A user-visible login URL that can be presented to complete authentication. + /// - responseData: The raw `AFDataResponse` received from the server. + /// - error: An `NKError` object representing success or failure of the operation. func getLoginFlowV2(serverUrl: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -252,14 +265,45 @@ public extension NextcloudKit { } } - // Polls the login flow V2 endpoint to retrieve login credentials (OAuth-style). - // - // Parameters: - // - token: The login flow token to poll for. - // - endpoint: The base URL endpoint (e.g., https://cloud.example.com). - // - options: Optional request configuration (version, headers, queues, etc.). - // - taskHandler: Callback to observe the underlying URLSessionTask. - // - completion: Returns the discovered server URL, loginName, appPassword, the raw response data, and any NKError. + /// Asynchronously initiates the Login Flow v2 process to obtain authentication parameters. + /// - Parameters: + /// - serverUrl: The base URL of the Nextcloud server. + /// - options: Optional request configuration for API version, queue, etc. + /// - taskHandler: Optional callback to observe the `URLSessionTask`. + /// - Returns: A tuple containing the login token, polling endpoint, login URL, response data, and any encountered error. + func getLoginFlowV2Async(serverUrl: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + token: String?, + endpoint: String?, + login: String?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getLoginFlowV2(serverUrl: serverUrl, + options: options, + taskHandler: taskHandler) { token, endpoint, login, responseData, error in + continuation.resume(returning: ( + token: token, + endpoint: endpoint, + login: login, + responseData: responseData, + error: error + )) + } + } + } + + /// Polls the login flow V2 endpoint to retrieve login credentials (OAuth-style). + /// + /// Parameters: + /// - token: The login flow token to poll for. + /// - endpoint: The base URL endpoint (e.g., https://cloud.example.com). + /// - options: Optional request configuration (version, headers, queues, etc.). + /// - taskHandler: Callback to observe the underlying URLSessionTask. + /// - completion: Returns the discovered server URL, loginName, appPassword, the raw response data, and any NKError. func getLoginFlowV2Poll(token: String, endpoint: String, options: NKRequestOptions = NKRequestOptions(), From 3d8cd3124e1a62bf3071cd05dd6fda6b4403a6e6 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 15:07:07 +0200 Subject: [PATCH 08/10] doc Signed-off-by: Marino Faggiana --- .../NextcloudKit/NextcloudKit+NCText.swift | 70 +++---- .../NextcloudKit+PushNotification.swift | 84 ++++---- .../NextcloudKit+RecommendedFiles.swift | 18 +- .../NextcloudKit+Richdocuments.swift | 68 +++--- .../NextcloudKit/NextcloudKit+Search.swift | 112 +++++----- .../NextcloudKit+ShareDownloadLimit.swift | 94 ++++----- .../NextcloudKit/NextcloudKit+Upload.swift | 150 +++++++------- .../NextcloudKit+UserStatus.swift | 194 +++++++++--------- 8 files changed, 400 insertions(+), 390 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+NCText.swift b/Sources/NextcloudKit/NextcloudKit+NCText.swift index 1925e54f..03b61d5b 100644 --- a/Sources/NextcloudKit/NextcloudKit+NCText.swift +++ b/Sources/NextcloudKit/NextcloudKit+NCText.swift @@ -7,13 +7,13 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Retrieves the list of editors and creators for collaborative text editing. - // - // Parameters: - // - account: The account from which to fetch the editor details. - // - options: Optional request configuration such as headers, queue, or API version. - // - taskHandler: Callback to track the underlying URLSessionTask. - // - completion: Returns the account, array of editors, array of creators, the raw response data, and NKError. + /// Retrieves the list of editors and creators for collaborative text editing. + /// + /// Parameters: + /// - account: The account from which to fetch the editor details. + /// - options: Optional request configuration such as headers, queue, or API version. + /// - taskHandler: Callback to track the underlying URLSessionTask. + /// - completion: Returns the account, array of editors, array of creators, the raw response data, and NKError. func textObtainEditorDetails(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -89,16 +89,16 @@ public extension NextcloudKit { } } - // Opens a file using the specified text editor and returns the access URL. - // - // Parameters: - // - fileNamePath: The path of the file to open on the server. - // - fileId: Optional file identifier used to reference the file more precisely. - // - editor: The identifier of the text editor to use. - // - account: The account initiating the file open request. - // - options: Optional configuration for the request (headers, API version, etc.). - // - taskHandler: Callback triggered with the underlying URLSessionTask. - // - completion: Returns the account, the resulting file editor URL, raw response data, and an NKError. + /// Opens a file using the specified text editor and returns the access URL. + /// + /// Parameters: + /// - fileNamePath: The path of the file to open on the server. + /// - fileId: Optional file identifier used to reference the file more precisely. + /// - editor: The identifier of the text editor to use. + /// - account: The account initiating the file open request. + /// - options: Optional configuration for the request (headers, API version, etc.). + /// - taskHandler: Callback triggered with the underlying URLSessionTask. + /// - completion: Returns the account, the resulting file editor URL, raw response data, and an NKError. func textOpenFile(fileNamePath: String, fileId: String? = nil, editor: String, @@ -174,13 +174,13 @@ public extension NextcloudKit { } } - // Retrieves the list of available editor templates for the given account. - // - // Parameters: - // - account: The account requesting the list of templates. - // - options: Optional request configuration such as headers, queue, or API version. - // - taskHandler: Callback triggered with the underlying URLSessionTask. - // - completion: Returns the account, an optional array of NKEditorTemplate, the raw response, and an NKError. + /// Retrieves the list of available editor templates for the given account. + /// + /// Parameters: + /// - account: The account requesting the list of templates. + /// - options: Optional request configuration such as headers, queue, or API version. + /// - taskHandler: Callback triggered with the underlying URLSessionTask. + /// - completion: Returns the account, an optional array of NKEditorTemplate, the raw response, and an NKError. func textGetListOfTemplates(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -250,17 +250,17 @@ public extension NextcloudKit { } } - // Creates a new file using a specific editor, creator, and template. - // - // Parameters: - // - fileNamePath: The full destination path where the new file will be created. - // - editorId: The identifier of the editor to use (e.g., "richdocuments"). - // - creatorId: The identifier of the creator (e.g., "document", "spreadsheet"). - // - templateId: The identifier of the template to use for this file. - // - account: The account performing the operation. - // - options: Optional request configuration (headers, queue, version, etc.). - // - taskHandler: Callback to monitor the underlying URLSessionTask. - // - completion: Returns the account, the resulting file URL (if any), the raw response, and NKError. + /// Creates a new file using a specific editor, creator, and template. + /// + /// Parameters: + /// - fileNamePath: The full destination path where the new file will be created. + /// - editorId: The identifier of the editor to use (e.g., "richdocuments"). + /// - creatorId: The identifier of the creator (e.g., "document", "spreadsheet"). + /// - templateId: The identifier of the template to use for this file. + /// - account: The account performing the operation. + /// - options: Optional request configuration (headers, queue, version, etc.). + /// - taskHandler: Callback to monitor the underlying URLSessionTask. + /// - completion: Returns the account, the resulting file URL (if any), the raw response, and NKError. func textCreateFile(fileNamePath: String, editorId: String, creatorId: String, diff --git a/Sources/NextcloudKit/NextcloudKit+PushNotification.swift b/Sources/NextcloudKit/NextcloudKit+PushNotification.swift index 5338b679..aa3078ae 100644 --- a/Sources/NextcloudKit/NextcloudKit+PushNotification.swift +++ b/Sources/NextcloudKit/NextcloudKit+PushNotification.swift @@ -7,17 +7,17 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Subscribes the current device to push notifications. - // - // Parameters: - // - serverUrl: The base server URL for the Nextcloud instance. - // - pushTokenHash: Hashed device push token, used for identification. - // - devicePublicKey: The public key of the device for encryption/authentication. - // - proxyServerUrl: The URL of the proxy push server. - // - account: The Nextcloud account performing the subscription. - // - options: Optional request configuration (headers, version, etc.). - // - taskHandler: Callback to monitor the `URLSessionTask`. - // - completion: Returns the account, device identifier, push signature, public key, response data, and NKError. + /// Subscribes the current device to push notifications. + /// + /// Parameters: + /// - serverUrl: The base server URL for the Nextcloud instance. + /// - pushTokenHash: Hashed device push token, used for identification. + /// - devicePublicKey: The public key of the device for encryption/authentication. + /// - proxyServerUrl: The URL of the proxy push server. + /// - account: The Nextcloud account performing the subscription. + /// - options: Optional request configuration (headers, version, etc.). + /// - taskHandler: Callback to monitor the `URLSessionTask`. + /// - completion: Returns the account, device identifier, push signature, public key, response data, and NKError. func subscribingPushNotification(serverUrl: String, pushTokenHash: String, devicePublicKey: String, @@ -107,14 +107,14 @@ public extension NextcloudKit { } } - // Unsubscribes the current device from push notifications. - // - // Parameters: - // - serverUrl: The base server URL of the Nextcloud instance. - // - account: The Nextcloud account performing the unsubscription. - // - options: Optional request configuration (headers, queue, etc.). - // - taskHandler: Callback to monitor the `URLSessionTask`. - // - completion: Returns the account, raw response data, and NKError. + /// Unsubscribes the current device from push notifications. + /// + /// Parameters: + /// - serverUrl: The base server URL of the Nextcloud instance. + /// - account: The Nextcloud account performing the unsubscription. + /// - options: Optional request configuration (headers, queue, etc.). + /// - taskHandler: Callback to monitor the `URLSessionTask`. + /// - completion: Returns the account, raw response data, and NKError. func unsubscribingPushNotification(serverUrl: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -172,18 +172,18 @@ public extension NextcloudKit { } } - // Subscribes a device to the push proxy server for receiving push notifications. - // - // Parameters: - // - proxyServerUrl: The URL of the push proxy server. - // - pushToken: The token representing the push notification subscription. - // - deviceIdentifier: A unique identifier for the device. - // - signature: A signature to validate the subscription. - // - publicKey: The public key associated with the device. - // - account: The Nextcloud account performing the subscription. - // - options: Optional request customization. - // - taskHandler: Callback for tracking the underlying URLSessionTask. - // - completion: Returns the account, raw response data, and NKError. + /// Subscribes a device to the push proxy server for receiving push notifications. + /// + /// Parameters: + /// - proxyServerUrl: The URL of the push proxy server. + /// - pushToken: The token representing the push notification subscription. + /// - deviceIdentifier: A unique identifier for the device. + /// - signature: A signature to validate the subscription. + /// - publicKey: The public key associated with the device. + /// - account: The Nextcloud account performing the subscription. + /// - options: Optional request customization. + /// - taskHandler: Callback for tracking the underlying URLSessionTask. + /// - completion: Returns the account, raw response data, and NKError. func subscribingPushProxy(proxyServerUrl: String, pushToken: String, deviceIdentifier: String, @@ -264,17 +264,17 @@ public extension NextcloudKit { } } - // Unsubscribes a device from the push proxy server. - // - // Parameters: - // - proxyServerUrl: The URL of the push proxy server. - // - deviceIdentifier: A unique identifier for the device. - // - signature: A cryptographic signature to authenticate the request. - // - publicKey: The public key associated with the device. - // - account: The Nextcloud account initiating the request. - // - options: Optional configuration for the request (queue, headers, version, etc.). - // - taskHandler: Callback triggered when the underlying URLSessionTask is created. - // - completion: Completion handler with account, response data, and NKError result. + /// Unsubscribes a device from the push proxy server. + /// + /// Parameters: + /// - proxyServerUrl: The URL of the push proxy server. + /// - deviceIdentifier: A unique identifier for the device. + /// - signature: A cryptographic signature to authenticate the request. + /// - publicKey: The public key associated with the device. + /// - account: The Nextcloud account initiating the request. + /// - options: Optional configuration for the request (queue, headers, version, etc.). + /// - taskHandler: Callback triggered when the underlying URLSessionTask is created. + /// - completion: Completion handler with account, response data, and NKError result. func unsubscribingPushProxy(proxyServerUrl: String, deviceIdentifier: String, signature: String, diff --git a/Sources/NextcloudKit/NextcloudKit+RecommendedFiles.swift b/Sources/NextcloudKit/NextcloudKit+RecommendedFiles.swift index 4e27a69c..2b5a2121 100644 --- a/Sources/NextcloudKit/NextcloudKit+RecommendedFiles.swift +++ b/Sources/NextcloudKit/NextcloudKit+RecommendedFiles.swift @@ -7,15 +7,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Retrieves a list of recommended files from the server. - // - // Parameters: - // - account: The Nextcloud account used to perform the request. - // - options: Optional configuration for headers, queue, versioning, etc. - // - request: Optional callback to observe or manipulate the underlying DataRequest. - // - taskHandler: Callback triggered when the URLSessionTask is created. - // - completion: Completion handler returning the account, the list of recommendations, - // the raw response data, and an NKError result. + /// Retrieves a list of recommended files from the server. + /// + /// Parameters: + /// - account: The Nextcloud account used to perform the request. + /// - options: Optional configuration for headers, queue, versioning, etc. + /// - request: Optional callback to observe or manipulate the underlying DataRequest. + /// - taskHandler: Callback triggered when the URLSessionTask is created. + /// - completion: Completion handler returning the account, the list of recommendations, + /// the raw response data, and an NKError result. func getRecommendedFiles(account: String, options: NKRequestOptions = NKRequestOptions(), request: @escaping (DataRequest?) -> Void = { _ in }, diff --git a/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift b/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift index b3dc161d..39133729 100644 --- a/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift +++ b/Sources/NextcloudKit/NextcloudKit+Richdocuments.swift @@ -7,15 +7,15 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Requests a URL for editing or viewing a file via the Richdocuments (Collabora/OnlyOffice) app. - // - // Parameters: - // - fileID: The unique identifier of the file for which the document URL is requested. - // - account: The Nextcloud account performing the request. - // - options: Optional configuration such as custom headers, queue, or API version. - // - taskHandler: Callback invoked when the underlying URLSessionTask is created. - // - completion: Completion handler returning the account, document URL (if available), - // the raw HTTP response, and an NKError object. + /// Requests a URL for editing or viewing a file via the Richdocuments (Collabora/OnlyOffice) app. + /// + /// Parameters: + /// - fileID: The unique identifier of the file for which the document URL is requested. + /// - account: The Nextcloud account performing the request. + /// - options: Optional configuration such as custom headers, queue, or API version. + /// - taskHandler: Callback invoked when the underlying URLSessionTask is created. + /// - completion: Completion handler returning the account, document URL (if available), + /// the raw HTTP response, and an NKError object. func createUrlRichdocuments(fileID: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -82,14 +82,14 @@ public extension NextcloudKit { } } - // Retrieves the list of Richdocuments templates of a given type (e.g., "document", "spreadsheet"). - // - // Parameters: - // - typeTemplate: The type of template to retrieve (e.g., "document", "presentation"). - // - account: The Nextcloud account performing the request. - // - options: Optional configuration (headers, queue, API version, etc.). - // - taskHandler: Callback invoked when the underlying URLSessionTask is created. - // - completion: Completion handler returning the account, array of templates, response data, and NKError. + /// Retrieves the list of Richdocuments templates of a given type (e.g., "document", "spreadsheet"). + /// + /// Parameters: + /// - typeTemplate: The type of template to retrieve (e.g., "document", "presentation"). + /// - account: The Nextcloud account performing the request. + /// - options: Optional configuration (headers, queue, API version, etc.). + /// - taskHandler: Callback invoked when the underlying URLSessionTask is created. + /// - completion: Completion handler returning the account, array of templates, response data, and NKError. func getTemplatesRichdocuments(typeTemplate: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -167,15 +167,15 @@ public extension NextcloudKit { } } - // Creates a new Richdocuments file using a specific template. - // - // Parameters: - // - path: The target path where the new document should be created. - // - templateId: The ID of the Richdocuments template to use. - // - account: The Nextcloud account performing the request. - // - options: Optional request configuration (headers, queue, API version, etc.). - // - taskHandler: Callback invoked when the underlying URLSessionTask is created. - // - completion: Completion handler returning the account, resulting file URL, raw response, and NKError. + /// Creates a new Richdocuments file using a specific template. + /// + /// Parameters: + /// - path: The target path where the new document should be created. + /// - templateId: The ID of the Richdocuments template to use. + /// - account: The Nextcloud account performing the request. + /// - options: Optional request configuration (headers, queue, API version, etc.). + /// - taskHandler: Callback invoked when the underlying URLSessionTask is created. + /// - completion: Completion handler returning the account, resulting file URL, raw response, and NKError. func createRichdocuments(path: String, templateId: String, account: String, @@ -246,14 +246,14 @@ public extension NextcloudKit { } } - // Creates a new Richdocuments file based on a default asset (no template). - // - // Parameters: - // - path: The destination path where the asset will be created. - // - account: The Nextcloud account initiating the creation. - // - options: Optional configuration for the request (e.g. headers, queue, API version). - // - taskHandler: Callback invoked when the underlying URLSessionTask is created. - // - completion: Completion handler returning account, resulting file URL, raw response data, and NKError. + /// Creates a new Richdocuments file based on a default asset (no template). + /// + /// Parameters: + /// - path: The destination path where the asset will be created. + /// - account: The Nextcloud account initiating the creation. + /// - options: Optional configuration for the request (e.g. headers, queue, API version). + /// - taskHandler: Callback invoked when the underlying URLSessionTask is created. + /// - completion: Completion handler returning account, resulting file URL, raw response data, and NKError. func createAssetRichdocuments(path: String, account: String, options: NKRequestOptions = NKRequestOptions(), diff --git a/Sources/NextcloudKit/NextcloudKit+Search.swift b/Sources/NextcloudKit/NextcloudKit+Search.swift index cfbf0cb5..0bd64619 100644 --- a/Sources/NextcloudKit/NextcloudKit+Search.swift +++ b/Sources/NextcloudKit/NextcloudKit+Search.swift @@ -8,21 +8,21 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Available NC >= 20 - // Performs a unified search using multiple providers and returns results asynchronously. - // - // Parameters: - // - term: The search term to query. - // - timeout: The individual request timeout per provider. - // - timeoutProvider: The maximum time allowed for each provider before being cancelled. - // - account: The Nextcloud account performing the search. - // - options: Optional configuration for the request (headers, queue, etc.). - // - filter: A closure to filter which `NKSearchProvider` are enabled. - // - request: Callback to access and inspect the underlying `DataRequest?`. - // - taskHandler: Callback triggered when a `URLSessionTask` is created. - // - providers: Callback providing the list of providers that will be queried. - // - update: Called for every result update from a provider. - // - completion: Called when all providers are finished, returns the response and status. + /// Available NC >= 20 + /// Performs a unified search using multiple providers and returns results asynchronously. + /// + /// - Parameters: + /// - term: The search term to query. + /// - timeout: The individual request timeout per provider. + /// - timeoutProvider: The maximum time allowed for each provider before being cancelled. + /// - account: The Nextcloud account performing the search. + /// - options: Optional configuration for the request (headers, queue, etc.). + /// - filter: A closure to filter which `NKSearchProvider` are enabled. + /// - request: Callback to access and inspect the underlying `DataRequest?`. + /// - taskHandler: Callback triggered when a `URLSessionTask` is created. + /// - providers: Callback providing the list of providers that will be queried. + /// - update: Called for every result update from a provider. + /// - completion: Called when all providers are finished, returns the response and status. func unifiedSearch(term: String, timeout: TimeInterval = 30, timeoutProvider: TimeInterval = 60, @@ -77,20 +77,20 @@ public extension NextcloudKit { request(requestUnifiedSearch) } - // Asynchronously performs a unified search and returns the final search response. - // - // - Parameters: - // - term: The string to search for. - // - timeout: Per-provider timeout in seconds. - // - timeoutProvider: Overall timeout for a provider. - // - account: The account used to authenticate the request. - // - options: Optional parameters for the search. - // - filter: Closure to filter the search providers. - // - request: Callback with the underlying `DataRequest?`. - // - taskHandler: Monitors the task creation. - // - providers: Callback that reports which providers are used. - // - update: Callback triggered as results come in from providers. - // - Returns: Final completion with account, raw response data, and NKError. + /// Asynchronously performs a unified search and returns the final search response. + /// + /// - Parameters: + /// - term: The string to search for. + /// - timeout: Per-provider timeout in seconds. + /// - timeoutProvider: Overall timeout for a provider. + /// - account: The account used to authenticate the request. + /// - options: Optional parameters for the search. + /// - filter: Closure to filter the search providers. + /// - request: Callback with the underlying `DataRequest?`. + /// - taskHandler: Monitors the task creation. + /// - providers: Callback that reports which providers are used. + /// - update: Callback triggered as results come in from providers. + /// - Returns: Final completion with account, raw response data, and NKError. func unifiedSearchAsync(term: String, timeout: TimeInterval = 30, timeoutProvider: TimeInterval = 60, @@ -126,20 +126,21 @@ public extension NextcloudKit { } } - // Available NC >= 20 - // Performs a search using a specified provider with pagination and timeout support. - // - // Parameters: - // - id: The identifier of the search provider to use. - // - term: The search term. - // - limit: Optional maximum number of results to return. - // - cursor: Optional pagination cursor for subsequent requests. - // - timeout: The timeout interval for the search request. - // - account: The Nextcloud account performing the search. - // - options: Optional request configuration such as headers and queue. - // - taskHandler: Callback to observe the underlying URLSessionTask. - // - completion: Completion handler returning the account, search results, raw response, and NKError. - // - Returns: The underlying DataRequest object if the request was started, otherwise nil. + /// Available NC >= 20 + /// Performs a search using a specified provider with pagination and timeout support. + /// + /// - Parameters: + /// - id: The identifier of the search provider to use. + /// - term: The search term. + /// - limit: Optional maximum number of results to return. + /// - cursor: Optional pagination cursor for subsequent requests. + /// - timeout: The timeout interval for the search request. + /// - account: The Nextcloud account performing the search. + /// - options: Optional request configuration such as headers and queue. + /// - taskHandler: Callback to observe the underlying URLSessionTask. + /// - completion: Completion handler returning the account, search results, raw response, and NKError. + /// + /// - Returns: The underlying DataRequest object if the request was started, otherwise nil. func searchProvider(_ id: String, term: String, limit: Int? = nil, @@ -198,18 +199,19 @@ public extension NextcloudKit { return requestSearchProvider } - // Asynchronously performs a search request using the specified provider. - // - // Parameters: - // - id: The identifier of the search provider to use. - // - term: The search query string. - // - limit: Optional limit for number of results. - // - cursor: Optional pagination cursor. - // - timeout: The timeout for the request. - // - account: The Nextcloud account performing the request. - // - options: Optional configuration options for the request. - // - taskHandler: Callback to observe the created task. - // Returns: A tuple containing the account, search result, response data, and error. + /// Asynchronously performs a search request using the specified provider. + /// + /// - Parameters: + /// - id: The identifier of the search provider to use. + /// - term: The search query string. + /// - limit: Optional limit for number of results. + /// - cursor: Optional pagination cursor. + /// - timeout: The timeout for the request. + /// - account: The Nextcloud account performing the request. + /// - options: Optional configuration options for the request. + /// - taskHandler: Callback to observe the created task. + /// + /// - Returns: A tuple containing the account, search result, response data, and error. func searchProviderAsync(_ id: String, term: String, limit: Int? = nil, diff --git a/Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift b/Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift index 0018f6dc..a2f78314 100644 --- a/Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift +++ b/Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift @@ -11,14 +11,14 @@ public extension NextcloudKit { "ocs/v2.php/apps/files_downloadlimit/api/v1/\(token)/limit" } - // Retrieves the current download limit for a shared file based on its public share token. - // - // Parameters: - // - account: The Nextcloud account identifier. - // - token: The public share token associated with the file or folder. - // - completion: A closure returning: - // - NKDownloadLimit?: The current download limit information, or `nil` if not available. - // - NKError: An object representing success or error during the request. + /// Retrieves the current download limit for a shared file based on its public share token. + /// + /// Parameters: + /// - account: The Nextcloud account identifier. + /// - token: The public share token associated with the file or folder. + /// - completion: A closure returning: + /// - NKDownloadLimit?: The current download limit information, or `nil` if not available. + /// - NKError: An object representing success or error during the request. func getDownloadLimit(account: String, token: String, completion: @escaping (NKDownloadLimit?, NKError) -> Void) { let endpoint = makeEndpoint(with: token) let options = NKRequestOptions() @@ -84,15 +84,15 @@ public extension NextcloudKit { } } - // Retrieves the current download limit for a shared file using its public token. - // - // Parameters: - // - account: The account associated with the Nextcloud session. - // - token: The public share token used to identify the shared file. - // - // Returns: A tuple containing: - // - downloadLimit: The current NKDownloadLimit object if available. - // - error: The NKError representing success or failure of the request. + /// Retrieves the current download limit for a shared file using its public token. + /// + /// Parameters: + /// - account: The account associated with the Nextcloud session. + /// - token: The public share token used to identify the shared file. + /// + /// Returns: A tuple containing: + /// - downloadLimit: The current NKDownloadLimit object if available. + /// - error: The NKError representing success or failure of the request. func getDownloadLimitAsync(account: String, token: String) async -> ( downloadLimit: NKDownloadLimit?, error: NKError @@ -107,13 +107,13 @@ public extension NextcloudKit { } } - // Removes the download limit for a shared file using its public share token. - // - // Parameters: - // - account: The Nextcloud account identifier. - // - token: The public share token associated with the file or folder. - // - completion: A closure returning: - // - NKError: An object representing the success or failure of the request. + /// Removes the download limit for a shared file using its public share token. + /// + /// Parameters: + /// - account: The Nextcloud account identifier. + /// - token: The public share token associated with the file or folder. + /// - completion: A closure returning: + /// - NKError: An object representing the success or failure of the request. func removeShareDownloadLimit(account: String, token: String, completion: @escaping (_ error: NKError) -> Void) { let endpoint = makeEndpoint(with: token) let options = NKRequestOptions() @@ -146,13 +146,13 @@ public extension NextcloudKit { } } - // Asynchronously removes the download limit for a public shared file or folder. - // - // Parameters: - // - account: The Nextcloud account used for the request. - // - token: The public token representing the shared resource. - // - // Returns: An NKError that indicates the outcome of the operation. + /// Asynchronously removes the download limit for a public shared file or folder. + /// + /// Parameters: + /// - account: The Nextcloud account used for the request. + /// - token: The public token representing the shared resource. + /// + /// Returns: An NKError that indicates the outcome of the operation. func removeShareDownloadLimitAsync(account: String, token: String) async -> NKError { await withCheckedContinuation { continuation in removeShareDownloadLimit(account: account, token: token) { error in @@ -161,14 +161,14 @@ public extension NextcloudKit { } } - // Sets a download limit for a public shared file or folder. - // - // Parameters: - // - account: The Nextcloud account associated with the request. - // - token: The public share token identifying the shared resource. - // - limit: The new download limit to be set. - // - completion: A closure returning: - // - error: An NKError representing the success or failure of the operation. + /// Sets a download limit for a public shared file or folder. + /// + /// Parameters: + /// - account: The Nextcloud account associated with the request. + /// - token: The public share token identifying the shared resource. + /// - limit: The new download limit to be set. + /// - completion: A closure returning: + /// - error: An NKError representing the success or failure of the operation. func setShareDownloadLimit(account: String, token: String, limit: Int, completion: @escaping (_ error: NKError) -> Void) { let endpoint = makeEndpoint(with: token) let options = NKRequestOptions() @@ -207,14 +207,14 @@ public extension NextcloudKit { } } - // Asynchronously sets a download limit for a public shared file or folder. - // - // Parameters: - // - account: The Nextcloud account used for the request. - // - token: The public share token of the resource. - // - limit: The maximum number of downloads to allow. - // - // Returns: An NKError indicating whether the operation was successful. + /// Asynchronously sets a download limit for a public shared file or folder. + /// + /// Parameters: + /// - account: The Nextcloud account used for the request. + /// - token: The public share token of the resource. + /// - limit: The maximum number of downloads to allow. + /// + /// Returns: An NKError indicating whether the operation was successful. func setShareDownloadLimitAsync(account: String, token: String, limit: Int) async -> NKError { await withCheckedContinuation { continuation in setShareDownloadLimit(account: account, token: token, limit: limit) { error in diff --git a/Sources/NextcloudKit/NextcloudKit+Upload.swift b/Sources/NextcloudKit/NextcloudKit+Upload.swift index 8c94677e..15241b57 100644 --- a/Sources/NextcloudKit/NextcloudKit+Upload.swift +++ b/Sources/NextcloudKit/NextcloudKit+Upload.swift @@ -7,27 +7,27 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Uploads a file to the Nextcloud server. - // - // Parameters: - // - serverUrlFileName: The remote server URL or path where the file will be uploaded. - // - fileNameLocalPath: The local file path to be uploaded. - // - dateCreationFile: Optional creation date to include in headers (X-OC-CTime). - // - dateModificationFile: Optional modification date to include in headers (X-OC-MTime). - // - overwrite: If true, the remote file will be overwritten if it already exists. - // - account: The account associated with the upload session. - // - options: Optional configuration for the request (headers, queue, timeout, etc.). - // - requestHandler: Called with the created UploadRequest. - // - taskHandler: Called with the underlying URLSessionTask when it's created. - // - progressHandler: Called periodically with upload progress. - // - completionHandler: Called at the end of the upload with: - // - account: The account used, - // - ocId: The server-side file identifier, - // - etag: The entity tag for versioning, - // - date: The server date of the operation, - // - size: The total uploaded size in bytes, - // - headers: The response headers, - // - nkError: The result status. + /// Uploads a file to the Nextcloud server. + /// + /// - Parameters: + /// - serverUrlFileName: The remote server URL or path where the file will be uploaded. + /// - fileNameLocalPath: The local file path to be uploaded. + /// - dateCreationFile: Optional creation date to include in headers (X-OC-CTime). + /// - dateModificationFile: Optional modification date to include in headers (X-OC-MTime). + /// - overwrite: If true, the remote file will be overwritten if it already exists. + /// - account: The account associated with the upload session. + /// - options: Optional configuration for the request (headers, queue, timeout, etc.). + /// - requestHandler: Called with the created UploadRequest. + /// - taskHandler: Called with the underlying URLSessionTask when it's created. + /// - progressHandler: Called periodically with upload progress. + /// - completionHandler: Called at the end of the upload with: + /// - account: The account used. + /// - ocId: The server-side file identifier. + /// - etag: The entity tag for versioning. + /// - date: The server date of the operation. + /// - size: The total uploaded size in bytes. + /// - headers: The response headers. + /// - nkError: The result status. func upload(serverUrlFileName: Any, fileNameLocalPath: String, dateCreationFile: Date? = nil, @@ -76,7 +76,7 @@ public extension NextcloudKit { } .responseData(queue: self.nkCommonInstance.backgroundQueue) { response in var ocId: String?, etag: String?, date: Date? var result: NKError - + if self.nkCommonInstance.findHeader("oc-fileid", allHeaderFields: response.response?.allHeaderFields) != nil { ocId = self.nkCommonInstance.findHeader("oc-fileid", allHeaderFields: response.response?.allHeaderFields) } else if self.nkCommonInstance.findHeader("fileid", allHeaderFields: response.response?.allHeaderFields) != nil { @@ -93,7 +93,7 @@ public extension NextcloudKit { if let dateRaw = self.nkCommonInstance.findHeader("date", allHeaderFields: response.response?.allHeaderFields) { date = dateRaw.parsedDate(using: "EEE, dd MMM y HH:mm:ss zzz") } - + if !uploadCompleted { nkLog(error: "Upload incomplete: only \(uploadedSize) bytes sent.") result = .uploadIncomplete @@ -109,18 +109,28 @@ public extension NextcloudKit { options.queue.async { requestHandler(request) } } - // Asynchronously uploads a file to the Nextcloud server. - // - // - Parameters are the same as the synchronous version. - // - // - Returns: A tuple with: - // - account: The account used for the upload. - // - ocId: The remote file identifier returned by the server. - // - etag: The file etag returned by the server. - // - date: The server timestamp. - // - size: The size of the uploaded file in bytes. - // - headers: The raw HTTP response headers. - // - error: The NKError result of the upload. + /// Asynchronously uploads a file to the Nextcloud server. + /// + /// - Parameters: + /// - serverUrlFileName: The remote server URL or path where the file will be uploaded. + /// - fileNameLocalPath: The local file path to be uploaded. + /// - dateCreationFile: Optional creation date to include in headers (X-OC-CTime). + /// - dateModificationFile: Optional modification date to include in headers (X-OC-MTime). + /// - overwrite: If true, the remote file will be overwritten if it already exists. + /// - account: The account associated with the upload session. + /// - options: Optional configuration for the request (headers, queue, timeout, etc.). + /// - requestHandler: Called with the created UploadRequest. + /// - taskHandler: Called with the underlying URLSessionTask when it's created. + /// - progressHandler: Called periodically with upload progress. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the upload. + /// - ocId: The remote file identifier returned by the server. + /// - etag: The file etag returned by the server. + /// - date: The server timestamp. + /// - size: The size of the uploaded file in bytes. + /// - headers: The raw HTTP response headers. + /// - error: The NKError result of the upload. func uploadAsync(serverUrlFileName: Any, fileNameLocalPath: String, dateCreationFile: Date? = nil, @@ -164,33 +174,33 @@ public extension NextcloudKit { } } - // Uploads a file in multiple chunks to the Nextcloud server using TUS-like behavior. - // - // Parameters: - // - directory: The local directory containing the original file. - // - fileChunksOutputDirectory: Optional custom output directory for chunks (default is same as `directory`). - // - fileName: Name of the original file to split and upload. - // - destinationFileName: Optional custom filename to be used on the server. - // - date: The modification date to be set on the uploaded file. - // - creationDate: The creation date to be set on the uploaded file. - // - serverUrl: The destination server path. - // - chunkFolder: A temporary folder name (usually a UUID). - // - filesChunk: List of chunk identifiers and their expected sizes. - // - chunkSize: Size of each chunk in bytes. - // - account: The Nextcloud account used for authentication. - // - options: Request options (headers, queue, etc.). - // - numChunks: Callback invoked with total number of chunks. - // - counterChunk: Callback invoked with the index of the chunk being uploaded. - // - start: Called when chunk upload begins, with the full chunk list. - // - requestHandler: Handler to inspect the upload request. - // - taskHandler: Handler to inspect the upload task. - // - progressHandler: Progress callback with expected bytes, transferred bytes, and fraction completed. - // - uploaded: Called each time a chunk is successfully uploaded. - // - completion: Called when all chunks are uploaded and reassembled. Returns: - // - account: The user account used. - // - filesChunk: Remaining chunks (if any). - // - file: The final `NKFile` metadata for the uploaded file. - // - error: Upload result as `NKError`. + /// Uploads a file in multiple chunks to the Nextcloud server using TUS-like behavior. + /// + /// - Parameters: + /// - directory: The local directory containing the original file. + /// - fileChunksOutputDirectory: Optional custom output directory for chunks (default is same as `directory`). + /// - fileName: Name of the original file to split and upload. + /// - destinationFileName: Optional custom filename to be used on the server. + /// - date: The modification date to be set on the uploaded file. + /// - creationDate: The creation date to be set on the uploaded file. + /// - serverUrl: The destination server path. + /// - chunkFolder: A temporary folder name (usually a UUID). + /// - filesChunk: List of chunk identifiers and their expected sizes. + /// - chunkSize: Size of each chunk in bytes. + /// - account: The Nextcloud account used for authentication. + /// - options: Request options (headers, queue, etc.). + /// - numChunks: Callback invoked with total number of chunks. + /// - counterChunk: Callback invoked with the index of the chunk being uploaded. + /// - start: Called when chunk upload begins, with the full chunk list. + /// - requestHandler: Handler to inspect the upload request. + /// - taskHandler: Handler to inspect the upload task. + /// - progressHandler: Progress callback with expected bytes, transferred bytes, and fraction completed. + /// - uploaded: Called each time a chunk is successfully uploaded. + /// - completion: Called when all chunks are uploaded and reassembled. Returns: + /// - account: The user account used. + /// - filesChunk: Remaining chunks (if any). + /// - file: The final `NKFile` metadata for the uploaded file. + /// - error: Upload result as `NKError`. func uploadChunk(directory: String, fileChunksOutputDirectory: String? = nil, fileName: String, @@ -352,14 +362,14 @@ public extension NextcloudKit { } } - // Asynchronously uploads a file in chunks and assembles it on the Nextcloud server. - // - // - Parameters: Same as the sync version. - // - Returns: A tuple containing: - // - account: The user account used. - // - remainingChunks: Remaining chunks if any failed (or nil if success). - // - file: The final file metadata object. - // - error: Upload result as `NKError`. + /// Asynchronously uploads a file in chunks and assembles it on the Nextcloud server. + /// + /// - Parameters: Same as the sync version. + /// - Returns: A tuple containing: + /// - account: The user account used. + /// - remainingChunks: Remaining chunks if any failed (or nil if success). + /// - file: The final file metadata object. + /// - error: Upload result as `NKError`. func uploadChunkAsync(directory: String, fileChunksOutputDirectory: String? = nil, fileName: String, diff --git a/Sources/NextcloudKit/NextcloudKit+UserStatus.swift b/Sources/NextcloudKit/NextcloudKit+UserStatus.swift index 2a88f83f..6ba1101b 100644 --- a/Sources/NextcloudKit/NextcloudKit+UserStatus.swift +++ b/Sources/NextcloudKit/NextcloudKit+UserStatus.swift @@ -7,25 +7,25 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { - // Retrieves the user status from the Nextcloud server. - // - // Parameters: - // - userId: Optional user ID to query (if nil, fetches the status for the authenticated user). - // - account: The Nextcloud account identifier. - // - options: Optional request options (headers, queue, version, etc.). - // - taskHandler: Callback for monitoring the `URLSessionTask`. - // - completion: Returns multiple values: - // - account: The user account used. - // - clearAt: Optional expiration `Date` of the status. - // - icon: Optional status icon name. - // - message: Optional status message. - // - messageId: Optional ID of the predefined message. - // - messageIsPredefined: Indicates whether the message is predefined. - // - status: Optional raw status value. - // - statusIsUserDefined: Indicates if the status was set manually by the user. - // - userId: The actual user ID returned by the server. - // - responseData: Raw response data from the server. - // - error: Result as `NKError`. + /// Retrieves the user status from the Nextcloud server. + /// + /// - Parameters: + /// - userId: Optional user ID to query (if `nil`, fetches the status for the authenticated user). + /// - account: The Nextcloud account identifier. + /// - options: Optional request options (headers, queue, version, etc.). + /// - taskHandler: Callback for monitoring the `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The user account used. + /// - clearAt: Optional expiration `Date` of the status. + /// - icon: Optional status icon name. + /// - message: Optional status message. + /// - messageId: Optional ID of the predefined message. + /// - messageIsPredefined: Indicates whether the message is predefined. + /// - status: Optional raw status value. + /// - statusIsUserDefined: Indicates if the status was set manually by the user. + /// - userId: The actual user ID returned by the server. + /// - responseData: Raw response data from the server. + /// - error: Result as `NKError`. func getUserStatus(userId: String? = nil, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -74,10 +74,10 @@ public extension NextcloudKit { } } - // Asynchronously retrieves the user status from the Nextcloud server. - // - // - Parameters: Same as the sync version. - // - Returns: A tuple with explicitly named values describing the user status. + /// Asynchronously retrieves the user status from the Nextcloud server. + /// + /// - Parameters: Same as the sync version. + /// - Returns: A tuple with explicitly named values describing the user status. func getUserStatusAsync(userId: String? = nil, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -118,14 +118,14 @@ public extension NextcloudKit { } - // Sets the current user status on the Nextcloud server. - // - // Parameters: - // - status: The raw status value to be set (e.g. "online", "away", etc.). - // - account: The Nextcloud account performing the operation. - // - options: Optional request configuration. - // - taskHandler: Callback for the underlying `URLSessionTask`. - // - completion: Returns the account, the raw response data, and any resulting NKError. + /// Sets the current user status on the Nextcloud server. + /// + /// Parameters: + /// - status: The raw status value to be set (e.g. "online", "away", etc.). + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request configuration. + /// - taskHandler: Callback for the underlying `URLSessionTask`. + /// - completion: Returns the account, the raw response data, and any resulting NKError. func setUserStatus(status: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -188,7 +188,6 @@ public extension NextcloudKit { } } - /// Sets a predefined custom message for the user's status on the Nextcloud server. /// /// - Parameters: @@ -241,15 +240,15 @@ public extension NextcloudKit { } } - // Asynchronously sets a predefined custom message with optional expiration. - // - // Parameters: - // - messageId: The identifier of the predefined message to set. - // - clearAt: Expiration timestamp (UNIX time) after which the message is cleared (optional, use 0 to skip). - // - account: The Nextcloud account performing the operation. - // - options: Optional request configuration (headers, queue, etc.). - // - taskHandler: Callback for monitoring the underlying URLSessionTask. - // - Returns: A tuple containing the account identifier, the raw response, and any resulting NKError. + /// Asynchronously sets a predefined custom message with optional expiration. + /// + /// Parameters: + /// - messageId: The identifier of the predefined message to set. + /// - clearAt: Expiration timestamp (UNIX time) after which the message is cleared (optional, use 0 to skip). + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request configuration (headers, queue, etc.). + /// - taskHandler: Callback for monitoring the underlying URLSessionTask. + /// - Returns: A tuple containing the account identifier, the raw response, and any resulting NKError. func setCustomMessagePredefinedAsync(messageId: String, clearAt: Double, account: String, @@ -275,19 +274,19 @@ public extension NextcloudKit { } } - // Sets a custom user-defined status message on the Nextcloud server. - // - // Parameters: - // - statusIcon: Optional icon name representing the status. - // - message: The custom status message string to display to other users. - // - clearAt: Expiration timestamp (in UNIX time format) for the status message; use 0 to disable automatic clearing. - // - account: The Nextcloud account identifier on which to apply the status. - // - options: Optional request configuration such as headers, queue, or task description. - // - taskHandler: Closure invoked when the URLSessionTask is created, used for task tracking or debugging. - // - completion: Completion handler returning: - // - account: The account identifier used. - // - responseData: The raw Alamofire response data (if any). - // - error: An `NKError` indicating success or failure. + /// Sets a custom user-defined status message on the Nextcloud server. + /// + /// Parameters: + /// - statusIcon: Optional icon name representing the status. + /// - message: The custom status message string to display to other users. + /// - clearAt: Expiration timestamp (in UNIX time format) for the status message; use 0 to disable automatic clearing. + /// - account: The Nextcloud account identifier on which to apply the status. + /// - options: Optional request configuration such as headers, queue, or task description. + /// - taskHandler: Closure invoked when the URLSessionTask is created, used for task tracking or debugging. + /// - completion: Completion handler returning: + /// - account: The account identifier used. + /// - responseData: The raw Alamofire response data (if any). + /// - error: An `NKError` indicating success or failure. func setCustomMessageUserDefined(statusIcon: String?, message: String, clearAt: Double, @@ -332,17 +331,17 @@ public extension NextcloudKit { } } - // Asynchronously sets a custom user-defined status message. - // - // Parameters: - // - statusIcon: Optional icon to display with the message. - // - message: The custom status message string. - // - clearAt: Timestamp (UNIX time) when the message should expire (use 0 to skip). - // - account: The Nextcloud account performing the operation. - // - options: Request options such as headers, task description, queue. - // - taskHandler: Callback for URLSessionTask monitoring. - // - // Returns: A tuple containing account, responseData, and any resulting NKError. + /// Asynchronously sets a custom user-defined status message. + /// + /// Parameters: + /// - statusIcon: Optional icon to display with the message. + /// - message: The custom status message string. + /// - clearAt: Timestamp (UNIX time) when the message should expire (use 0 to skip). + /// - account: The Nextcloud account performing the operation. + /// - options: Request options such as headers, task description, queue. + /// - taskHandler: Callback for URLSessionTask monitoring. + /// + /// Returns: A tuple containing account, responseData, and any resulting NKError. func setCustomMessageUserDefinedAsync(statusIcon: String?, message: String, clearAt: Double, @@ -370,16 +369,16 @@ public extension NextcloudKit { } } - // Clears any custom or predefined user status message currently set on the Nextcloud server. - // - // Parameters: - // - account: The Nextcloud account identifier whose status message should be cleared. - // - options: Optional request configuration such as custom headers, dispatch queue, or task description. - // - taskHandler: Closure called when the `URLSessionTask` is created, useful for debugging or tracking purposes. - // - completion: Completion handler returning: - // - account: The account identifier used. - // - responseData: The raw Alamofire response object, if available. - // - error: An `NKError` representing the result of the operation (success or failure). + /// Clears any custom or predefined user status message currently set on the Nextcloud server. + /// + /// Parameters: + /// - account: The Nextcloud account identifier whose status message should be cleared. + /// - options: Optional request configuration such as custom headers, dispatch queue, or task description. + /// - taskHandler: Closure called when the `URLSessionTask` is created, useful for debugging or tracking purposes. + /// - completion: Completion handler returning: + /// - account: The account identifier used. + /// - responseData: The raw Alamofire response object, if available. + /// - error: An `NKError` representing the result of the operation (success or failure). func clearMessage(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, @@ -412,17 +411,17 @@ public extension NextcloudKit { } } - // Asynchronously clears any user status message (custom or predefined) on the Nextcloud server. - // - // Parameters: - // - account: The Nextcloud account identifier whose status message will be cleared. - // - options: Optional `NKRequestOptions` to customize the request (e.g., headers, queue). - // - taskHandler: Callback triggered upon creation of the `URLSessionTask`. - // - // Returns: A tuple containing: - // - account: The account identifier used for the operation. - // - responseData: The raw `AFDataResponse` object returned by Alamofire. - // - error: The resulting `NKError`, either `.success` or a failure case. + /// Asynchronously clears any user status message (custom or predefined) on the Nextcloud server. + /// + /// Parameters: + /// - account: The Nextcloud account identifier whose status message will be cleared. + /// - options: Optional `NKRequestOptions` to customize the request (e.g., headers, queue). + /// - taskHandler: Callback triggered upon creation of the `URLSessionTask`. + /// + /// Returns: A tuple containing: + /// - account: The account identifier used for the operation. + /// - responseData: The raw `AFDataResponse` object returned by Alamofire. + /// - error: The resulting `NKError`, either `.success` or a failure case. func clearMessageAsync(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } @@ -444,18 +443,17 @@ public extension NextcloudKit { } } - // Retrieves the list of predefined user statuses (e.g., "Available", "Away", "Do not disturb") from the Nextcloud server. - // - // Parameters: - // - account: The Nextcloud account identifier performing the request. - // - options: Optional `NKRequestOptions` to customize the request (e.g., custom headers, queue). - // - taskHandler: Callback triggered when the `URLSessionTask` is created. - // - // Returns: A tuple containing: - // - account: The account identifier used for the request. - // - userStatuses: An optional array of predefined `NKUserStatus` objects. - // - responseData: Raw `AFDataResponse` from Alamofire. - // - error: Resulting `NKError` describing success or failure. + /// Retrieves the list of predefined user statuses (e.g., "Available", "Away", "Do not disturb") from the Nextcloud server. + /// + /// - Parameters: + /// - account: The Nextcloud account identifier performing the request. + /// - options: Optional `NKRequestOptions` to customize the request (e.g., custom headers, queue). + /// - taskHandler: Callback triggered when the `URLSessionTask` is created. + /// - completion: Completion handler returning: + /// - account: The account identifier used for the request. + /// - userStatuses: An optional array of predefined `NKUserStatus` objects. + /// - responseData: Raw `AFDataResponse` from Alamofire. + /// - error: Resulting `NKError` describing success or failure. func getUserStatusPredefinedStatuses(account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, From 6afa8081b420b3480b65e326fff096342cb827f3 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 15:20:47 +0200 Subject: [PATCH 09/10] async Signed-off-by: Marino Faggiana --- .../NextcloudKit/NextcloudKit+WebDAV.swift | 712 ++++++++++++++++-- 1 file changed, 667 insertions(+), 45 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+WebDAV.swift b/Sources/NextcloudKit/NextcloudKit+WebDAV.swift index 3e8fef6b..64470181 100644 --- a/Sources/NextcloudKit/NextcloudKit+WebDAV.swift +++ b/Sources/NextcloudKit/NextcloudKit+WebDAV.swift @@ -7,6 +7,19 @@ import Alamofire import SwiftyJSON public extension NextcloudKit { + /// Creates a folder on the Nextcloud server at the specified path. + /// + /// - Parameters: + /// - serverUrlFileName: The full URL string of the folder to create. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options including headers, timeout, and queue. + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - ocId: Optional file ID assigned by the server for the new folder. + /// - date: Optional date from the server response headers. + /// - responseData: The raw Alamofire response data. + /// - error: The `NKError` result indicating success or failure. func createFolder(serverUrlFileName: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -43,16 +56,48 @@ public extension NextcloudKit { } } + /// Asynchronously creates a folder on the Nextcloud server. + /// + /// - Parameters: Same as the sync version. + /// - Returns: A tuple with account, optional ocId, optional date, responseData, and NKError. func createFolderAsync(serverUrlFileName: String, - account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, ocId: String?, date: Date?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.createFolder(serverUrlFileName: serverUrlFileName, account: account, options: options) { account, ocId, date, responseData, error in - continuation.resume(returning: (account: account, ocId: ocId, date: date, responseData: responseData, error: error)) + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + ocId: String?, + date: Date?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + createFolder(serverUrlFileName: serverUrlFileName, + account: account, + options: options, + taskHandler: taskHandler) { account, ocId, date, responseData, error in + continuation.resume(returning: ( + account: account, + ocId: ocId, + date: date, + responseData: responseData, + error: error + )) } - }) + } } + /// Deletes a file or folder from the Nextcloud server at the specified URL. + /// + /// - Parameters: + /// - serverUrlFileName: The full URL string of the file or folder to delete. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options including headers, timeout, and queue. + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - responseData: The raw Alamofire response data. + /// - error: The `NKError` result indicating success or failure. func deleteFileOrFolder(serverUrlFileName: String, account: String, options: NKRequestOptions = NKRequestOptions(), @@ -83,16 +128,54 @@ public extension NextcloudKit { } } + /// Asynchronously deletes a file or folder from the Nextcloud server. + /// + /// - Parameters: + /// - serverUrlFileName: The full URL string of the file or folder to delete. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options including headers, timeout, and queue. + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the request. + /// - responseData: The raw Alamofire response data. + /// - error: The `NKError` result indicating success or failure. func deleteFileOrFolderAsync(serverUrlFileName: String, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.deleteFileOrFolder(serverUrlFileName: serverUrlFileName, account: account, options: options) { account, responseData, error in - continuation.resume(returning: (account: account, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + deleteFileOrFolder(serverUrlFileName: serverUrlFileName, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } - }) + } } + /// Moves or renames a file or folder on the Nextcloud server. + /// + /// - Parameters: + /// - serverUrlFileNameSource: The full URL string of the source file or folder to move. + /// - serverUrlFileNameDestination: The full URL string of the destination path. + /// - overwrite: Whether to overwrite the destination if it exists. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options including headers, timeout, and queue. + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - responseData: The raw Alamofire response data. + /// - error: The `NKError` result indicating success or failure. func moveFileOrFolder(serverUrlFileNameSource: String, serverUrlFileNameDestination: String, overwrite: Bool, @@ -132,18 +215,60 @@ public extension NextcloudKit { } } + /// Asynchronously moves or renames a file or folder on the Nextcloud server. + /// + /// - Parameters: + /// - serverUrlFileNameSource: The full URL string of the source file or folder to move. + /// - serverUrlFileNameDestination: The full URL string of the destination path. + /// - overwrite: Whether to overwrite the destination if it exists. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options including headers, timeout, and queue. + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the request. + /// - responseData: The raw Alamofire response data. + /// - error: The `NKError` result indicating success or failure. func moveFileOrFolderAsync(serverUrlFileNameSource: String, serverUrlFileNameDestination: String, overwrite: Bool, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite, account: account, options: options) { account, responseData, error in - continuation.resume(returning: (account: account, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + moveFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, + serverUrlFileNameDestination: serverUrlFileNameDestination, + overwrite: overwrite, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } - }) + } } + /// Copies a file or folder on the Nextcloud server from a source path to a destination path. + /// + /// - Parameters: + /// - serverUrlFileNameSource: The full URL string of the source file or folder to copy. + /// - serverUrlFileNameDestination: The full URL string of the destination path. + /// - overwrite: A Boolean indicating whether to overwrite the destination if it exists. + /// - account: The Nextcloud account identifier. + /// - options: Optional request configuration including headers, timeout, and queue. + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - responseData: The raw Alamofire response data. + /// - error: An `NKError` indicating success or failure. func copyFileOrFolder(serverUrlFileNameSource: String, serverUrlFileNameDestination: String, overwrite: Bool, @@ -184,18 +309,63 @@ public extension NextcloudKit { } } + /// Asynchronously copies a file or folder on the Nextcloud server. + /// + /// - Parameters: + /// - serverUrlFileNameSource: The full URL string of the source file or folder. + /// - serverUrlFileNameDestination: The full URL string of the destination. + /// - overwrite: Indicates whether to overwrite existing destination. + /// - account: The Nextcloud account identifier. + /// - options: Optional request configuration. + /// - taskHandler: Callback for the underlying `URLSessionTask`. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the request. + /// - responseData: The raw Alamofire response data. + /// - error: The resulting `NKError`. func copyFileOrFolderAsync(serverUrlFileNameSource: String, serverUrlFileNameDestination: String, overwrite: Bool, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.copyFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite, account: account, options: options) { account, responseData, error in - continuation.resume(returning: (account: account, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + copyFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, + serverUrlFileNameDestination: serverUrlFileNameDestination, + overwrite: overwrite, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } - }) + } } + /// Reads the contents of a file or folder on the Nextcloud server. + /// + /// - Parameters: + /// - serverUrlFileName: The full URL string of the file or folder to read. + /// - depth: The depth level for folder traversal (e.g., "0", "1", "infinity"). + /// - showHiddenFiles: Boolean flag indicating whether to show hidden files (default is true). + /// - includeHiddenFiles: An array of specific hidden filenames to include despite hidden status. + /// - requestBody: Optional raw data to send as the request body. + /// - account: The Nextcloud account identifier. + /// - options: Optional request configuration including headers, timeout, and queue. + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - files: An optional array of `NKFile` objects representing the contents. + /// - responseData: The raw Alamofire response data. + /// - error: An `NKError` indicating success or failure. func readFileOrFolder(serverUrlFileName: String, depth: String, showHiddenFiles: Bool = true, @@ -256,19 +426,69 @@ public extension NextcloudKit { } } + /// Asynchronously reads the contents of a file or folder. + /// + /// - Parameters: + /// - serverUrlFileName: The full URL string of the file or folder. + /// - depth: The depth level to traverse. + /// - showHiddenFiles: Whether to show hidden files. + /// - includeHiddenFiles: Specific hidden files to include. + /// - requestBody: Optional request body data. + /// - account: The Nextcloud account identifier. + /// - options: Optional request configuration. + /// - taskHandler: Callback for the underlying URLSessionTask. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the request. + /// - files: Optional array of `NKFile` contents. + /// - responseData: The raw Alamofire response data. + /// - error: The resulting `NKError`. func readFileOrFolderAsync(serverUrlFileName: String, depth: String, showHiddenFiles: Bool = true, + includeHiddenFiles: [String] = [], requestBody: Data? = nil, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, files: [NKFile]?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: depth, showHiddenFiles: showHiddenFiles, requestBody: requestBody, account: account, options: options) { account, files, responseData, error in - continuation.resume(returning: (account: account, files: files, responseData: responseData, error: error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + files: [NKFile]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + readFileOrFolder(serverUrlFileName: serverUrlFileName, + depth: depth, + showHiddenFiles: showHiddenFiles, + includeHiddenFiles: includeHiddenFiles, + requestBody: requestBody, + account: account, + options: options, + taskHandler: taskHandler) { account, files, responseData, error in + continuation.resume(returning: ( + account: account, + files: files, + responseData: responseData, + error: error + )) } - }) + } } + /// Retrieves a file object from the server using either a file ID or a direct link. + /// + /// - Parameters: + /// - fileId: Optional file identifier to fetch the file. + /// - link: Optional direct link to the file. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options (headers, queue, etc.). + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - file: Optional `NKFile` object representing the file. + /// - responseData: Raw Alamofire response data. + /// - error: An `NKError` indicating success or failure. func getFileFromFileId(fileId: String? = nil, link: String? = nil, account: String, @@ -299,6 +519,62 @@ public extension NextcloudKit { } } + /// Asynchronously retrieves a file object using file ID or link. + /// + /// - Parameters: + /// - fileId: Optional file ID. + /// - link: Optional direct link. + /// - account: Nextcloud account identifier. + /// - options: Optional request options. + /// - taskHandler: Callback for URLSessionTask monitoring. + /// + /// - Returns: A tuple containing: + /// - account: The account used. + /// - file: Optional `NKFile` object. + /// - responseData: Raw response data. + /// - error: Resulting `NKError`. + func getFileFromFileIdAsync(fileId: String? = nil, + link: String? = nil, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + file: NKFile?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + getFileFromFileId(fileId: fileId, + link: link, + account: account, + options: options, + taskHandler: taskHandler) { account, file, responseData, error in + continuation.resume(returning: ( + account: account, + file: file, + responseData: responseData, + error: error + )) + } + } + } + + /// Performs a search on the server with a given XML body request. + /// + /// - Parameters: + /// - serverUrl: The base URL of the server. + /// - requestBody: The XML request body as a string. + /// - showHiddenFiles: Whether to include hidden files in the search. + /// - includeHiddenFiles: An array of hidden file names to specifically include. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options (headers, queue, etc.). + /// - taskHandler: Callback triggered with the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - files: Optional array of `NKFile` results matching the search. + /// - responseData: Raw Alamofire response data. + /// - error: An `NKError` indicating success or failure. func searchBodyRequest(serverUrl: String, requestBody: String, showHiddenFiles: Bool, @@ -316,6 +592,69 @@ public extension NextcloudKit { } } + /// Asynchronously performs a search on the server with an XML request body. + /// + /// - Parameters: + /// - serverUrl: The base URL of the server. + /// - requestBody: The XML request body string. + /// - showHiddenFiles: Flag to include hidden files. + /// - includeHiddenFiles: Array of hidden files to include. + /// - account: The Nextcloud account. + /// - options: Optional request options. + /// - taskHandler: Callback to observe the underlying URLSessionTask. + /// + /// - Returns: A tuple containing: + /// - account: The account used. + /// - files: Optional array of `NKFile` results. + /// - responseData: Raw response data. + /// - error: Resulting `NKError`. + func searchBodyRequestAsync(serverUrl: String, + requestBody: String, + showHiddenFiles: Bool, + includeHiddenFiles: [String] = [], + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + files: [NKFile]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + searchBodyRequest(serverUrl: serverUrl, + requestBody: requestBody, + showHiddenFiles: showHiddenFiles, + includeHiddenFiles: includeHiddenFiles, + account: account, + options: options, + taskHandler: taskHandler) { account, files, responseData, error in + continuation.resume(returning: ( + account: account, + files: files, + responseData: responseData, + error: error + )) + } + } + } + + /// Performs a search on the server with a literal string query. + /// + /// - Parameters: + /// - serverUrl: The base URL of the server. + /// - depth: The depth of the search in the directory hierarchy. + /// - literal: The literal search string to query. + /// - showHiddenFiles: Whether to include hidden files in the search. + /// - includeHiddenFiles: Specific hidden files to include. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options (headers, queue, etc.). + /// - taskHandler: Callback for the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - files: Optional array of `NKFile` objects matching the search. + /// - responseData: Raw Alamofire response data. + /// - error: An `NKError` indicating success or failure. func searchLiteral(serverUrl: String, depth: String, literal: String, @@ -339,6 +678,72 @@ public extension NextcloudKit { } } + /// Asynchronously performs a literal search on the server. + /// + /// - Parameters: + /// - serverUrl: The server base URL. + /// - depth: Search depth. + /// - literal: Literal query string. + /// - showHiddenFiles: Whether to include hidden files. + /// - includeHiddenFiles: Specific hidden files to include. + /// - account: Nextcloud account identifier. + /// - options: Optional request options. + /// - taskHandler: Callback for the underlying URLSessionTask. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the request. + /// - files: Optional array of NKFile results. + /// - responseData: Raw response data. + /// - error: Resulting NKError. + func searchLiteralAsync(serverUrl: String, + depth: String, + literal: String, + showHiddenFiles: Bool, + includeHiddenFiles: [String] = [], + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + files: [NKFile]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + searchLiteral(serverUrl: serverUrl, + depth: depth, + literal: literal, + showHiddenFiles: showHiddenFiles, + includeHiddenFiles: includeHiddenFiles, + account: account, + options: options, + taskHandler: taskHandler) { account, files, responseData, error in + continuation.resume(returning: ( + account: account, + files: files, + responseData: responseData, + error: error + )) + } + } + } + + /// Searches media files within a specified date range on the server. + /// + /// - Parameters: + /// - path: The directory path to search within (default is empty string for root). + /// - lessDate: The upper bound date filter (files older than this). + /// - greaterDate: The lower bound date filter (files newer than this). + /// - elementDate: The file date attribute to filter on (e.g., "created", "modified"). + /// - limit: Maximum number of files to return. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options (headers, queue, etc.). + /// - taskHandler: Callback for monitoring the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - files: Optional array of matching `NKFile` objects. + /// - responseData: Raw Alamofire response data. + /// - error: An `NKError` describing success or failure. func searchMedia(path: String = "", lessDate: Any, greaterDate: Any, @@ -379,6 +784,71 @@ public extension NextcloudKit { } } + /// Asynchronously searches media files with date filters. + /// + /// - Parameters: + /// - path: Directory path to search. + /// - lessDate: Upper date bound filter. + /// - greaterDate: Lower date bound filter. + /// - elementDate: File date attribute to filter on. + /// - limit: Maximum number of results. + /// - account: Nextcloud account identifier. + /// - options: Optional request options. + /// - taskHandler: Callback for URLSessionTask monitoring. + /// + /// - Returns: A tuple containing: + /// - account: Account used for the request. + /// - files: Optional array of `NKFile` matching results. + /// - responseData: Raw server response data. + /// - error: Resulting `NKError`. + func searchMediaAsync(path: String = "", + lessDate: Any, + greaterDate: Any, + elementDate: String, + limit: Int, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + files: [NKFile]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + searchMedia(path: path, + lessDate: lessDate, + greaterDate: greaterDate, + elementDate: elementDate, + limit: limit, + account: account, + options: options, + taskHandler: taskHandler) { account, files, responseData, error in + continuation.resume(returning: ( + account: account, + files: files, + responseData: responseData, + error: error + )) + } + } + } + + /// Performs a private search request with a custom HTTP body on the server. + /// + /// - Parameters: + /// - serverUrl: The base URL of the Nextcloud server. + /// - httpBody: The raw HTTP request body data for the search. + /// - showHiddenFiles: Boolean indicating whether to include hidden files in the search. + /// - includeHiddenFiles: Specific hidden files to include despite general hidden files exclusion. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options (headers, queue, version, etc.). + /// - taskHandler: Callback to monitor the created `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the request. + /// - files: Optional array of `NKFile` matching the search. + /// - responseData: Raw response data from Alamofire. + /// - error: An `NKError` indicating success or failure. private func search(serverUrl: String, httpBody: Data, showHiddenFiles: Bool, @@ -428,15 +898,74 @@ public extension NextcloudKit { } } + /// Asynchronously performs a search with a custom HTTP body. + /// + /// - Parameters: + /// - serverUrl: The base URL of the Nextcloud server. + /// - httpBody: The raw HTTP request body data for the search. + /// - showHiddenFiles: Boolean indicating whether to include hidden files in the search. + /// - includeHiddenFiles: Specific hidden files to include despite general hidden files exclusion. + /// - account: The Nextcloud account identifier. + /// - options: Optional request options (headers, queue, version, etc.). + /// - taskHandler: Callback to monitor the created `URLSessionTask`. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the request. + /// - files: Optional array of `NKFile` results. + /// - responseData: Raw response data. + /// - error: Resulting `NKError`. + private func searchAsync(serverUrl: String, + httpBody: Data, + showHiddenFiles: Bool, + includeHiddenFiles: [String], + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + files: [NKFile]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + search(serverUrl: serverUrl, + httpBody: httpBody, + showHiddenFiles: showHiddenFiles, + includeHiddenFiles: includeHiddenFiles, + account: account, + options: options, + taskHandler: taskHandler) { account, files, responseData, error in + continuation.resume(returning: ( + account: account, + files: files, + responseData: responseData, + error: error + )) + } + } + } + + /// Sets or removes a favorite flag on a specified file or folder on the Nextcloud server. + /// + /// - Parameters: + /// - fileName: The full path or URL-encoded name of the file or folder. + /// - favorite: A Boolean value indicating whether to set (`true`) or remove (`false`) the favorite status. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request configuration (headers, queue, version, etc.). + /// - taskHandler: Callback for monitoring the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the operation. + /// - responseData: Raw Alamofire response data. + /// - error: An `NKError` indicating success or failure. func setFavorite(fileName: String, favorite: Bool, account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, completion: @escaping (_ account: String, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { - /// + // options.contentType = "application/xml" - /// + // guard let nkSession = nkCommonInstance.nksessions.session(forAccount: account), let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { return options.queue.async { completion(account, nil, .urlError) } @@ -469,26 +998,61 @@ public extension NextcloudKit { } } + /// Asynchronously sets or removes a favorite flag on a file or folder. + /// + /// - Parameters: Same as the synchronous version. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the operation. + /// - responseData: Raw response data from Alamofire. + /// - error: The resulting `NKError`. func setFavoriteAsync(fileName: String, favorite: Bool, account: String, - options: NKRequestOptions = NKRequestOptions()) async -> NKError { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.setFavorite(fileName: fileName, favorite: favorite, account: account) { _, _, error in - continuation.resume(returning: error) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + setFavorite(fileName: fileName, + favorite: favorite, + account: account, + options: options, + taskHandler: taskHandler) { account, responseData, error in + continuation.resume(returning: ( + account: account, + responseData: responseData, + error: error + )) } - }) + } } + /// Lists all favorite files and folders for a user on the Nextcloud server. + /// + /// - Parameters: + /// - showHiddenFiles: Whether to include hidden files in the results. + /// - includeHiddenFiles: Specific hidden files to include even if `showHiddenFiles` is false. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request configuration (headers, queue, version, etc.). + /// - taskHandler: Callback for monitoring the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the operation. + /// - files: An optional array of `NKFile` representing the favorite items. + /// - responseData: Raw Alamofire response data. + /// - error: An `NKError` indicating success or failure. func listingFavorites(showHiddenFiles: Bool, includeHiddenFiles: [String] = [], account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, completion: @escaping (_ account: String, _ files: [NKFile]?, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { - /// + // options.contentType = "application/xml" - /// + // guard let nkSession = nkCommonInstance.nksessions.session(forAccount: account), let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { return options.queue.async { completion(account, nil, nil, .urlError) } @@ -529,26 +1093,64 @@ public extension NextcloudKit { } } + /// Asynchronously lists all favorite files and folders for a user. + /// + /// - Parameters: Same as the synchronous version. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the operation. + /// - files: An optional array of `NKFile` for the favorite items. + /// - responseData: Raw response data from Alamofire. + /// - error: The resulting `NKError`. func listingFavoritesAsync(showHiddenFiles: Bool, includeHiddenFiles: [String] = [], account: String, - options: NKRequestOptions = NKRequestOptions()) async -> (account: String, files: [NKFile]?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation({ continuation in - NextcloudKit.shared.listingFavorites(showHiddenFiles: showHiddenFiles, includeHiddenFiles: includeHiddenFiles, account: account, options: options) { account, files, data, error in - continuation.resume(returning: (account, files, data, error)) + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + files: [NKFile]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in + listingFavorites(showHiddenFiles: showHiddenFiles, + includeHiddenFiles: includeHiddenFiles, + account: account, + options: options, + taskHandler: taskHandler) { account, files, responseData, error in + continuation.resume(returning: ( + account: account, + files: files, + responseData: responseData, + error: error + )) } - }) + } } + /// Lists the contents of the trash bin for a user on the Nextcloud server. + /// + /// - Parameters: + /// - filename: Optional specific filename to filter the trash items. + /// - showHiddenFiles: Whether to include hidden files in the trash listing. + /// - account: The Nextcloud account performing the operation. + /// - options: Optional request configuration (headers, queue, version, etc.). + /// - taskHandler: Callback for monitoring the underlying `URLSessionTask`. + /// - completion: Completion handler returning: + /// - account: The account used for the operation. + /// - items: An optional array of `NKTrash` objects representing trashed items. + /// - responseData: Raw Alamofire response data. + /// - error: An `NKError` indicating success or failure. func listingTrash(filename: String? = nil, showHiddenFiles: Bool, account: String, options: NKRequestOptions = NKRequestOptions(), taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, completion: @escaping (_ account: String, _ items: [NKTrash]?, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { - /// + // options.contentType = "application/xml" - /// + // guard let nkSession = nkCommonInstance.nksessions.session(forAccount: account), var headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { return options.queue.async { completion(account, nil, nil, .urlError) } @@ -593,18 +1195,38 @@ public extension NextcloudKit { } } + /// Asynchronously lists the trash contents for a user. + /// + /// - Parameters: Same as the synchronous version. + /// + /// - Returns: A tuple containing: + /// - account: The account used for the operation. + /// - items: An optional array of `NKTrash` representing trashed items. + /// - responseData: Raw response data from Alamofire. + /// - error: The resulting `NKError`. func listingTrashAsync(filename: String? = nil, showHiddenFiles: Bool, account: String, options: NKRequestOptions = NKRequestOptions(), - taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }) async -> (account: String, items: [NKTrash]?, responseData: AFDataResponse?, error: NKError) { - await withUnsafeContinuation { continuation in + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in } + ) async -> ( + account: String, + items: [NKTrash]?, + responseData: AFDataResponse?, + error: NKError + ) { + await withCheckedContinuation { continuation in listingTrash(filename: filename, showHiddenFiles: showHiddenFiles, account: account, options: options, taskHandler: taskHandler) { account, items, responseData, error in - continuation.resume(returning: (account, items, responseData, error)) + continuation.resume(returning: ( + account: account, + items: items, + responseData: responseData, + error: error + )) } } } From 8bee0987a434bafc39f12015e2b8d71c1be151ef Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Fri, 27 Jun 2025 15:25:42 +0200 Subject: [PATCH 10/10] async Signed-off-by: Marino Faggiana --- .../NextcloudKit/NextcloudKitBackground.swift | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/Sources/NextcloudKit/NextcloudKitBackground.swift b/Sources/NextcloudKit/NextcloudKitBackground.swift index 76810f40..0c2ab372 100644 --- a/Sources/NextcloudKit/NextcloudKitBackground.swift +++ b/Sources/NextcloudKit/NextcloudKitBackground.swift @@ -14,6 +14,17 @@ public final class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDel // MARK: - Download + /// Starts a download task for a file from the server to a local path. + /// + /// - Parameters: + /// - serverUrlFileName: The URL or URL string of the file to download. + /// - fileNameLocalPath: The local file path where the downloaded file will be saved. + /// - taskDescription: Optional description to set on the URLSession task. + /// - account: The Nextcloud account associated with the download. + /// + /// - Returns: A tuple containing: + /// - URLSessionDownloadTask?: The download task if created successfully. + /// - error: An `NKError` indicating success or failure in starting the download. public func download(serverUrlFileName: Any, fileNameLocalPath: String, taskDescription: String? = nil, @@ -63,8 +74,46 @@ public final class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDel return (task, .success) } + /// Asynchronously starts a download task for a file. + /// + /// - Parameters: Same as the synchronous version. + /// + /// - Returns: A tuple containing: + /// - downloadTask: The `URLSessionDownloadTask?` if successfully created. + /// - error: The `NKError` result. + public func downloadAsync(serverUrlFileName: Any, + fileNameLocalPath: String, + taskDescription: String? = nil, + account: String) async -> ( + downloadTask: URLSessionDownloadTask?, + error: NKError + ) { + await withCheckedContinuation { continuation in + let (task, error) = download(serverUrlFileName: serverUrlFileName, + fileNameLocalPath: fileNameLocalPath, + taskDescription: taskDescription, + account: account) + continuation.resume(returning: (downloadTask: task, error: error)) + } + } + // MARK: - Upload + /// Starts an upload task to send a local file to the server. + /// + /// - Parameters: + /// - serverUrlFileName: The server URL or URL string where the file will be uploaded. + /// - fileNameLocalPath: The local file path of the file to upload. + /// - dateCreationFile: Optional creation date metadata for the file. + /// - dateModificationFile: Optional modification date metadata for the file. + /// - taskDescription: Optional description to set on the URLSession task. + /// - overwrite: Boolean indicating whether to overwrite existing files on the server. + /// - account: The Nextcloud account associated with the upload. + /// - sessionIdentifier: A string identifier for the upload session. + /// + /// - Returns: A tuple containing: + /// - URLSessionUploadTask?: The upload task if created successfully. + /// - error: An `NKError` indicating success or failure in starting the upload. public func upload(serverUrlFileName: Any, fileNameLocalPath: String, dateCreationFile: Date?, @@ -138,6 +187,37 @@ public final class NKBackground: NSObject, URLSessionTaskDelegate, URLSessionDel return (task, .success) } + /// Asynchronously starts an upload task to send a local file. + /// + /// - Parameters: Same as the synchronous version. + /// + /// - Returns: A tuple containing: + /// - uploadTask: The `URLSessionUploadTask?` if successfully created. + /// - error: The `NKError` result. + public func uploadAsync(serverUrlFileName: Any, + fileNameLocalPath: String, + dateCreationFile: Date?, + dateModificationFile: Date?, + taskDescription: String? = nil, + overwrite: Bool = false, + account: String, + sessionIdentifier: String) async -> ( + uploadTask: URLSessionUploadTask?, + error: NKError + ) { + await withCheckedContinuation { continuation in + let (task, error) = upload(serverUrlFileName: serverUrlFileName, + fileNameLocalPath: fileNameLocalPath, + dateCreationFile: dateCreationFile, + dateModificationFile: dateModificationFile, + taskDescription: taskDescription, + overwrite: overwrite, + account: account, + sessionIdentifier: sessionIdentifier) + continuation.resume(returning: (uploadTask: task, error: error)) + } + } + // MARK: - SessionDelegate public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {