Skip to content

Commit ac9af29

Browse files
authored
Merge pull request #7824 from nextcloud/feature/ncfpk-2.0
shell_integration/macOS: Upgrade to NextcloudFileProviderKit 2.0
2 parents 6b7cf3f + bfe9a97 commit ac9af29

11 files changed

+137
-73
lines changed

shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift

+19-18
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,25 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
107107
@objc func setupDomainAccount(
108108
user: String, userId: String, serverUrl: String, password: String
109109
) {
110+
let account = Account(user: user, id: userId, serverUrl: serverUrl, password: password)
111+
guard account != ncAccount else { return }
112+
110113
Task {
111-
let authTestNcKit = NextcloudKit()
112-
authTestNcKit.setup(user: user, userId: userId, password: password, urlBase: serverUrl)
114+
ncKit.appendSession(
115+
account: account.ncKitAccount,
116+
urlBase: serverUrl,
117+
user: user,
118+
userId: userId,
119+
password: password,
120+
userAgent: "Nextcloud-macOS/FileProviderExt",
121+
nextcloudVersion: 25,
122+
groupIdentifier: ""
123+
)
113124
var authAttemptState = AuthenticationAttemptResultState.connectionError // default
114125

115126
// Retry a few times if we have a connection issue
116127
for authTimeout in AuthenticationTimeouts {
117-
authAttemptState = await authTestNcKit.tryAuthenticationAttempt()
128+
authAttemptState = await ncKit.tryAuthenticationAttempt(account: account)
118129
guard authAttemptState == .connectionError else { break }
119130

120131
Logger.fileProviderExtension.info(
@@ -146,22 +157,12 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
146157
}
147158

148159
Task { @MainActor in
149-
let newNcAccount =
150-
Account(user: user, id: userId, serverUrl: serverUrl, password: password)
151-
guard newNcAccount != ncAccount else { return }
152-
ncAccount = newNcAccount
153-
ncKit.setup(
154-
account: newNcAccount.ncKitAccount,
155-
user: newNcAccount.username,
156-
userId: newNcAccount.id,
157-
password: newNcAccount.password,
158-
urlBase: newNcAccount.serverUrl,
159-
userAgent: "Nextcloud-macOS/FileProviderExt",
160-
nextcloudVersion: 25,
161-
delegate: nil) // TODO: add delegate methods for self
162-
160+
ncAccount = account
163161
changeObserver = RemoteChangeObserver(
164-
remoteInterface: ncKit, changeNotificationInterface: self, domain: domain
162+
account: account,
163+
remoteInterface: ncKit,
164+
changeNotificationInterface: self,
165+
domain: domain
165166
)
166167
ncKit.setup(delegate: changeObserver)
167168
signalEnumeratorAfterAccountSetup()

shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+Thumbnailing.swift

+6
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,15 @@ extension FileProviderExtension: NSFileProviderThumbnailing {
2929
) -> Void,
3030
completionHandler: @escaping (Error?) -> Void
3131
) -> Progress {
32+
guard let ncAccount else {
33+
completionHandler(NSFileProviderError(.notAuthenticated))
34+
return Progress()
35+
}
36+
3237
return NextcloudFileProviderKit.fetchThumbnails(
3338
for: itemIdentifiers,
3439
requestedSize: size,
40+
account: ncAccount,
3541
usingRemoteInterface: self.ncKit,
3642
perThumbnailCompletionHandler: perThumbnailCompletionHandler,
3743
completionHandler: completionHandler

shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift

+22-9
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import OSLog
2020

2121
@objc class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension {
2222
let domain: NSFileProviderDomain
23-
let ncKit = NextcloudKit()
23+
let ncKit = NextcloudKit.shared
2424
let appGroupIdentifier = Bundle.main.object(forInfoDictionaryKey: "SocketApiPrefix") as? String
2525
var ncAccount: Account?
2626
var changeObserver: RemoteChangeObserver?
@@ -104,15 +104,20 @@ import OSLog
104104
request _: NSFileProviderRequest,
105105
completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void
106106
) -> Progress {
107-
if ncAccount == nil {
107+
guard let ncAccount else {
108108
Logger.fileProviderExtension.error(
109109
"""
110110
Not fetching item for identifier: \(identifier.rawValue, privacy: .public)
111111
as account not set up yet.
112112
"""
113113
)
114114
completionHandler(nil, NSFileProviderError(.notAuthenticated))
115-
} else if let item = Item.storedItem(identifier: identifier, remoteInterface: ncKit) {
115+
return Progress()
116+
}
117+
118+
if let item = Item.storedItem(
119+
identifier: identifier, account: ncAccount, remoteInterface: ncKit
120+
) {
116121
completionHandler(item, nil)
117122
} else {
118123
completionHandler(nil, NSFileProviderError(.noSuchItem))
@@ -147,7 +152,7 @@ import OSLog
147152
return Progress()
148153
}
149154

150-
guard ncAccount != nil else {
155+
guard let ncAccount else {
151156
Logger.fileProviderExtension.error(
152157
"""
153158
Not fetching contents for item: \(itemIdentifier.rawValue, privacy: .public)
@@ -159,7 +164,9 @@ import OSLog
159164
return Progress()
160165
}
161166

162-
guard let item = Item.storedItem(identifier: itemIdentifier, remoteInterface: ncKit) else {
167+
guard let item = Item.storedItem(
168+
identifier: itemIdentifier, account: ncAccount, remoteInterface: ncKit
169+
) else {
163170
Logger.fileProviderExtension.error(
164171
"""
165172
Not fetching contents for item: \(itemIdentifier.rawValue, privacy: .public)
@@ -228,6 +235,7 @@ import OSLog
228235
contents: url,
229236
request: request,
230237
domain: self.domain,
238+
account: ncAccount,
231239
remoteInterface: ncKit,
232240
progress: progress
233241
)
@@ -283,7 +291,9 @@ import OSLog
283291
return Progress()
284292
}
285293

286-
guard let existingItem = Item.storedItem(identifier: identifier, remoteInterface: ncKit) else {
294+
guard let existingItem = Item.storedItem(
295+
identifier: identifier, account: ncAccount, remoteInterface: ncKit
296+
) else {
287297
Logger.fileProviderExtension.error(
288298
"Not modifying item: \(ocId, privacy: .public) as item not found."
289299
)
@@ -331,7 +341,7 @@ import OSLog
331341
"Received delete request for item: \(identifier.rawValue, privacy: .public)"
332342
)
333343

334-
guard ncAccount != nil else {
344+
guard let ncAccount else {
335345
Logger.fileProviderExtension.error(
336346
"Not deleting item \(identifier.rawValue, privacy: .public), account not set up yet"
337347
)
@@ -340,7 +350,9 @@ import OSLog
340350
return Progress()
341351
}
342352

343-
guard let item = Item.storedItem(identifier: identifier, remoteInterface: ncKit) else {
353+
guard let item = Item.storedItem(
354+
identifier: identifier, account: ncAccount, remoteInterface: ncKit
355+
) else {
344356
Logger.fileProviderExtension.error(
345357
"Not deleting item \(identifier.rawValue, privacy: .public), item not found"
346358
)
@@ -359,7 +371,7 @@ import OSLog
359371
removeSyncAction(actionId)
360372
}
361373
progress.completedUnitCount = 1
362-
completionHandler(await item.delete())
374+
completionHandler(error)
363375
}
364376
return progress
365377
}
@@ -376,6 +388,7 @@ import OSLog
376388

377389
return Enumerator(
378390
enumeratedItemIdentifier: containerItemIdentifier,
391+
account: ncAccount,
379392
remoteInterface: ncKit,
380393
domain: domain,
381394
fastEnumeration: config.fastEnumerationEnabled,

shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift

+11-6
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,20 @@ class LockViewController: NSViewController {
157157
return
158158
}
159159
let serverPathString = serverPath as String
160-
let kit = NextcloudKit()
161-
kit.setup(
160+
let kit = NextcloudKit.shared
161+
kit.appendSession(
162+
account: account.ncKitAccount,
163+
urlBase: account.serverUrl,
162164
user: account.username,
163-
userId: account.username,
165+
userId: account.id,
164166
password: account.password,
165-
urlBase: account.serverUrl
167+
userAgent: "Nextcloud-macOS/FileProviderUIExt",
168+
nextcloudVersion: 25,
169+
groupIdentifier: ""
166170
)
167171
// guard let capabilities = await fetchCapabilities() else {
168172
guard let itemMetadata = await fetchItemMetadata(
169-
itemRelativePath: serverPathString, kit: kit
173+
itemRelativePath: serverPathString, account: account, kit: kit
170174
) else {
171175
presentError("Could not get item metadata.")
172176
return
@@ -200,7 +204,8 @@ class LockViewController: NSViewController {
200204
kit.lockUnlockFile(
201205
serverUrlFileName: serverUrlFileName,
202206
shouldLock: locking,
203-
completion: { _, error in
207+
account: account.ncKitAccount,
208+
completion: { _, _, error in
204209
continuation.resume(returning: error)
205210
}
206211
)

shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/MetadataProvider.swift

+16-7
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
//
77

88
import Foundation
9+
import NextcloudFileProviderKit
910
import NextcloudKit
1011
import OSLog
1112

12-
func fetchItemMetadata(itemRelativePath: String, kit: NextcloudKit) async -> NKFile? {
13+
func fetchItemMetadata(
14+
itemRelativePath: String, account: Account, kit: NextcloudKit
15+
) async -> NKFile? {
1316
func slashlessPath(_ string: String) -> String {
1417
var strCopy = string
1518
if strCopy.hasPrefix("/") {
@@ -21,15 +24,21 @@ func fetchItemMetadata(itemRelativePath: String, kit: NextcloudKit) async -> NKF
2124
return strCopy
2225
}
2326

24-
let nkCommon = kit.nkCommonInstance
25-
let urlBase = slashlessPath(nkCommon.urlBase)
26-
let davSuffix = slashlessPath(nkCommon.dav)
27-
let userId = nkCommon.userId
27+
guard let nksession = kit.getSession(account: account.ncKitAccount) else {
28+
Logger.metadataProvider.error("Could not get nksession for \(account.ncKitAccount)")
29+
return nil
30+
}
31+
32+
let urlBase = slashlessPath(nksession.urlBase)
33+
let davSuffix = slashlessPath(nksession.dav)
34+
let userId = nksession.userId
2835
let itemRelPath = slashlessPath(itemRelativePath)
2936

3037
let itemFullServerPath = "\(urlBase)/\(davSuffix)/files/\(userId)/\(itemRelPath)"
3138
return await withCheckedContinuation { continuation in
32-
kit.readFileOrFolder(serverUrlFileName: itemFullServerPath, depth: "0") {
39+
kit.readFileOrFolder(
40+
serverUrlFileName: itemFullServerPath, depth: "0", account: account.ncKitAccount
41+
) {
3342
account, files, data, error in
3443
guard error == .success else {
3544
Logger.metadataProvider.error(
@@ -39,7 +48,7 @@ func fetchItemMetadata(itemRelativePath: String, kit: NextcloudKit) async -> NKF
3948
return
4049
}
4150
Logger.metadataProvider.info("Successfully retrieved item metadata")
42-
continuation.resume(returning: files.first)
51+
continuation.resume(returning: files?.first)
4352
}
4453
}
4554
}

shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareController.swift

+12-4
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77

88
import Combine
99
import Foundation
10+
import NextcloudFileProviderKit
1011
import NextcloudKit
1112
import OSLog
1213

1314
class ShareController: ObservableObject {
1415
@Published private(set) var share: NKShare
1516
private let kit: NextcloudKit
17+
private let account: Account
1618

1719
static func create(
20+
account: Account,
1821
kit: NextcloudKit,
1922
shareType: NKShare.ShareType,
2023
itemServerRelativePath: String,
@@ -38,6 +41,7 @@ class ShareController: ObservableObject {
3841
publicUpload: publicUpload,
3942
password: password,
4043
permissions: permissions,
44+
account: account.ncKitAccount,
4145
options: options
4246
) { account, share, data, error in
4347
defer { continuation.resume(returning: error) }
@@ -65,8 +69,8 @@ class ShareController: ObservableObject {
6569
shareWith: shareWith,
6670
password: password,
6771
permissions: permissions,
68-
options: options,
69-
attributes: attributes
72+
attributes: attributes,
73+
account: account.ncKitAccount
7074
) { account, share, data, error in
7175
defer { continuation.resume(returning: error) }
7276
guard error == .success else {
@@ -82,7 +86,8 @@ class ShareController: ObservableObject {
8286
}
8387
}
8488

85-
init(share: NKShare, kit: NextcloudKit) {
89+
init(share: NKShare, account: Account, kit: NextcloudKit) {
90+
self.account = account
8691
self.share = share
8792
self.kit = kit
8893
}
@@ -110,6 +115,7 @@ class ShareController: ObservableObject {
110115
label: label,
111116
hideDownload: hideDownload,
112117
attributes: attributes,
118+
account: account.ncKitAccount,
113119
options: options
114120
) { account, share, data, error in
115121
Logger.shareController.info(
@@ -134,7 +140,9 @@ class ShareController: ObservableObject {
134140
func delete() async -> NKError? {
135141
Logger.shareController.info("Deleting share: \(self.share.url, privacy: .public)")
136142
return await withCheckedContinuation { continuation in
137-
kit.deleteShare(idShare: share.idShare) { account, error in
143+
kit.deleteShare(
144+
idShare: share.idShare, account: account.ncKitAccount
145+
) { account, _, error in
138146
Logger.shareController.info(
139147
"""
140148
Received delete response: \(self.share.url, privacy: .public)

shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareOptionsView.swift

+10-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import AppKit
99
import Combine
10+
import NextcloudFileProviderKit
1011
import NextcloudKit
1112
import OSLog
1213
import SuggestionsTextFieldKit
@@ -34,16 +35,17 @@ class ShareOptionsView: NSView {
3435
@IBOutlet private weak var circleShare: NSMenuItem!
3536
@IBOutlet private weak var talkConversationShare: NSMenuItem!
3637

37-
var kit: NextcloudKit? {
38+
let kit = NextcloudKit.shared
39+
var account: Account? {
3840
didSet {
39-
Logger.shareOptionsView.info("Setting up the kit.")
40-
guard let kit = kit else {
41+
Logger.shareOptionsView.info("Setting up account.")
42+
guard let account else {
4143
Logger.shareOptionsView.error("Could not configure suggestions data source.")
4244
return
4345
}
4446

4547
suggestionsTextFieldDelegate.suggestionsDataSource = ShareeSuggestionsDataSource(
46-
kit: kit
48+
account: account, kit: kit
4749
)
4850
suggestionsTextFieldDelegate.confirmationHandler = { suggestion in
4951
guard let sharee = suggestion?.data as? NKSharee else { return }
@@ -255,13 +257,13 @@ class ShareOptionsView: NSView {
255257
guard !createMode else {
256258
Logger.shareOptionsView.info("Creating new share!")
257259

258-
guard let dataSource = dataSource,
259-
let kit = kit,
260+
guard let dataSource,
261+
let account,
260262
let itemServerRelativePath = dataSource.itemServerRelativePath
261263
else {
262264
Logger.shareOptionsView.error("Cannot create new share due to missing data.")
263265
Logger.shareOptionsView.error("dataSource: \(self.dataSource, privacy: .public)")
264-
Logger.shareOptionsView.error("kit: \(self.kit, privacy: .public)")
266+
Logger.shareOptionsView.error("account: \(self.account != nil, privacy: .public)")
265267
Logger.shareOptionsView.error(
266268
"path: \(self.dataSource?.itemServerRelativePath ?? "", privacy: .public)"
267269
)
@@ -280,6 +282,7 @@ class ShareOptionsView: NSView {
280282
deleteButton.isEnabled = false
281283
saveButton.isEnabled = false
282284
let error = await ShareController.create(
285+
account: account,
283286
kit: kit,
284287
shareType: selectedShareType,
285288
itemServerRelativePath: itemServerRelativePath,

0 commit comments

Comments
 (0)