class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension {
let domain: NSFileProviderDomain
- let socketClient: LocalSocketClient
-
+ var socketClient: LocalSocketClient = LocalSocketClient()
+
required init(domain: NSFileProviderDomain) {
self.domain = domain
// The containing application must create a domain using `NSFileProviderManager.add(_:, completionHandler:)`. The system will then launch the application extension process, call `FileProviderExtension.init(domain:)` to instantiate the extension for that domain, and call methods on the instance.
- let bundle = Bundle(for: type(of: self))
- guard let fileProviderSocketApiPrefix = bundle.object(forInfoDictionaryKey: "SocketApiPrefix") as? String else {
- NSLog("Could not start file provider socket client properly as SocketApiPrefix is missing")
- self.socketClient = LocalSocketClient()
- super.init()
- return;
- }
-
- let containerUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: fileProviderSocketApiPrefix)
- let socketPath = containerUrl?.appendingPathComponent(".fileprovidersocket", conformingTo: .archive)
- self.socketClient = LocalSocketClient(socketPath: socketPath?.path, lineProcessor: nil)
- self.socketClient.start();
super.init()
+ startLocalSocketClient()
}
func invalidate() {
// TODO: cleanup any resources
}
+
+ // MARK: NSFileProviderReplicatedExtension protocol methods
func item(for identifier: NSFileProviderItemIdentifier, request: NSFileProviderRequest, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) -> Progress {
// resolve the given identifier to a record in the model
func enumerator(for containerItemIdentifier: NSFileProviderItemIdentifier, request: NSFileProviderRequest) throws -> NSFileProviderEnumerator {
return FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier)
}
+
+ // MARK: Nextcloud desktop client communication
+
+ func startLocalSocketClient() {
+ let bundle = Bundle(for: type(of: self))
+ guard let fileProviderSocketApiPrefix = bundle.object(forInfoDictionaryKey: "SocketApiPrefix") as? String else {
+ NSLog("Could not start file provider socket client properly as SocketApiPrefix is missing")
+
+ return;
+ }
+
+ let containerUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: fileProviderSocketApiPrefix)
+ let socketPath = containerUrl?.appendingPathComponent(".fileprovidersocket", conformingTo: .archive)
+ let lineProcessor = FileProviderSocketLineProcessor(delegate: self)
+
+ self.socketClient = LocalSocketClient(socketPath: socketPath?.path, lineProcessor: lineProcessor)
+ self.socketClient.start();
+ }
+
+ func sendDelegateFileProviderDomainIdentifier() {
+ let command = "FILE_PROVIDER_DOMAIN_IDENTIFIER_REQUEST_REPLY"
+ let argument = domain.identifier.rawValue
+ let message = command + ":" + argument + "\n"
+ socketClient.sendMessage(message)
+ }
}
--- /dev/null
+/*
+ * Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+import Foundation
+import NCDesktopClientSocketKit
+
+class FileProviderSocketLineProcessor: NSObject, LineProcessor {
+ var delegate: FileProviderExtension
+
+ init(delegate: FileProviderExtension) {
+ self.delegate = delegate
+ }
+
+ func process(_ line: String) {
+ NSLog("Processing file provider line: %@", line)
+
+ let splitLine = line.split(separator: ":")
+ guard let commandSubsequence = splitLine.first else {
+ NSLog("Input line did not have a first element")
+ return;
+ }
+ let command = String(commandSubsequence);
+
+ NSLog("Received command: %@", command)
+ if (command == "SEND_FILE_PROVIDER_DOMAIN_IDENTIFIER") {
+ delegate.sendDelegateFileProviderDomainIdentifier()
+ }
+ }
+}
objects = {
/* Begin PBXBuildFile section */
+ 536EFBF7295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536EFBF6295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift */; };
538E396A27F4765000FA63D5 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */; };
538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */; };
538E396F27F4765000FA63D5 /* FileProviderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538E396E27F4765000FA63D5 /* FileProviderItem.swift */; };
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 536EFBF6295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderSocketLineProcessor.swift; sourceTree = "<group>"; };
538E396727F4765000FA63D5 /* FileProviderExt.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FileProviderExt.appex; sourceTree = BUILT_PRODUCTS_DIR; };
538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; };
538E396C27F4765000FA63D5 /* FileProviderExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderExtension.swift; sourceTree = "<group>"; };
538E396C27F4765000FA63D5 /* FileProviderExtension.swift */,
538E396E27F4765000FA63D5 /* FileProviderItem.swift */,
538E397027F4765000FA63D5 /* FileProviderEnumerator.swift */,
+ 536EFBF6295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift */,
538E397227F4765000FA63D5 /* Info.plist */,
538E397327F4765000FA63D5 /* FileProviderExt.entitlements */,
);
buildActionMask = 2147483647;
files = (
538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */,
+ 536EFBF7295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift in Sources */,
538E396F27F4765000FA63D5 /* FileProviderItem.swift in Sources */,
538E397127F4765000FA63D5 /* FileProviderEnumerator.swift in Sources */,
);