From fed1cfd74636031882347685dc070033ab57e8cb Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 9 Apr 2025 15:21:08 +0900 Subject: [PATCH 01/10] feat(shell_integration/macOS/FileProviderExt): Move to separate db NCFPK branch Signed-off-by: Claudio Cambra --- .../NextcloudIntegration.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index 4fd49162ff..6adbdd714d 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -1528,7 +1528,7 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/claucambra/NextcloudFileProviderKit.git"; requirement = { - branch = "stable-2.0"; + branch = "bugfix/separate-db"; kind = branch; }; }; From c75c4c46a3084fba0e8ed709390a304e34664c28 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 9 Apr 2025 15:16:18 +0900 Subject: [PATCH 02/10] feat(shell_integration/macOS/FileProviderExt): Configure specific instance of FilesDatabaseManager for account Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension+ClientInterface.swift | 2 ++ .../FileProviderExt/FileProviderExtension.swift | 1 + 2 files changed, 3 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift index 03da389c8e..0ba1887387 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift @@ -149,6 +149,7 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte Task { @MainActor in ncAccount = account + dbManager = FilesDatabaseManager(account: account.ncKitAccount) changeObserver = RemoteChangeObserver( account: account, remoteInterface: ncKit, @@ -166,6 +167,7 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte "Received instruction to remove account data for user \(self.ncAccount!.username, privacy: .public) at server \(self.ncAccount!.serverUrl, privacy: .public)" ) ncAccount = nil + dbManager = nil } func updatedSyncStateReporting(oldActions: Set) { diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 9f9acf6311..229db72d35 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -14,6 +14,7 @@ import OSLog let ncKit = NextcloudKit.shared let appGroupIdentifier = Bundle.main.object(forInfoDictionaryKey: "SocketApiPrefix") as? String var ncAccount: Account? + var dbManager: FilesDatabaseManager? var changeObserver: RemoteChangeObserver? lazy var ncKitBackground = NKBackground(nkCommonInstance: ncKit.nkCommonInstance) lazy var socketClient: LocalSocketClient? = { From bc111b1e48e380193cf2a375bbc8b18c29513c98 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 9 Apr 2025 15:18:31 +0900 Subject: [PATCH 03/10] feat(shell_integration/macOS/FileProviderExt): Pass dbManager into standard FileProviderExtension methods Signed-off-by: Claudio Cambra --- .../FileProviderExtension.swift | 99 ++++++++++++++++--- 1 file changed, 85 insertions(+), 14 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 229db72d35..af01ffbe76 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -106,9 +106,19 @@ import OSLog completionHandler(nil, NSFileProviderError(.notAuthenticated)) return Progress() } + guard let dbManager else { + Logger.fileProviderExtension.error( + """ + Not fetching item for identifier: \(identifier.rawValue, privacy: .public) + as database is unreachable + """ + ) + completionHandler(nil, NSFileProviderError(.cannotSynchronize)) + return Progress() + } if let item = Item.storedItem( - identifier: identifier, account: ncAccount, remoteInterface: ncKit + identifier: identifier, account: ncAccount, remoteInterface: ncKit, dbManager: dbManager ) { completionHandler(item, nil) } else { @@ -155,9 +165,22 @@ import OSLog completionHandler(nil, nil, NSFileProviderError(.notAuthenticated)) return Progress() } + guard let dbManager else { + Logger.fileProviderExtension.error( + """ + Not fetching contents for item: \(itemIdentifier.rawValue, privacy: .public) + as database is unreachable + """ + ) + completionHandler(nil, nil, NSFileProviderError(.cannotSynchronize)) + return Progress() + } guard let item = Item.storedItem( - identifier: itemIdentifier, account: ncAccount, remoteInterface: ncKit + identifier: itemIdentifier, + account: ncAccount, + remoteInterface: ncKit, + dbManager: dbManager ) else { Logger.fileProviderExtension.error( """ @@ -173,7 +196,7 @@ import OSLog let progress = Progress() Task { let (localUrl, updatedItem, error) = await item.fetchContents( - domain: self.domain, progress: progress + domain: self.domain, progress: progress, dbManager: dbManager ) removeSyncAction(actionId) completionHandler(localUrl, updatedItem, error) @@ -210,12 +233,19 @@ import OSLog """ ) insertErrorAction(actionId) - completionHandler( - itemTemplate, - NSFileProviderItemFields(), - false, - NSFileProviderError(.notAuthenticated) + completionHandler(itemTemplate, [], false, NSFileProviderError(.notAuthenticated)) + return Progress() + } + + guard let dbManager else { + Logger.fileProviderExtension.error( + """ + Not creating item: \(itemTemplate.itemIdentifier.rawValue, privacy: .public) + as database is unreachable + """ ) + insertErrorAction(actionId) + completionHandler(itemTemplate, [], false, NSFileProviderError(.cannotSynchronize)) return Progress() } @@ -229,7 +259,8 @@ import OSLog domain: self.domain, account: ncAccount, remoteInterface: ncKit, - progress: progress + progress: progress, + dbManager: dbManager ) if error != nil { @@ -283,8 +314,22 @@ import OSLog return Progress() } + + guard let dbManager else { + Logger.fileProviderExtension.error( + """ + Not modifying item: \(ocId, privacy: .public) + with filename: \(item.filename, privacy: .public) + as database is unreachable + """ + ) + insertErrorAction(actionId) + completionHandler(item, [], false, NSFileProviderError(.cannotSynchronize)) + return Progress() + } + guard let existingItem = Item.storedItem( - identifier: identifier, account: ncAccount, remoteInterface: ncKit + identifier: identifier, account: ncAccount, remoteInterface: ncKit, dbManager: dbManager ) else { Logger.fileProviderExtension.error( "Not modifying item: \(ocId, privacy: .public) as item not found." @@ -304,7 +349,8 @@ import OSLog options: options, request: request, domain: domain, - progress: progress + progress: progress, + dbManager: dbManager ) if error != nil { @@ -342,8 +388,17 @@ import OSLog return Progress() } + guard let dbManager else { + Logger.fileProviderExtension.error( + "Not deleting item \(identifier.rawValue, privacy: .public), db manager unavailable" + ) + insertErrorAction(actionId) + completionHandler(NSFileProviderError(.cannotSynchronize)) + return Progress() + } + guard let item = Item.storedItem( - identifier: identifier, account: ncAccount, remoteInterface: ncKit + identifier: identifier, account: ncAccount, remoteInterface: ncKit, dbManager: dbManager ) else { Logger.fileProviderExtension.error( "Not deleting item \(identifier.rawValue, privacy: .public), item not found" @@ -355,7 +410,7 @@ import OSLog let progress = Progress(totalUnitCount: 1) Task { - let error = await item.delete() + let error = await item.delete(dbManager: dbManager) if error != nil { insertErrorAction(actionId) signalEnumerator(completionHandler: { _ in }) @@ -373,15 +428,31 @@ import OSLog ) throws -> NSFileProviderEnumerator { guard let ncAccount else { Logger.fileProviderExtension.error( - "Not providing enumerator for container with identifier \(containerItemIdentifier.rawValue, privacy: .public) yet as account not set up" + """ + Not providing enumerator for container + with identifier \(containerItemIdentifier.rawValue, privacy: .public) yet + as account not set up + """ ) throw NSFileProviderError(.notAuthenticated) } + guard let dbManager else { + Logger.fileProviderExtension.error( + """ + Not providing enumerator for container + with identifier \(containerItemIdentifier.rawValue, privacy: .public) yet + as db manager is unavailable + """ + ) + throw NSFileProviderError(.cannotSynchronize) + } + return Enumerator( enumeratedItemIdentifier: containerItemIdentifier, account: ncAccount, remoteInterface: ncKit, + dbManager: dbManager, domain: domain, fastEnumeration: config.fastEnumerationEnabled ) From 52655ca9cec38acb4053d8eb0c758d12d14b1134 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 9 Apr 2025 15:19:15 +0900 Subject: [PATCH 04/10] feat(shell_integration/macOS/FileProviderExt): Also use specific dbManager for local file handling Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension.swift | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index af01ffbe76..bfa024c423 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -466,6 +466,17 @@ import OSLog return } + guard let dbManager else { + Logger.fileProviderExtension.error( + """ + Not purging stale local file metadatas. + db manager unabilable for domain: \(self.domain.displayName, privacy: .public) + """ + ) + completionHandler() + return + } + guard let fpManager = NSFileProviderManager(for: domain) else { Logger.fileProviderExtension.error( "Could not get file provider manager for domain: \(self.domain.displayName, privacy: .public)" @@ -476,7 +487,7 @@ import OSLog let materialisedEnumerator = fpManager.enumeratorForMaterializedItems() let materialisedObserver = MaterialisedEnumerationObserver( - ncKitAccount: ncAccount.ncKitAccount + ncKitAccount: ncAccount.ncKitAccount, dbManager: dbManager ) { _ in completionHandler() } From 49e560b819409e8c77fd25599c2cec379c4fa905 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 9 Apr 2025 15:19:39 +0900 Subject: [PATCH 05/10] feat(shell_integration/macOS/FileProviderExt): Use specific dbManager for thumbnailing Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension+Thumbnailing.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+Thumbnailing.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+Thumbnailing.swift index 9fb0f0edac..f608f5acf7 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+Thumbnailing.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+Thumbnailing.swift @@ -24,12 +24,17 @@ extension FileProviderExtension: NSFileProviderThumbnailing { completionHandler(NSFileProviderError(.notAuthenticated)) return Progress() } + guard let dbManager else { + completionHandler(NSFileProviderError(.cannotSynchronize)) + return Progress() + } return NextcloudFileProviderKit.fetchThumbnails( for: itemIdentifiers, requestedSize: size, account: ncAccount, usingRemoteInterface: self.ncKit, + andDatabase: dbManager, perThumbnailCompletionHandler: perThumbnailCompletionHandler, completionHandler: completionHandler ) From 550e698bc26a6131e1065326b3949829458a0b63 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 9 Apr 2025 15:20:17 +0900 Subject: [PATCH 06/10] feat(shell_integration/macOS/FileProviderExt): Also use specific db manager in FPUIExtensionServiceSource Signed-off-by: Claudio Cambra --- .../Services/FPUIExtensionServiceSource.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/FPUIExtensionServiceSource.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/FPUIExtensionServiceSource.swift index 5b8fd45751..9db037f269 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/FPUIExtensionServiceSource.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/FPUIExtensionServiceSource.swift @@ -53,7 +53,14 @@ class FPUIExtensionServiceSource: NSObject, NSFileProviderServiceSource, NSXPCLi return nil } - let dbManager = FilesDatabaseManager.shared + guard let account = fpExtension.ncAccount?.ncKitAccount else { + Logger.shares.error("Could not fetch ncKitAccount on parent extension") + return nil + } + guard let dbManager = fpExtension.dbManager else { + Logger.shares.error("Could not get db manager for \(account, privacy: .public)") + return nil + } guard let item = dbManager.itemMetadataFromFileProviderItemIdentifier(identifier) else { Logger.shares.error("No item \(rawIdentifier, privacy: .public) in db, no shares.") return nil From e2d9fd1e3ec7208af1cecb6bac72967fced149b3 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 10 Apr 2025 17:08:40 +0900 Subject: [PATCH 07/10] feat(shell_integration/macOS/FileProviderExt): Move to stable-2.1 branch of NCFPK Signed-off-by: Claudio Cambra --- .../NextcloudIntegration.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index 6adbdd714d..e1d04cb7f5 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -1528,7 +1528,7 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/claucambra/NextcloudFileProviderKit.git"; requirement = { - branch = "bugfix/separate-db"; + branch = "stable-2.1"; kind = branch; }; }; From 804c9ac0ab9107c25aff2c9187b7f72ac32357fa Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 21 Apr 2025 17:41:22 +0800 Subject: [PATCH 08/10] feat(shell_integration/macOS/FileProviderExt): Adapt to db manager changes and pass full account struct to init Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension+ClientInterface.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift index 0ba1887387..32d7552548 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift @@ -149,7 +149,7 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte Task { @MainActor in ncAccount = account - dbManager = FilesDatabaseManager(account: account.ncKitAccount) + dbManager = FilesDatabaseManager(account: account) changeObserver = RemoteChangeObserver( account: account, remoteInterface: ncKit, From bd216129d231a3cd8431765af76d231000652438 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 21 Apr 2025 17:42:03 +0800 Subject: [PATCH 09/10] feat(shell_integration/macOS/FileProviderExt): Fix Realm bundling when building FileProviderExt against NCFPK 2.1 Signed-off-by: Claudio Cambra --- shell_integration/MacOSX/CMakeLists.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/shell_integration/MacOSX/CMakeLists.txt b/shell_integration/MacOSX/CMakeLists.txt index a3f561484a..a9f0597978 100644 --- a/shell_integration/MacOSX/CMakeLists.txt +++ b/shell_integration/MacOSX/CMakeLists.txt @@ -69,9 +69,17 @@ if(APPLE) DESTINATION ${OSX_PLUGINS_INSTALL_DIR} USE_SOURCE_PERMISSIONS) + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${XCODE_TARGET_CONFIGURATION}/PackageFrameworks/RealmSwift.framework + DESTINATION ${OSX_PLUGINS_INSTALL_DIR}/FileProviderExt.appex/Contents/Frameworks + USE_SOURCE_PERMISSIONS) + install(DIRECTORY ${OSX_PLUGINS_BINARY_DIR}/FileProviderUIExt.appex - DESTINATION ${OSX_PLUGINS_INSTALL_DIR} - USE_SOURCE_PERMISSIONS) + DESTINATION ${OSX_PLUGINS_INSTALL_DIR} + USE_SOURCE_PERMISSIONS) + + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${XCODE_TARGET_CONFIGURATION}/PackageFrameworks/RealmSwift.framework + DESTINATION ${OSX_PLUGINS_INSTALL_DIR}/FileProviderUIExt.appex/Contents/Frameworks + USE_SOURCE_PERMISSIONS) endif() endif() endif() From f842be368f1ac0e890b6bd5d82bec763314c0d5f Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 29 Apr 2025 10:49:19 +0800 Subject: [PATCH 10/10] feat(shell_integration/macOS/FileProviderUIExt): Fix rpath for FileProviderUIExt Fixes crash from unable to load RealmSwift (required by dependency on NCFPK) Signed-off-by: Claudio Cambra --- .../NextcloudIntegration.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index e1d04cb7f5..ce29a33758 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -1072,6 +1072,7 @@ LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", + "@executable_path/../Frameworks", "@executable_path/../../Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; @@ -1132,6 +1133,7 @@ LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", + "@executable_path/../Frameworks", "@executable_path/../../Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES;