From bcc6a42679ee4d5242a0fa435221e00cac5deee1 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Tue, 18 Mar 2025 16:55:32 +0100 Subject: [PATCH 1/3] Version 6.0.4 (#131) * https://github.com/nextcloud/ios/issues/2390 Signed-off-by: Marino Faggiana <8616947+marinofaggiana@users.noreply.github.com> * add async/await searchMedia Signed-off-by: Marino Faggiana <8616947+marinofaggiana@users.noreply.github.com> * Livephoto detect (#51) * Update NKModel.swift * cleaning Signed-off-by: Marino Faggiana * Fix build on macOS broken by freeDisk change (#53) Signed-off-by: Claudio Cambra * livePhotoFile -> fileId Signed-off-by: Marino Faggiana * rollback Signed-off-by: Marino Faggiana * rollback Signed-off-by: Marino Faggiana * Fix error description chunk Signed-off-by: Marino Faggiana * chunk error fix Signed-off-by: Marino Faggiana * errorDescription Signed-off-by: Marino Faggiana * added description Signed-off-by: Marino Faggiana * Change to markdown Signed-off-by: Milen Pivchev * Added e2ee options versionApi Signed-off-by: Marino Faggiana * change variable name Signed-off-by: Marino Faggiana * endpoint update Signed-off-by: Marino Faggiana * Fix chunk S3 (#56) * cod Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * public func Signed-off-by: Marino Faggiana * lint Signed-off-by: Marino Faggiana * remove description Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * fix log Signed-off-by: Marino Faggiana * Resolution - GPS (#59) * fix resolution-gps Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * set h, w to Double Signed-off-by: Marino Faggiana * coding (#61) Signed-off-by: Marino Faggiana * normalized taskHandler taskHandler(task) }. Signed-off-by: Marino Faggiana * add filename in trash (#63) * add filename Signed-off-by: Marino Faggiana * disable Build and test Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * Nextcloud Assistant (#66) * getTextProcessingTaskTypes Signed-off-by: Marino Faggiana * getTextProcessingTaskTypes Signed-off-by: Marino Faggiana * NKTextProcessingTaskTypes Signed-off-by: Marino Faggiana * coding Signed-off-by: Marino Faggiana * coding Signed-off-by: Marino Faggiana * coding Signed-off-by: Marino Faggiana * coding Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Add init Signed-off-by: Milen Pivchev * Change model Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev --------- Signed-off-by: Marino Faggiana Signed-off-by: Milen Pivchev Co-authored-by: Milen Pivchev * Add support for visionOS, fix tvOS and watchOS support (#67) * Add CoreServices import for visionOS Signed-off-by: Claudio Cambra * Fix screen scaling calculation when UIScreen is not available (for visionOS) Signed-off-by: Claudio Cambra * Fix availability of UIImage.resizeImage on non iOS platforms Signed-off-by: Claudio Cambra * Add visionOS target support to NextcloudKit Signed-off-by: Claudio Cambra * Bump watchOS version up, per dependency requirements Signed-off-by: Claudio Cambra * Remove reachability observation on watchOS, as this is unsupported in Alamofire Signed-off-by: Claudio Cambra * Remove free disk calculation on watchOS which cannot be done Signed-off-by: Claudio Cambra * Bump up tvOS version per dependencies Signed-off-by: Claudio Cambra * Also restrict free space calculation on tvOS, as unavailable Signed-off-by: Claudio Cambra --------- Signed-off-by: Claudio Cambra * Task description (#70) * coding Signed-off-by: Marino Faggiana * task.taskDescription Signed-off-by: Marino Faggiana * DownloadingFinish Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * improvements Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * change TypeIconFile (#71) Signed-off-by: Marino Faggiana * Core Preview Improvements and use only fileId Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * improvements Signed-off-by: Marino Faggiana * Improvements Signed-off-by: Marino Faggiana * added compressionQuality Signed-off-by: Marino Faggiana * Improvements (#76) Signed-off-by: Marino Faggiana * improved code Signed-off-by: Marino Faggiana * fix paramenters default Signed-off-by: Marino Faggiana * fix paramenters default Signed-off-by: Marino Faggiana * improvements Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * improvements Signed-off-by: Marino Faggiana * downloadPreview Signed-off-by: Marino Faggiana * added downloadPreview url Signed-off-by: Marino Faggiana * httpCookieStorage (#80) Signed-off-by: Marino Faggiana * new getUserProfile() Signed-off-by: Marino Faggiana * change paramenter name Signed-off-by: Marino Faggiana * Account (#82) * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * Revert "cod" This reverts commit 83b75a17686ad446e7f720c28b542c5cabdda4c9. Signed-off-by: Marino Faggiana * Filename validator (#83) * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * cleanup Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Make singleton Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev --------- Signed-off-by: Milen Pivchev * fix session delegate Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * Filename validator (#92) * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * cleanup Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Make singleton Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev --------- Signed-off-by: Milen Pivchev Co-authored-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * NextcloudKit Version 5 - Multisession (#94) --------- Signed-off-by: Marino Faggiana Signed-off-by: Milen Pivchev Co-authored-by: Milen Pivchev * NextcloudKit V 5 Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * requestCachePolicy Signed-off-by: Marino Faggiana * cache Signed-off-by: Marino Faggiana * cache Signed-off-by: Marino Faggiana * cache Signed-off-by: Marino Faggiana * Add optional spaces and periods - WCF Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev * Response (#97) * API Signed-off-by: Marino Faggiana * assistant Signed-off-by: Marino Faggiana * comments Signed-off-by: Marino Faggiana * dashboard Signed-off-by: Marino Faggiana * e2ee Signed-off-by: Marino Faggiana * groupfolders Signed-off-by: Marino Faggiana * hovercard Signed-off-by: Marino Faggiana * login Signed-off-by: Marino Faggiana * nctext Signed-off-by: Marino Faggiana * pn Signed-off-by: Marino Faggiana * richdocuments Signed-off-by: Marino Faggiana * search Signed-off-by: Marino Faggiana * share Signed-off-by: Marino Faggiana * userstatus Signed-off-by: Marino Faggiana * webdav Signed-off-by: Marino Faggiana * upload Signed-off-by: Marino Faggiana * API Signed-off-by: Marino Faggiana * download Signed-off-by: Marino Faggiana * upload Signed-off-by: Marino Faggiana * NextcloudKitSessionDelegate Signed-off-by: Marino Faggiana * normalized Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * ThreadSafeArray Signed-off-by: Marino Faggiana * logger delegate Signed-off-by: Marino Faggiana * fix message 503 Signed-off-by: Marino Faggiana * public Signed-off-by: Marino Faggiana * fix error Signed-off-by: Marino Faggiana * Add reuse compliance (#96) * Auto rename (#99) * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * License Signed-off-by: Milen Pivchev * Licenses Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Swiftlint fixes Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Fix lint issue Signed-off-by: Milen Pivchev * Fix ordering Signed-off-by: Milen Pivchev * Refactor Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * License Signed-off-by: Milen Pivchev * Licenses Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Swiftlint fixes Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Fix lint issue Signed-off-by: Milen Pivchev * Fix ordering Signed-off-by: Milen Pivchev * Refactor Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev --------- Signed-off-by: Milen Pivchev Co-authored-by: Marino Faggiana * Keep original extension Signed-off-by: Milen Pivchev * Refactor Signed-off-by: Milen Pivchev * License (#102) Signed-off-by: Marino Faggiana * ( multipathServiceType ) Signed-off-by: Marino Faggiana * Add more extensive test for AutoRenamer (#101) * Add more extensive test Signed-off-by: Milen Pivchev * Force check Signed-off-by: Milen Pivchev * Revert "Force check" This reverts commit b7fadf683cb15be6f92ac6d9de6436db5bd4eb9e. * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev --------- Signed-off-by: Milen Pivchev Co-authored-by: Marino Faggiana * Split NKModel.swift into designated source code files for every contained type. Signed-off-by: Iva Horn * Update README.md (#106) Signed-off-by: Milen Pivchev * Prettier Landing Page (#108) - Replaced logo with an self-created image based on the Apple symbol design for frameworks. - Removed the "V 2" in the top level heading because it contradicts the current major version 5. - Corrected alt text of image which appears to be copied and pasted from Nextcloud iOS app README. - Improved orthography on testing headings. - Added syntax definitions to some code fences. - Minor formatting improvements. * Reenabled build on macOS. (#109) Certain APIs used were not available on macOS in general or the currently supported version per package manifest. I added necessary code switches to make the code at least build again. Co-authored-by: Marino Faggiana * Track ocId in NKTrash items (#110) Signed-off-by: Claudio Cambra * Dav pagination (#111) * add paginate Signed-off-by: Marino Faggiana * StandardHeaders Signed-off-by: Marino Faggiana * code Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * Terms of Service (#112) * tos Signed-off-by: Marino Faggiana * getTermsOfService Signed-off-by: Marino Faggiana * getTermsOfService Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * code Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * signTermsOfService Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * Added capabilities to manage share download limits. (#107) - Requesting share download limit capability of files_downloadlimit app. - Augmented WebDAV metadata requests and responses with optional share download limits. - Extended NextcloudKit with methods to manage share download limits via OCS. Signed-off-by: Iva Horn * Recommended files (#115) * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * improvements Signed-off-by: Marino Faggiana * Allow setting custom destinations in chunked upload (#116) * Allow setting a different destination file name from local file name in chunked upload Using macOS File Provider APIs we rely on the system to provide us with a URL pointing the an item's local modified contents. This URL last path component is a UUID and does not represent the expected file name of the item. The current API of uploadChunk presents a problem because it assumes the local content file's filename is the same as what will eventually be uploaded to the server. This commit addresses the issue by allowing users of this function to provide a destination file name which will replace the provided local filename, if used. Signed-off-by: Claudio Cambra * Make file chunks output directory customisable Currently the chunking procedure produces file chunks within the directory of the input file. However, this fails in cases where the directory is read-only. This can be fixed by allowing the chunked files output directory to be changed Signed-off-by: Claudio Cambra --------- Signed-off-by: Claudio Cambra * added httpMaximumConnectionsPerHost Signed-off-by: Marino Faggiana * httpMaximumConnectionsPerHost Signed-off-by: Marino Faggiana * appendSession Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * Added feature to get download limits explicitly via OCS API. Signed-off-by: Iva Horn * Update FileNameValidator.swift * Make NextcloudKit Swift 6 compatible (#119) * Define NKDownloadLimit as a sendable struct Signed-off-by: Claudio Cambra * Define NKFile as a sendable struct Signed-off-by: Claudio Cambra * Define NKSession as a sendable struct Signed-off-by: Claudio Cambra f Signed-off-by: Claudio Cambra * Define UTTypeConformsToServer as a sendable struct Signed-off-by: Claudio Cambra * Define NKError as a sendable, equatable struct Signed-off-by: Claudio Cambra * Convert ThreadSafeArray into a sendable struct This also modifies the behaviour of its methods to be sendable compliant by using locking instead of a dispatch queue Signed-off-by: Claudio Cambra * Make FileAutoRenamer Sendable compliant Signed-off-by: Claudio Cambra f autorenamer Signed-off-by: Claudio Cambra f autorenamer Signed-off-by: Claudio Cambra f autorenamer 3 Signed-off-by: Claudio Cambra * Make FileNameValidator Sendable compliant Signed-off-by: Claudio Cambra f filenamevalidator Signed-off-by: Claudio Cambra * Fix copyright header in NSLock extension Signed-off-by: Claudio Cambra * Use self createFolder rather than going for shared instance Signed-off-by: Claudio Cambra * Make NextcloudKitDelegate protocol sendable Signed-off-by: Claudio Cambra * Make NKBackground a final class Signed-off-by: Claudio Cambra * Make NextcloudKitSessionDelegate conform to sendable Signed-off-by: Claudio Cambra * Use the appropriate nkCommonInstance in NKSession initialiser Signed-off-by: Claudio Cambra * Make nkCommonInstance mutable in NextcloudKit Signed-off-by: Claudio Cambra * Only provide shared NextcloudKit instance on swift <6 Signed-off-by: Claudio Cambra f shared nckit Signed-off-by: Claudio Cambra * When using swift 6, use a task to retrieve screen scale on iOS Signed-off-by: Claudio Cambra * Make NKFileProperty a sendable struct Signed-off-by: Claudio Cambra f nkfileproperty Signed-off-by: Claudio Cambra * Convert NKCommon into a sendable struct This required modifying the caches into standard maps. Unfortunately NSCache is not sendable compliant. I have made the changes take effect only when building with Swift 6 Signed-off-by: Claudio Cambra * Fix whitespace handling in FileAutoRenamer Signed-off-by: Claudio Cambra * Remove leading dot for hidden file filenames in autorenamer This is seemingly expected by the autotests Signed-off-by: Claudio Cambra --------- Signed-off-by: Claudio Cambra Co-authored-by: Milen Pivchev * Add static/refactor Signed-off-by: Milen Pivchev * NextcloudKitDelegate Signed-off-by: Marino Faggiana * change Name to NKMonitor Signed-off-by: Marino Faggiana * Added NKInterceptor Signed-off-by: Marino Faggiana * Interceptor Signed-off-by: Marino Faggiana * Interceptor Signed-off-by: Marino Faggiana * interceptor Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana * Interceptor Signed-off-by: Marino Faggiana * INterceptor Signed-off-by: Marino Faggiana * sendable Signed-off-by: Marino Faggiana * test Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana * checkUnauthorized Signed-off-by: Marino Faggiana * debug Signed-off-by: Marino Faggiana * X-NC-CheckUnauthorized Signed-off-by: Marino Faggiana * test Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * common (#121) * fix Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana * added checkUnauthorized options Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * setupLog Signed-off-by: Marino Faggiana * dependencies version updated Signed-off-by: Marino Faggiana * improved code Signed-off-by: Marino Faggiana * improved Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana * debugPrint Signed-off-by: Marino Faggiana * debugprint Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * log Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana * LOG (#123) * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana * added request delagate Signed-off-by: Marino Faggiana * cleaning Signed-off-by: Marino Faggiana * protocol NextcloudKitDelegate optional Signed-off-by: Marino Faggiana * added getRequestBodyFileExists Signed-off-by: Marino Faggiana * public Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * init Signed-off-by: Marino Faggiana * Interceptor & Monitor Improved (#126) * cod Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana * code Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana * improvements Signed-off-by: Marino Faggiana * cod Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana Co-authored-by: Marino Faggiana * Improved code Signed-off-by: Marino Faggiana * Improvements Signed-off-by: Marino Faggiana * Upload fix multisession (#129) * fix Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana Co-authored-by: Marino Faggiana * Fix: Login poll without cached responses. Signed-off-by: Milen Pivchev * Assistant V2 Signed-off-by: Milen Pivchev Fix compile Signed-off-by: Milen Pivchev Refactor Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev Refactor Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev WIP Signed-off-by: Milen Pivchev Refactor Signed-off-by: Milen Pivchev Finish Signed-off-by: Milen Pivchev Compliance Signed-off-by: Milen Pivchev PR fixes Signed-off-by: Milen Pivchev Assistant API v2 (#124) * WIP Signed-off-by: Milen Pivchev * Fix compile Signed-off-by: Milen Pivchev * Refactor Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Refactor Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * WIP Signed-off-by: Milen Pivchev * Refactor Signed-off-by: Milen Pivchev * Finish Signed-off-by: Milen Pivchev * Compliance Signed-off-by: Milen Pivchev * PR fixes Signed-off-by: Milen Pivchev * Upload fix multisession (#129) * fix Signed-off-by: Marino Faggiana * fix Signed-off-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana Co-authored-by: Marino Faggiana * Fix: Login poll without cached responses. Signed-off-by: Milen Pivchev * Linter Signed-off-by: Milen Pivchev --------- Signed-off-by: Milen Pivchev Signed-off-by: Marino Faggiana Co-authored-by: Marino Faggiana Co-authored-by: Marino Faggiana --------- Signed-off-by: Marino Faggiana <8616947+marinofaggiana@users.noreply.github.com> Signed-off-by: Marino Faggiana Signed-off-by: Claudio Cambra Signed-off-by: Milen Pivchev Signed-off-by: Iva Horn Co-authored-by: Marino Faggiana <8616947+marinofaggiana@users.noreply.github.com> Co-authored-by: Marino Faggiana Co-authored-by: Claudio Cambra Co-authored-by: Milen Pivchev Co-authored-by: Andy Scherzinger Co-authored-by: Iva Horn --- .../Assistant/v1/NKTextProcessingTask.swift | 71 ++++++++ .../v1/NKTextProcessingTaskType.swift | 38 ++++ .../Models/Assistant/v2/TaskList.swift | 97 ++++++++++ .../Models/Assistant/v2/TaskTypes.swift | 89 ++++++++++ .../NextcloudKit/NextcloudKit+Assistant.swift | 78 +-------- .../NextcloudKit+AssistantV2.swift | 165 ++++++++++++++++++ 6 files changed, 466 insertions(+), 72 deletions(-) create mode 100644 Sources/NextcloudKit/Models/Assistant/v1/NKTextProcessingTask.swift create mode 100644 Sources/NextcloudKit/Models/Assistant/v1/NKTextProcessingTaskType.swift create mode 100644 Sources/NextcloudKit/Models/Assistant/v2/TaskList.swift create mode 100644 Sources/NextcloudKit/Models/Assistant/v2/TaskTypes.swift create mode 100644 Sources/NextcloudKit/NextcloudKit+AssistantV2.swift diff --git a/Sources/NextcloudKit/Models/Assistant/v1/NKTextProcessingTask.swift b/Sources/NextcloudKit/Models/Assistant/v1/NKTextProcessingTask.swift new file mode 100644 index 00000000..533413f1 --- /dev/null +++ b/Sources/NextcloudKit/Models/Assistant/v1/NKTextProcessingTask.swift @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2025 Milen Pivchev +// SPDX-License-Identifier: GPL-3.0-or-later + +import SwiftyJSON + +public class NKTextProcessingTask { + public var id: Int? + public var type: String? + public var status: Int? + public var userId: String? + public var appId: String? + public var input: String? + public var output: String? + public var identifier: String? + public var completionExpectedAt: Double? + + public init(id: Int? = nil, type: String? = nil, status: Int? = nil, userId: String? = nil, appId: String? = nil, input: String? = nil, output: String? = nil, identifier: String? = nil, completionExpectedAt: Double? = nil) { + self.id = id + self.type = type + self.status = status + self.userId = userId + self.appId = appId + self.input = input + self.output = output + self.identifier = identifier + self.completionExpectedAt = completionExpectedAt + } + + public init?(json: JSON) { + self.id = json["id"].int + self.type = json["type"].string + self.status = json["status"].int + self.userId = json["userId"].string + self.appId = json["appId"].string + self.input = json["input"].string + self.output = json["output"].string + self.identifier = json["identifier"].string + self.completionExpectedAt = json["completionExpectedAt"].double + } + + static func deserialize(multipleObjects data: JSON) -> [NKTextProcessingTask]? { + guard let allResults = data.array else { return nil } + return allResults.compactMap(NKTextProcessingTask.init) + } + + static func deserialize(singleObject data: JSON) -> NKTextProcessingTask? { + NKTextProcessingTask(json: data) + } + + public static func toV2(tasks: [NKTextProcessingTask]) -> TaskList { + let tasks = tasks.map { task in + AssistantTask( + id: Int64(task.id ?? 0), + type: task.type, + status: String(task.status ?? 0), + userId: task.userId, + appId: task.appId, + input: TaskInput(input: task.input), + output: TaskOutput(output: task.output), + completionExpectedAt: Int(task.completionExpectedAt ?? 0), + progress: nil, + lastUpdated: nil, + scheduledAt: nil, + endedAt: nil + ) + } + + return TaskList(tasks: tasks) + } +} diff --git a/Sources/NextcloudKit/Models/Assistant/v1/NKTextProcessingTaskType.swift b/Sources/NextcloudKit/Models/Assistant/v1/NKTextProcessingTaskType.swift new file mode 100644 index 00000000..5841b4bf --- /dev/null +++ b/Sources/NextcloudKit/Models/Assistant/v1/NKTextProcessingTaskType.swift @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2025 Milen Pivchev +// SPDX-License-Identifier: GPL-3.0-or-later + +import SwiftyJSON + +public class NKTextProcessingTaskType { + public var id: String? + public var name: String? + public var description: String? + + public init(id: String? = nil, name: String? = nil, description: String? = nil) { + self.id = id + self.name = name + self.description = description + } + + public init?(json: JSON) { + self.id = json["id"].string + self.name = json["name"].string + self.description = json["description"].string + } + + static func deserialize(multipleObjects data: JSON) -> [NKTextProcessingTaskType]? { + guard let allResults = data.array else { return nil } + return allResults.compactMap(NKTextProcessingTaskType.init) + } + + public static func toV2(type: [NKTextProcessingTaskType]) -> TaskTypes { + let types = type.map { type in + TaskTypeData(id: type.id, name: type.name, description: type.description, inputShape: nil, outputShape: nil) + } + + return TaskTypes(types: types) + } +} + + diff --git a/Sources/NextcloudKit/Models/Assistant/v2/TaskList.swift b/Sources/NextcloudKit/Models/Assistant/v2/TaskList.swift new file mode 100644 index 00000000..b17978a8 --- /dev/null +++ b/Sources/NextcloudKit/Models/Assistant/v2/TaskList.swift @@ -0,0 +1,97 @@ +// SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2025 Milen Pivchev +// SPDX-License-Identifier: GPL-3.0-or-later + +import SwiftyJSON + +public struct TaskList: Codable { + public var tasks: [AssistantTask] + + static func deserialize(from data: JSON) -> TaskList? { + let tasks = data.arrayValue.map { taskJson in + AssistantTask( + id: taskJson["id"].int64Value, + type: taskJson["type"].string, + status: taskJson["status"].string, + userId: taskJson["userId"].string, + appId: taskJson["appId"].string, + input: TaskInput(input: taskJson["input"]["input"].string), + output: TaskOutput(output: taskJson["output"]["output"].string), + completionExpectedAt: taskJson["completionExpectedAt"].int, + progress: taskJson["progress"].int, + lastUpdated: taskJson["lastUpdated"].int, + scheduledAt: taskJson["scheduledAt"].int, + endedAt: taskJson["endedAt"].int + ) + } + + return TaskList(tasks: tasks) + } +} + +public struct AssistantTask: Codable { + public let id: Int64 + public let type: String? + public let status: String? + public let userId: String? + public let appId: String? + public let input: TaskInput? + public let output: TaskOutput? + public let completionExpectedAt: Int? + public var progress: Int? + public let lastUpdated: Int? + public let scheduledAt: Int? + public let endedAt: Int? + + public init(id: Int64, type: String?, status: String?, userId: String?, appId: String?, input: TaskInput?, output: TaskOutput?, completionExpectedAt: Int?, progress: Int? = nil, lastUpdated: Int?, scheduledAt: Int?, endedAt: Int?) { + self.id = id + self.type = type + self.status = status + self.userId = userId + self.appId = appId + self.input = input + self.output = output + self.completionExpectedAt = completionExpectedAt + self.progress = progress + self.lastUpdated = lastUpdated + self.scheduledAt = scheduledAt + self.endedAt = endedAt + } + + static func deserialize(from data: JSON) -> AssistantTask? { + let task = AssistantTask( + id: data["id"].int64Value, + type: data["type"].string, + status: data["status"].string, + userId: data["userId"].string, + appId: data["appId"].string, + input: TaskInput(input: data["input"]["input"].string), + output: TaskOutput(output: data["output"]["output"].string), + completionExpectedAt: data["completionExpectedAt"].int, + progress: data["progress"].int, + lastUpdated: data["lastUpdated"].int, + scheduledAt: data["scheduledAt"].int, + endedAt: data["endedAt"].int + ) + + return task + } +} + +public struct TaskInput: Codable { + public var input: String? + + public init(input: String? = nil) { + self.input = input + } +} + +public struct TaskOutput: Codable { + public var output: String? + + public init(output: String? = nil) { + self.output = output + } +} + + diff --git a/Sources/NextcloudKit/Models/Assistant/v2/TaskTypes.swift b/Sources/NextcloudKit/Models/Assistant/v2/TaskTypes.swift new file mode 100644 index 00000000..70b502a7 --- /dev/null +++ b/Sources/NextcloudKit/Models/Assistant/v2/TaskTypes.swift @@ -0,0 +1,89 @@ +// SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2025 Milen Pivchev +// SPDX-License-Identifier: GPL-3.0-or-later + +import SwiftyJSON + +public struct TaskTypes: Codable { + public let types: [TaskTypeData] + + static func deserialize(from data: JSON) -> TaskTypes? { + var taskTypes: [TaskTypeData] = [] + + for (key, subJson) in data { + let taskTypeData = TaskTypeData( + id: key, + name: subJson["name"].string, + description: subJson["description"].string, + inputShape: subJson["inputShape"].dictionary != nil ? TaskInputShape( + input: subJson["inputShape"]["input"].dictionary != nil ? Shape( + name: subJson["inputShape"]["input"]["name"].stringValue, + description: subJson["inputShape"]["input"]["description"].stringValue, + type: subJson["inputShape"]["input"]["type"].stringValue + ) : nil + ) : nil, + outputShape: subJson["outputShape"].dictionary != nil ? TaskOutputShape( + output: subJson["outputShape"]["output"].dictionary != nil ? Shape( + name: subJson["outputShape"]["output"]["name"].stringValue, + description: subJson["outputShape"]["output"]["description"].stringValue, + type: subJson["outputShape"]["output"]["type"].stringValue + ) : nil + ) : nil + ) + + taskTypes.append(taskTypeData) + } + + return TaskTypes(types: taskTypes) + } +} + +public struct TaskTypeData: Codable { + public let id: String? + public let name: String? + public let description: String? + public let inputShape: TaskInputShape? + public let outputShape: TaskOutputShape? + + public init(id: String?, name: String?, description: String?, inputShape: TaskInputShape?, outputShape: TaskOutputShape?) { + self.id = id + self.name = name + self.description = description + self.inputShape = inputShape + self.outputShape = outputShape + } +} + +public struct TaskInputShape: Codable { + public let input: Shape? + + public init(input: Shape?) { + self.input = input + } +} + +public struct TaskOutputShape: Codable { + public let output: Shape? + + public init(output: Shape?) { + self.output = output + } +} + +public struct Shape: Codable { + public let name: String + public let description: String + public let type: String + + public init(name: String, description: String, type: String) { + self.name = name + self.description = description + self.type = type + } +} + + + + + + diff --git a/Sources/NextcloudKit/NextcloudKit+Assistant.swift b/Sources/NextcloudKit/NextcloudKit+Assistant.swift index 992e870d..2d795052 100644 --- a/Sources/NextcloudKit/NextcloudKit+Assistant.swift +++ b/Sources/NextcloudKit/NextcloudKit+Assistant.swift @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: Nextcloud GmbH -// SPDX-FileCopyrightText: 2024 Marino Faggiana +// SPDX-FileCopyrightText: 2025 Milen Pivchev // SPDX-License-Identifier: GPL-3.0-or-later import Foundation @@ -34,7 +34,7 @@ public extension NextcloudKit { let data = json["ocs"]["data"]["types"] let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError if 200..<300 ~= statusCode { - let results = NKTextProcessingTaskType.factory(data: data) + let results = NKTextProcessingTaskType.deserialize(multipleObjects: data) options.queue.async { completion(account, results, response, .success) } } else { options.queue.async { completion(account, nil, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } @@ -75,7 +75,7 @@ public extension NextcloudKit { let data = json["ocs"]["data"]["task"] let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError if 200..<300 ~= statusCode { - let result = NKTextProcessingTask.factory(data: data) + let result = NKTextProcessingTask.deserialize(singleObject: data) options.queue.async { completion(account, result, response, .success) } } else { options.queue.async { completion(account, nil, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } @@ -112,7 +112,7 @@ public extension NextcloudKit { let data = json["ocs"]["data"]["task"] let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError if 200..<300 ~= statusCode { - let result = NKTextProcessingTask.factory(data: data) + let result = NKTextProcessingTask.deserialize(singleObject: data) options.queue.async { completion(account, result, response, .success) } } else { options.queue.async { completion(account, nil, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } @@ -149,7 +149,7 @@ public extension NextcloudKit { let data = json["ocs"]["data"]["task"] let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError if 200..<300 ~= statusCode { - let result = NKTextProcessingTask.factory(data: data) + let result = NKTextProcessingTask.deserialize(singleObject: data) options.queue.async { completion(account, result, response, .success) } } else { options.queue.async { completion(account, nil, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } @@ -186,7 +186,7 @@ public extension NextcloudKit { let data = json["ocs"]["data"]["tasks"] let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError if 200..<300 ~= statusCode { - let results = NKTextProcessingTask.factories(data: data) + let results = NKTextProcessingTask.deserialize(multipleObjects: data) options.queue.async { completion(account, results, response, .success) } } else { options.queue.async { completion(account, nil, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } @@ -196,70 +196,4 @@ public extension NextcloudKit { } } -public class NKTextProcessingTaskType { - public var id: String? - public var name: String? - public var description: String? - public init(id: String? = nil, name: String? = nil, description: String? = nil) { - self.id = id - self.name = name - self.description = description - } - - public init?(json: JSON) { - self.id = json["id"].string - self.name = json["name"].string - self.description = json["description"].string - } - - static func factory(data: JSON) -> [NKTextProcessingTaskType]? { - guard let allResults = data.array else { return nil } - return allResults.compactMap(NKTextProcessingTaskType.init) - } -} - -public class NKTextProcessingTask { - public var id: Int? - public var type: String? - public var status: Int? - public var userId: String? - public var appId: String? - public var input: String? - public var output: String? - public var identifier: String? - public var completionExpectedAt: Double? - - public init(id: Int? = nil, type: String? = nil, status: Int? = nil, userId: String? = nil, appId: String? = nil, input: String? = nil, output: String? = nil, identifier: String? = nil, completionExpectedAt: Double? = nil) { - self.id = id - self.type = type - self.status = status - self.userId = userId - self.appId = appId - self.input = input - self.output = output - self.identifier = identifier - self.completionExpectedAt = completionExpectedAt - } - - public init?(json: JSON) { - self.id = json["id"].int - self.type = json["type"].string - self.status = json["status"].int - self.userId = json["userId"].string - self.appId = json["appId"].string - self.input = json["input"].string - self.output = json["output"].string - self.identifier = json["identifier"].string - self.completionExpectedAt = json["completionExpectedAt"].double - } - - static func factories(data: JSON) -> [NKTextProcessingTask]? { - guard let allResults = data.array else { return nil } - return allResults.compactMap(NKTextProcessingTask.init) - } - - static func factory(data: JSON) -> NKTextProcessingTask? { - NKTextProcessingTask(json: data) - } -} diff --git a/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift b/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift new file mode 100644 index 00000000..57e20c58 --- /dev/null +++ b/Sources/NextcloudKit/NextcloudKit+AssistantV2.swift @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2025 Milen Pivchev +// SPDX-License-Identifier: GPL-3.0-or-later + +import Foundation +import Alamofire +import SwiftyJSON + +public extension NextcloudKit { + func textProcessingGetTypesV2(account: String, + supportedTaskType: String = "Text", + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ types: [TaskTypeData]?, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { + let endpoint = "ocs/v2.php/taskprocessing/tasktypes" + guard let nkSession = nkCommonInstance.getSession(account: account), + let url = nkCommonInstance.createStandardUrl(serverUrl: nkSession.urlBase, endpoint: endpoint, options: options), + let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { + return options.queue.async { completion(account, nil, nil, .urlError) } + } + + nkSession.sessionData.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: NKInterceptor(nkCommonInstance: nkCommonInstance)).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in + task.taskDescription = options.taskDescription + taskHandler(task) + }.responseData(queue: self.nkCommonInstance.backgroundQueue) { response in + if self.nkCommonInstance.levelLog > 0 { + debugPrint(response) + } + switch response.result { + case .failure(let error): + let error = NKError(error: error, afResponse: response, responseData: response.data) + options.queue.async { completion(account, nil, response, error) } + case .success(let jsonData): + let json = JSON(jsonData) + let data = json["ocs"]["data"]["types"] + let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError + if 200..<300 ~= statusCode { + let dict = TaskTypes.deserialize(from: data) + let result = dict?.types.map({$0}) + var filteredResult = result? + .filter({ $0.inputShape?.input?.type == supportedTaskType && $0.outputShape?.output?.type == supportedTaskType }) + .sorted(by: {$0.id! < $1.id!}) + options.queue.async { completion(account, filteredResult, response, .success) } + } else { + options.queue.async { completion(account, nil, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } + } + } + } + } + + func textProcessingScheduleV2(input: String, + taskType: TaskTypeData, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ task: AssistantTask?, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { + let endpoint = "/ocs/v2.php/taskprocessing/schedule" + guard let nkSession = nkCommonInstance.getSession(account: account), + let url = nkCommonInstance.createStandardUrl(serverUrl: nkSession.urlBase, endpoint: endpoint, options: options), + let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { + return options.queue.async { completion(account, nil, nil, .urlError) } + } + + let inputField: [String: String] = ["input": input] + let parameters: [String: Any] = ["input": inputField, "type": taskType.id ?? "", "appId": "assistant", "customId": ""] + + nkSession.sessionData.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers, interceptor: NKInterceptor(nkCommonInstance: nkCommonInstance)).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in + task.taskDescription = options.taskDescription + taskHandler(task) + }.responseData(queue: self.nkCommonInstance.backgroundQueue) { response in + if self.nkCommonInstance.levelLog > 0 { + debugPrint(response) + } + switch response.result { + case .failure(let error): + let error = NKError(error: error, afResponse: response, responseData: response.data) + options.queue.async { completion(account, nil, response, error) } + case .success(let jsonData): + let json = JSON(jsonData) + let data = json["ocs"]["data"]["task"] + let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError + if 200..<300 ~= statusCode { + let result = AssistantTask.deserialize(from: data) + options.queue.async { completion(account, result, response, .success) } + } else { + options.queue.async { completion(account, nil, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } + } + } + } + } + + func textProcessingGetTasksV2(taskType: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ tasks: TaskList?, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { + let endpoint = "/ocs/v2.php/taskprocessing/tasks?taskType=\(taskType)" + guard let nkSession = nkCommonInstance.getSession(account: account), + let url = nkCommonInstance.createStandardUrl(serverUrl: nkSession.urlBase, endpoint: endpoint, options: options), + let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { + return options.queue.async { completion(account, nil, nil, .urlError) } + } + + nkSession.sessionData.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: NKInterceptor(nkCommonInstance: nkCommonInstance)).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in + task.taskDescription = options.taskDescription + taskHandler(task) + }.responseData(queue: self.nkCommonInstance.backgroundQueue) { response in + if self.nkCommonInstance.levelLog > 0 { + debugPrint(response) + } + switch response.result { + case .failure(let error): + let error = NKError(error: error, afResponse: response, responseData: response.data) + options.queue.async { completion(account, nil, response, error) } + case .success(let jsonData): + let json = JSON(jsonData) + let data = json["ocs"]["data"]["tasks"] + let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError + if 200..<300 ~= statusCode { + let result = TaskList.deserialize(from: data) + options.queue.async { completion(account, result, response, .success) } + } else { + options.queue.async { completion(account, nil, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } + } + } + } + } + + func textProcessingDeleteTaskV2(taskId: Int64, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { + let endpoint = "/ocs/v2.php/taskprocessing/task/\(taskId)" + guard let nkSession = nkCommonInstance.getSession(account: account), + let url = nkCommonInstance.createStandardUrl(serverUrl: nkSession.urlBase, endpoint: endpoint, options: options), + let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { + return options.queue.async { completion(account, nil, .urlError) } + } + + nkSession.sessionData.request(url, method: .delete, encoding: URLEncoding.default, headers: headers, interceptor: NKInterceptor(nkCommonInstance: nkCommonInstance)).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in + task.taskDescription = options.taskDescription + taskHandler(task) + }.responseData(queue: self.nkCommonInstance.backgroundQueue) { response in + if self.nkCommonInstance.levelLog > 0 { + debugPrint(response) + } + switch response.result { + case .failure(let error): + let error = NKError(error: error, afResponse: response, responseData: response.data) + options.queue.async { completion(account, response, error) } + case .success(let jsonData): + let json = JSON(jsonData) + let statusCode = json["ocs"]["meta"]["statuscode"].int ?? NKError.internalError + if 200..<300 ~= statusCode { + options.queue.async { completion(account, response, .success) } + } else { + options.queue.async { completion(account, response, NKError(rootJson: json, fallbackStatusCode: response.response?.statusCode)) } + } + } + } + } +} + + From 7c972afb65db623c58c9be30ce431f5b8092fd35 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Thu, 24 Apr 2025 13:02:48 +0200 Subject: [PATCH 2/3] cod Signed-off-by: Marino Faggiana --- Sources/NextcloudKit/NKSession.swift | 27 +++++++++++++++------ Sources/NextcloudKit/NextcloudKit+API.swift | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Sources/NextcloudKit/NKSession.swift b/Sources/NextcloudKit/NKSession.swift index 1e66394a..bb968b8e 100644 --- a/Sources/NextcloudKit/NKSession.swift +++ b/Sources/NextcloudKit/NKSession.swift @@ -21,6 +21,7 @@ public struct NKSession: Sendable { public let dav: String = "remote.php/dav" public var internalTypeIdentifiers: [NKCommon.UTTypeConformsToServer] = [] public let sessionData: Alamofire.Session + public let sessionDataNoCache: Alamofire.Session public let sessionDownloadBackground: URLSession public let sessionUploadBackground: URLSession public let sessionUploadBackgroundWWan: URLSession @@ -56,23 +57,35 @@ public struct NKSession: Sendable { /// Strange but works ?!?! let sharedCookieStorage = user + "@" + urlBase - /// Session Alamofire - let configuration = URLSessionConfiguration.af.default - configuration.requestCachePolicy = requestCachePolicy - configuration.httpMaximumConnectionsPerHost = httpMaximumConnectionsPerHost + /// SessionData Alamofire + let configurationSessionData = URLSessionConfiguration.af.default + configurationSessionData.requestCachePolicy = requestCachePolicy + configurationSessionData.httpMaximumConnectionsPerHost = httpMaximumConnectionsPerHost #if os(iOS) || targetEnvironment(macCatalyst) - configuration.multipathServiceType = .handover + configurationSessionData.multipathServiceType = .handover #endif - configuration.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: sharedCookieStorage) - sessionData = Alamofire.Session(configuration: configuration, + configurationSessionData.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: sharedCookieStorage) + sessionData = Alamofire.Session(configuration: configurationSessionData, delegate: NextcloudKitSessionDelegate(nkCommonInstance: nkCommonInstance), rootQueue: nkCommonInstance.rootQueue, requestQueue: nkCommonInstance.requestQueue, serializationQueue: nkCommonInstance.serializationQueue, eventMonitors: [NKMonitor(nkCommonInstance: nkCommonInstance)]) + /// SessionDataNoCache Alamofire + let configurationSessionDataNoCache = URLSessionConfiguration.af.default + configurationSessionDataNoCache.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData + configurationSessionDataNoCache.httpMaximumConnectionsPerHost = httpMaximumConnectionsPerHost + + sessionDataNoCache = Alamofire.Session(configuration: configurationSessionDataNoCache, + delegate: NextcloudKitSessionDelegate(nkCommonInstance: nkCommonInstance), + rootQueue: nkCommonInstance.rootQueue, + requestQueue: nkCommonInstance.requestQueue, + serializationQueue: nkCommonInstance.serializationQueue, + eventMonitors: [NKMonitor(nkCommonInstance: nkCommonInstance)]) + /// Session Download Background let configurationDownloadBackground = URLSessionConfiguration.background(withIdentifier: NKCommon().getSessionConfigurationIdentifier(NKCommon().identifierSessionDownloadBackground, account: account)) configurationDownloadBackground.allowsCellularAccess = true diff --git a/Sources/NextcloudKit/NextcloudKit+API.swift b/Sources/NextcloudKit/NextcloudKit+API.swift index c07077f3..3c25c0d6 100644 --- a/Sources/NextcloudKit/NextcloudKit+API.swift +++ b/Sources/NextcloudKit/NextcloudKit+API.swift @@ -463,7 +463,7 @@ public extension NextcloudKit { return options.queue.async { completion(account, nil, nil, .urlError) } } - nkSession.sessionData.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: NKInterceptor(nkCommonInstance: nkCommonInstance)).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in + nkSession.sessionDataNoCache.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: NKInterceptor(nkCommonInstance: nkCommonInstance)).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in task.taskDescription = options.taskDescription taskHandler(task) }.responseData(queue: self.nkCommonInstance.backgroundQueue) { response in From b7f0fddb93901cc5823410fd9abfb172668337e5 Mon Sep 17 00:00:00 2001 From: Marino Faggiana Date: Thu, 24 Apr 2025 13:39:04 +0200 Subject: [PATCH 3/3] remove unused parameter Signed-off-by: Marino Faggiana --- Sources/NextcloudKit/NKSession.swift | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Sources/NextcloudKit/NKSession.swift b/Sources/NextcloudKit/NKSession.swift index bb968b8e..2a9b169d 100644 --- a/Sources/NextcloudKit/NKSession.swift +++ b/Sources/NextcloudKit/NKSession.swift @@ -17,7 +17,6 @@ public struct NKSession: Sendable { public let httpMaximumConnectionsPerHost: Int public let httpMaximumConnectionsPerHostInDownload: Int public let httpMaximumConnectionsPerHostInUpload: Int - public let requestCachePolicy: URLRequest.CachePolicy public let dav: String = "remote.php/dav" public var internalTypeIdentifiers: [NKCommon.UTTypeConformsToServer] = [] public let sessionData: Alamofire.Session @@ -38,8 +37,7 @@ public struct NKSession: Sendable { groupIdentifier: String, httpMaximumConnectionsPerHost: Int, httpMaximumConnectionsPerHostInDownload: Int, - httpMaximumConnectionsPerHostInUpload: Int, - requestCachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy) { + httpMaximumConnectionsPerHostInUpload: Int) { self.urlBase = urlBase self.user = user self.userId = userId @@ -51,7 +49,6 @@ public struct NKSession: Sendable { self.httpMaximumConnectionsPerHost = httpMaximumConnectionsPerHost self.httpMaximumConnectionsPerHostInDownload = httpMaximumConnectionsPerHostInDownload self.httpMaximumConnectionsPerHostInUpload = httpMaximumConnectionsPerHostInUpload - self.requestCachePolicy = requestCachePolicy let backgroundSessionDelegate = NKBackground(nkCommonInstance: nkCommonInstance) /// Strange but works ?!?! @@ -59,7 +56,7 @@ public struct NKSession: Sendable { /// SessionData Alamofire let configurationSessionData = URLSessionConfiguration.af.default - configurationSessionData.requestCachePolicy = requestCachePolicy + configurationSessionData.requestCachePolicy = .useProtocolCachePolicy configurationSessionData.httpMaximumConnectionsPerHost = httpMaximumConnectionsPerHost #if os(iOS) || targetEnvironment(macCatalyst) @@ -96,7 +93,7 @@ public struct NKSession: Sendable { configurationDownloadBackground.isDiscretionary = false configurationDownloadBackground.httpMaximumConnectionsPerHost = self.httpMaximumConnectionsPerHostInDownload - configurationDownloadBackground.requestCachePolicy = requestCachePolicy + configurationDownloadBackground.requestCachePolicy = .useProtocolCachePolicy #if os(iOS) || targetEnvironment(macCatalyst) configurationDownloadBackground.multipathServiceType = .handover @@ -115,7 +112,7 @@ public struct NKSession: Sendable { configurationUploadBackground.isDiscretionary = false configurationUploadBackground.httpMaximumConnectionsPerHost = self.httpMaximumConnectionsPerHostInUpload - configurationUploadBackground.requestCachePolicy = requestCachePolicy + configurationUploadBackground.requestCachePolicy = .useProtocolCachePolicy #if os(iOS) || targetEnvironment(macCatalyst) configurationUploadBackground.multipathServiceType = .handover @@ -134,7 +131,7 @@ public struct NKSession: Sendable { configurationUploadBackgroundWWan.isDiscretionary = false configurationUploadBackgroundWWan.httpMaximumConnectionsPerHost = self.httpMaximumConnectionsPerHostInUpload - configurationUploadBackgroundWWan.requestCachePolicy = requestCachePolicy + configurationUploadBackgroundWWan.requestCachePolicy = .useProtocolCachePolicy configurationUploadBackgroundWWan.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: sharedCookieStorage) sessionUploadBackgroundWWan = URLSession(configuration: configurationUploadBackgroundWWan, delegate: backgroundSessionDelegate, delegateQueue: OperationQueue.main) @@ -148,7 +145,7 @@ public struct NKSession: Sendable { configurationUploadBackgroundExt.isDiscretionary = false configurationUploadBackgroundExt.httpMaximumConnectionsPerHost = self.httpMaximumConnectionsPerHostInUpload - configurationUploadBackgroundExt.requestCachePolicy = requestCachePolicy + configurationUploadBackgroundExt.requestCachePolicy = .useProtocolCachePolicy configurationUploadBackgroundExt.sharedContainerIdentifier = groupIdentifier #if os(iOS) || targetEnvironment(macCatalyst)