Merge pull request #8136 from nextcloud/work/separate-fpext-db-compat

feat(FileProvider): Adopt NextcloudFileProviderKit 2.1
This commit is contained in:
Matthieu Gallien 2025-05-06 09:45:59 +02:00 committed by GitHub
commit 9f774908db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 126 additions and 19 deletions

View File

@ -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()

View File

@ -149,6 +149,7 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
Task { @MainActor in
ncAccount = account
dbManager = FilesDatabaseManager(account: account)
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<UUID>) {

View File

@ -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
)

View File

@ -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? = {
@ -105,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 {
@ -154,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(
"""
@ -172,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)
@ -209,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()
}
@ -228,7 +259,8 @@ import OSLog
domain: self.domain,
account: ncAccount,
remoteInterface: ncKit,
progress: progress
progress: progress,
dbManager: dbManager
)
if error != nil {
@ -282,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."
@ -303,7 +349,8 @@ import OSLog
options: options,
request: request,
domain: domain,
progress: progress
progress: progress,
dbManager: dbManager
)
if error != nil {
@ -341,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"
@ -354,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 })
@ -372,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
)
@ -394,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)"
@ -404,7 +487,7 @@ import OSLog
let materialisedEnumerator = fpManager.enumeratorForMaterializedItems()
let materialisedObserver = MaterialisedEnumerationObserver(
ncKitAccount: ncAccount.ncKitAccount
ncKitAccount: ncAccount.ncKitAccount, dbManager: dbManager
) { _ in
completionHandler()
}

View File

@ -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

View File

@ -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;
@ -1528,7 +1530,7 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/claucambra/NextcloudFileProviderKit.git";
requirement = {
branch = "stable-2.0";
branch = "stable-2.1";
kind = branch;
};
};