From f0b4925db2f0f7bd6fa3b182d599458b3ea9054e Mon Sep 17 00:00:00 2001 From: Amir Abbas Date: Sun, 20 Aug 2017 22:41:53 +0430 Subject: [PATCH] Consistancy to delegate call in all contents(of:) methods - renamed opType instances to operation - moved to v2 in Dropbox - removed redundant CloudFileProvider methods --- Sources/CloudFileProvider.swift | 89 ++++----------------- Sources/DropboxFileProvider.swift | 21 ++--- Sources/DropboxHelper.swift | 4 + Sources/FTPFileProvider.swift | 124 ++++++++++++++--------------- Sources/FTPHelper.swift | 10 --- Sources/FileProvider.swift | 15 +++- Sources/HTTPFileProvider.swift | 20 ++--- Sources/LocalFileProvider.swift | 117 ++++++++++++++------------- Sources/OneDriveFileProvider.swift | 16 ++-- Sources/WebDAVFileProvider.swift | 4 +- 10 files changed, 186 insertions(+), 234 deletions(-) diff --git a/Sources/CloudFileProvider.swift b/Sources/CloudFileProvider.swift index f8dd61d..6f0506f 100644 --- a/Sources/CloudFileProvider.swift +++ b/Sources/CloudFileProvider.swift @@ -379,55 +379,6 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { } } - /** - Creates a new directory at the specified path asynchronously. - This will create any necessary intermediate directories. - - - Parameters: - - folder: Directory name. - - at: Parent path of new directory. - - completionHandler: If an error parameter was provided, a presentable `Error` will be returned. - - Returns: A `Progress` object to get progress or cancel progress. Doesn't work on `CloudFileProvider`. - */ - @discardableResult - open override func create(folder folderName: String, at atPath: String, completionHandler: SimpleCompletionHandler) -> Progress? { - return super.create(folder: folderName, at: atPath, completionHandler: completionHandler) - } - - /** - Moves a file or directory from `path` to designated path asynchronously. - When you want move a file, destination path should also consists of file name. - Either a new name or the old one. - - - Parameters: - - path: original file or directory path. - - to: destination path of file or directory, including file/directory name. - - overwrite: Destination file should be overwritten if file is already exists. **Default** is `false`. - - completionHandler: If an error parameter was provided, a presentable `Error` will be returned. - - Returns: A `Progress` object to get progress or cancel progress. Doesn't work on `CloudFileProvider`. - */ - @discardableResult - open override func moveItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> Progress? { - return super.moveItem(path: path, to: toPath, overwrite: overwrite, completionHandler: completionHandler) - } - - /** - Copies a file or directory from `path` to designated path asynchronously. - When want copy a file, destination path should also consists of file name. - Either a new name or the old one. - - - Parameters: - - path: original file or directory path. - - to: destination path of file or directory, including file/directory name. - - overwrite: Destination file should be overwritten if file is already exists. **Default** is `false`. - - completionHandler: If an error parameter was provided, a presentable `Error` will be returned. - - Returns: A `Progress` object to get progress or cancel progress. Doesn't work on `CloudFileProvider`. - */ - @discardableResult - open override func copyItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> Progress? { - return super.copyItem(path: path, to: toPath, overwrite: overwrite, completionHandler: completionHandler) - } - /** Removes the file or directory at the specified path. @@ -459,14 +410,14 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { @discardableResult open override func copyItem(localFile: URL, to toPath: String, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> Progress? { // TODO: Make use of overwrite parameter - let opType = FileOperationType.copy(source: localFile.absoluteString, destination: toPath) + let operation = FileOperationType.copy(source: localFile.absoluteString, destination: toPath) let progress = Progress(parent: nil, userInfo: nil) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.isCancellable = false progress.setUserInfoObject(localFile, forKey: .fileURLKey) progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) - monitorFile(path: toPath, opType: opType, progress: progress) + monitorFile(path: toPath, operation: operation, progress: progress) operation_queue.addOperation { let tempFolder: URL if #available(iOS 10.0, macOS 10.12, tvOS 10.0, *) { @@ -481,17 +432,13 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { let toUrl = self.url(of: toPath) try self.opFileManager.setUbiquitous(true, itemAt: tmpFile, destinationURL: toUrl) completionHandler?(nil) - DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) - }) + self.delegateNotify(operation, error: nil) } catch let e { if self.opFileManager.fileExists(atPath: tmpFile.path) { try? self.opFileManager.removeItem(at: tmpFile) } completionHandler?(e) - DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) - }) + self.delegateNotify(operation, error: e) } } return progress @@ -509,21 +456,19 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { */ @discardableResult open override func copyItem(path: String, toLocalURL: URL, completionHandler: SimpleCompletionHandler) -> Progress? { - let opType = FileOperationType.copy(source: path, destination: toLocalURL.absoluteString) + let operation = FileOperationType.copy(source: path, destination: toLocalURL.absoluteString) let progress = Progress(parent: nil, userInfo: nil) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.isCancellable = false progress.setUserInfoObject(self.url(of: path), forKey: .fileURLKey) progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) - monitorFile(path: path, opType: opType, progress: progress) + monitorFile(path: path, operation: operation, progress: progress) do { try self.opFileManager.startDownloadingUbiquitousItem(at: self.url(of: path)) } catch let e { completionHandler?(e) - DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) - }) + self.delegateNotify(operation, error: e) return nil } let _ = super.copyItem(path: path, toLocalURL: toLocalURL, completionHandler: completionHandler) @@ -549,7 +494,7 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { progress.kind = .file progress.setUserInfoObject(self.url(of: path), forKey: .fileURLKey) progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) - monitorFile(path: path, opType: operation, progress: progress) + monitorFile(path: path, operation: operation, progress: progress) _ = super.contents(path: path, completionHandler: completionHandler) return progress } @@ -575,7 +520,7 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { progress.kind = .file progress.setUserInfoObject(self.url(of: path), forKey: .fileURLKey) progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) - monitorFile(path: path, opType: operation, progress: progress) + monitorFile(path: path, operation: operation, progress: progress) _ = super.contents(path: path, offset: offset, length: length, completionHandler: completionHandler) return progress } @@ -599,7 +544,7 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { progress.kind = .file progress.setUserInfoObject(self.url(of: path), forKey: .fileURLKey) progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) - monitorFile(path: path, opType: operation, progress: progress) + monitorFile(path: path, operation: operation, progress: progress) _ = super.writeContents(path: path, contents: data, atomically: atomically, overwrite: overwrite, completionHandler: completionHandler) return progress } @@ -686,7 +631,7 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { return file } - fileprivate func monitorFile(path: String, opType: FileOperationType, progress: Progress?) { + fileprivate func monitorFile(path: String, operation: FileOperationType, progress: Progress?) { dispatch_queue.async { let pathURL = self.url(of: path) let size = pathURL.fileSize @@ -711,20 +656,18 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { if (downloaded == 0 || downloaded == 100) && (uploaded > 0 && uploaded < 100) { progress?.completedUnitCount = Int64(uploaded / 100 * Double(progress?.totalUnitCount ?? 0)) DispatchQueue.main.async { - self.delegate?.fileproviderProgress(self, operation: opType, progress: Float(uploaded / 100)) + self.delegate?.fileproviderProgress(self, operation: operation, progress: Float(uploaded / 100)) } } else if (uploaded == 0 || uploaded == 100) && (downloaded > 0 && downloaded < 100) { progress?.completedUnitCount = Int64(downloaded / 100 * Double(progress?.totalUnitCount ?? 0)) DispatchQueue.main.async { - self.delegate?.fileproviderProgress(self, operation: opType, progress: Float(downloaded / 100)) + self.delegate?.fileproviderProgress(self, operation: operation, progress: Float(downloaded / 100)) } } else if uploaded == 100 || downloaded == 100 { progress?.completedUnitCount = progress?.totalUnitCount ?? 0 query.stop() NotificationCenter.default.removeObserver(updateObserver!) - DispatchQueue.main.async { - self.delegate?.fileproviderSucceed(self, operation: opType) - } + self.delegateNotify(operation, error: nil) } query.enableUpdates() diff --git a/Sources/DropboxFileProvider.swift b/Sources/DropboxFileProvider.swift index 41db13a..d91ea80 100644 --- a/Sources/DropboxFileProvider.swift +++ b/Sources/DropboxFileProvider.swift @@ -133,7 +133,7 @@ open class DropboxFileProvider: HTTPFileProvider, FileProviderSharing { return progress } - override func request(for operation: FileOperationType, overwrite: Bool, attributes: [URLResourceKey : Any]) -> URLRequest { + override func request(for operation: FileOperationType, overwrite: Bool = false, attributes: [URLResourceKey : Any] = [:]) -> URLRequest { // content operations var request: URLRequest switch operation { @@ -169,25 +169,29 @@ open class DropboxFileProvider: HTTPFileProvider, FileProviderSharing { request.set(httpAuthentication: credential, with: .oAuth2) request.set(contentType: .stream) request.set(dropboxArgKey: requestDictionary) - default: // modify, link, fetch - return self.apiRequest(for: operation) + default: + return self.apiRequest(for: operation, overwrite: overwrite) } return request } - func apiRequest(for operation: FileOperationType) -> URLRequest { + func apiRequest(for operation: FileOperationType, overwrite: Bool = false) -> URLRequest { let url: String let sourcePath = operation.source let destPath = operation.destination + var requestDictionary = [String: AnyObject]() switch operation { case .create: - url = "files/create_folder" + url = "files/create_folder_v2" + case .copy: - url = "files/copy" + url = "files/copy_v2" + requestDictionary["allow_shared_folder"] = NSNumber(value: true) case .move: - url = "files/move" + url = "files/move_v2" + requestDictionary["allow_shared_folder"] = NSNumber(value: true) case .remove: - url = "files/delete" + url = "files/delete_v2" default: // modify, link, fetch fatalError("Unimplemented operation \(operation.description) in \(#file)") } @@ -195,7 +199,6 @@ open class DropboxFileProvider: HTTPFileProvider, FileProviderSharing { request.httpMethod = "POST" request.set(httpAuthentication: credential, with: .oAuth2) request.set(contentType: .json) - var requestDictionary = [String: AnyObject]() if let dest = correctPath(destPath) as NSString? { requestDictionary["from_path"] = correctPath(sourcePath) as NSString? requestDictionary["to_path"] = dest diff --git a/Sources/DropboxHelper.swift b/Sources/DropboxHelper.swift index 394a7bd..6ef812f 100644 --- a/Sources/DropboxHelper.swift +++ b/Sources/DropboxHelper.swift @@ -23,6 +23,10 @@ public final class DropboxFileObject: FileObject { } internal init? (json: [String: AnyObject]) { + var json = json + if json["name"] == nil, let metadata = json["metadata"] as? [String: AnyObject] { + json = metadata + } guard let name = json["name"] as? String else { return nil } guard let path = json["path_display"] as? String else { return nil } super.init(url: nil, name: name, path: path) diff --git a/Sources/FTPFileProvider.swift b/Sources/FTPFileProvider.swift index 6ad87d7..3672089 100644 --- a/Sources/FTPFileProvider.swift +++ b/Sources/FTPFileProvider.swift @@ -374,13 +374,13 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil return nil } - let opType = FileOperationType.copy(source: localFile.absoluteString, destination: toPath) - guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else { + let operation = FileOperationType.copy(source: localFile.absoluteString, destination: toPath) + guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: operation) ?? true == true else { return nil } let progress = Progress(totalUnitCount: 0) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) @@ -389,7 +389,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil if let error = error { self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -403,7 +403,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil }, onProgress: { bytesSent, totalSent, expectedBytes in progress.completedUnitCount = totalSent DispatchQueue.main.async { - self.delegate?.fileproviderProgress(self, operation: opType, progress: Float(progress.fractionCompleted)) + self.delegate?.fileproviderProgress(self, operation: operation, progress: Float(progress.fractionCompleted)) } }, completionHandler: { (error) in if error != nil { @@ -412,7 +412,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil self.ftpQuit(task) self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } }) } @@ -421,12 +421,12 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil } open func copyItem(path: String, toLocalURL destURL: URL, completionHandler: SimpleCompletionHandler) -> Progress? { - let opType = FileOperationType.copy(source: path, destination: destURL.absoluteString) - guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else { + let operation = FileOperationType.copy(source: path, destination: destURL.absoluteString) + guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: operation) ?? true == true else { return nil } var progress = Progress(totalUnitCount: 0) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) @@ -435,7 +435,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil if let error = error { self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -444,7 +444,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil self.dispatch_queue.async { let error = self.throwError(path, code: URLError.fileIsDirectory) completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -461,7 +461,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil completionHandler?(e) } } - task.taskDescription = opType.json + task.taskDescription = operation.json task.addObserver(self.sessionDelegate!, forKeyPath: #keyPath(URLSessionTask.countOfBytesReceived), options: .new, context: &progress) task.addObserver(self.sessionDelegate!, forKeyPath: #keyPath(URLSessionTask.countOfBytesExpectedToReceive), options: .new, context: &progress) progress.cancellationHandler = { [weak task] in @@ -490,14 +490,14 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil progress.totalUnitCount = totalSize progress.completedUnitCount = totalReceived DispatchQueue.main.async { - self.delegate?.fileproviderProgress(self, operation: opType, progress: Float(progress.fractionCompleted)) + self.delegate?.fileproviderProgress(self, operation: operation, progress: Float(progress.fractionCompleted)) } }) { (tmpurl, error) in if let error = error { progress.cancel() self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -506,7 +506,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil try? FileManager.default.moveItem(at: tmpurl, to: destURL) self.dispatch_queue.async { completionHandler?(nil) - self.delegateNotify(opType, error: nil) + self.delegateNotify(operation, error: nil) } } } @@ -516,14 +516,14 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil } open func contents(path: String, completionHandler: @escaping ((Data?, Error?) -> Void)) -> Progress? { - let opType = FileOperationType.fetch(path: path) - guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else { + let operation = FileOperationType.fetch(path: path) + guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: operation) ?? true == true else { return nil } if self.useAppleImplementation { var progress = Progress(totalUnitCount: 0) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) @@ -542,7 +542,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil completionHandler(nil, e) } } - task.taskDescription = opType.json + task.taskDescription = operation.json task.addObserver(sessionDelegate!, forKeyPath: #keyPath(URLSessionTask.countOfBytesReceived), options: .new, context: &progress) task.addObserver(sessionDelegate!, forKeyPath: #keyPath(URLSessionTask.countOfBytesExpectedToReceive), options: .new, context: &progress) progress.cancellationHandler = { [weak task] in @@ -557,16 +557,16 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil } open func contents(path: String, offset: Int64, length: Int, completionHandler: @escaping ((_ contents: Data?, _ error: Error?) -> Void)) -> Progress? { - let opType = FileOperationType.fetch(path: path) + let operation = FileOperationType.fetch(path: path) if length == 0 || offset < 0 { dispatch_queue.async { completionHandler(Data(), nil) - self.delegateNotify(opType, error: nil) + self.delegateNotify(operation, error: nil) } return nil } let progress = Progress(totalUnitCount: 0) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) @@ -589,14 +589,14 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil progress.totalUnitCount = totalSize progress.completedUnitCount = totalReceived DispatchQueue.main.async { - self.delegate?.fileproviderProgress(self, operation: opType, progress: Float(progress.fractionCompleted)) + self.delegate?.fileproviderProgress(self, operation: operation, progress: Float(progress.fractionCompleted)) } }) { (data, error) in if let error = error { progress.cancel() self.dispatch_queue.async { completionHandler(nil, error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -604,7 +604,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil if let data = data { self.dispatch_queue.async { completionHandler(data, nil) - self.delegateNotify(opType, error: nil) + self.delegateNotify(operation, error: nil) } } } @@ -614,13 +614,13 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil } open func writeContents(path: String, contents data: Data?, atomically: Bool, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> Progress? { - let opType = FileOperationType.modify(path: path) - guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else { + let operation = FileOperationType.modify(path: path) + guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: operation) ?? true == true else { return nil } let progress = Progress(totalUnitCount: Int64(data?.count ?? 0)) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) @@ -629,7 +629,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil if let error = error { self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -644,7 +644,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil }, onProgress: { bytesSent, totalSent, expectedBytes in progress.completedUnitCount = totalSent DispatchQueue.main.async { - self.delegate?.fileproviderProgress(self, operation: opType, progress: Float(progress.fractionCompleted)) + self.delegate?.fileproviderProgress(self, operation: operation, progress: Float(progress.fractionCompleted)) } }, completionHandler: { (error) in if error != nil { @@ -653,7 +653,7 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil self.ftpQuit(task) self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } }) } @@ -686,21 +686,21 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil - completionHandler: If an error parameter was provided, a presentable `Error` will be returned. */ open func create(symbolicLink path: String, withDestinationPath destPath: String, completionHandler: SimpleCompletionHandler) { - let opType = FileOperationType.link(link: path, target: destPath) - _=self.doOperation(opType, completionHandler: completionHandler) + let operation = FileOperationType.link(link: path, target: destPath) + _=self.doOperation(operation, completionHandler: completionHandler) } } extension FTPFileProvider { - fileprivate func doOperation(_ opType: FileOperationType, completionHandler: SimpleCompletionHandler) -> Progress? { - guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else { + fileprivate func doOperation(_ operation: FileOperationType, completionHandler: SimpleCompletionHandler) -> Progress? { + guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: operation) ?? true == true else { return nil } - let sourcePath = opType.source - let destPath = opType.destination + let sourcePath = operation.source + let destPath = operation.destination let command: String - switch opType { + switch operation { case .create: command = "MKD \(ftpPath(sourcePath))" case .copy: @@ -715,7 +715,7 @@ extension FTPFileProvider { return nil } let progress = Progress(totalUnitCount: 1) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.setUserInfoObject(Progress.FileOperationKind.downloading, forKey: .fileOperationKindKey) @@ -724,7 +724,7 @@ extension FTPFileProvider { if let error = error { self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -733,7 +733,7 @@ extension FTPFileProvider { if let error = error { self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -741,7 +741,7 @@ extension FTPFileProvider { guard let response = response else { self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: self.throwError(sourcePath, code: URLError.badServerResponse)) + self.delegateNotify(operation, error: self.throwError(sourcePath, code: URLError.badServerResponse)) } return } @@ -754,18 +754,18 @@ extension FTPFileProvider { if codes.filter({ (450..<560).contains($0) }).count > 0 { let errorCode: URLError.Code - switch opType { + switch operation { case .create: errorCode = URLError.cannotCreateFile case .modify: errorCode = URLError.cannotWriteToFile case .copy: - self.fallbackCopy(opType, progress: progress, completionHandler: completionHandler) + self.fallbackCopy(operation, progress: progress, completionHandler: completionHandler) return case .move: errorCode = URLError.cannotMoveFile case .remove: - self.fallbackRemove(opType, progress: progress, on: task, completionHandler: completionHandler) + self.fallbackRemove(operation, progress: progress, on: task, completionHandler: completionHandler) return case .link: errorCode = URLError.cannotWriteToFile @@ -777,7 +777,7 @@ extension FTPFileProvider { self.dispatch_queue.async { completionHandler?(error) } - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) return } @@ -785,7 +785,7 @@ extension FTPFileProvider { self.dispatch_queue.async { completionHandler?(nil) } - self.delegateNotify(opType, error: nil) + self.delegateNotify(operation, error: nil) }) } @@ -796,9 +796,9 @@ extension FTPFileProvider { return progress } - private func fallbackCopy(_ opType: FileOperationType, progress: Progress, completionHandler: SimpleCompletionHandler) { - let sourcePath = opType.source - guard let destPath = opType.destination else { return } + private func fallbackCopy(_ operation: FileOperationType, progress: Progress, completionHandler: SimpleCompletionHandler) { + let sourcePath = operation.source + guard let destPath = operation.destination else { return } let localURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString).appendingPathExtension("tmp") @@ -807,7 +807,7 @@ extension FTPFileProvider { if let error = error { self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -815,7 +815,7 @@ extension FTPFileProvider { progress.becomeCurrent(withPendingUnitCount: 1) _ = self.copyItem(localFile: localURL, to: destPath) { error in completionHandler?(nil) - self.delegateNotify(opType, error: nil) + self.delegateNotify(operation, error: nil) } progress.resignCurrent() } @@ -823,8 +823,8 @@ extension FTPFileProvider { return } - private func fallbackRemove(_ opType: FileOperationType, progress: Progress, on task: FileProviderStreamTask, completionHandler: SimpleCompletionHandler) { - let sourcePath = opType.source + private func fallbackRemove(_ operation: FileOperationType, progress: Progress, on task: FileProviderStreamTask, completionHandler: SimpleCompletionHandler) { + let sourcePath = operation.source self.execute(command: "SITE RMDIR \(ftpPath(sourcePath))", on: task) { (response, error) in if let error = error { @@ -832,7 +832,7 @@ extension FTPFileProvider { self.dispatch_queue.async { completionHandler?(error) } - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) return } @@ -842,12 +842,12 @@ extension FTPFileProvider { self.dispatch_queue.async { completionHandler?(error) } - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) return } if response.hasPrefix("50") { - self.fallbackRecursiveRemove(opType, progress: progress, on: task, completionHandler: completionHandler) + self.fallbackRecursiveRemove(operation, progress: progress, on: task, completionHandler: completionHandler) return } @@ -858,18 +858,18 @@ extension FTPFileProvider { self.dispatch_queue.async { completionHandler?(error) } - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } } - private func fallbackRecursiveRemove(_ opType: FileOperationType, progress: Progress, on task: FileProviderStreamTask, completionHandler: SimpleCompletionHandler) { - let sourcePath = opType.source + private func fallbackRecursiveRemove(_ operation: FileOperationType, progress: Progress, on task: FileProviderStreamTask, completionHandler: SimpleCompletionHandler) { + let sourcePath = operation.source _ = self.recursiveList(path: sourcePath, useMLST: true, completionHandler: { (contents, error) in if let error = error { self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } return } @@ -889,7 +889,7 @@ extension FTPFileProvider { recursiveProgress.completedUnitCount += 1 self.dispatch_queue.async { completionHandler?(error) - self.delegateNotify(opType, error: error) + self.delegateNotify(operation, error: error) } // TODO: Digest response }) diff --git a/Sources/FTPHelper.swift b/Sources/FTPHelper.swift index 7dad79e..2582902 100644 --- a/Sources/FTPHelper.swift +++ b/Sources/FTPHelper.swift @@ -9,16 +9,6 @@ import Foundation internal extension FTPFileProvider { - func delegateNotify(_ operation: FileOperationType, error: Error?) { - DispatchQueue.main.async(execute: { - if error == nil { - self.delegate?.fileproviderSucceed(self, operation: operation) - } else { - self.delegate?.fileproviderFailed(self, operation: operation) - } - }) - } - func readDataUntilEOF(of task: FileProviderStreamTask, minLength: Int, receivedData: Data? = nil, timeout: TimeInterval, completionHandler: @escaping (_ data: Data?, _ errror:Error?) -> Void) { task.readData(ofMinLength: minLength, maxLength: 65535, timeout: timeout) { (data, eof, error) in if let error = error { diff --git a/Sources/FileProvider.swift b/Sources/FileProvider.swift index 6b67432..c2acbf4 100644 --- a/Sources/FileProvider.swift +++ b/Sources/FileProvider.swift @@ -418,6 +418,18 @@ public extension FileProviderOperations { } } +internal extension FileProviderOperations { + internal func delegateNotify(_ operation: FileOperationType, error: Error?) { + DispatchQueue.main.async(execute: { + if error == nil { + self.delegate?.fileproviderSucceed(self, operation: operation) + } else { + self.delegate?.fileproviderFailed(self, operation: operation) + } + }) + } +} + /// Defines method for fetching and modifying file contents public protocol FileProviderReadWrite: FileProviderBasic { /** @@ -695,8 +707,9 @@ extension FileProviderBasic { } /// Returns a file name supposed to be unique with adding numbers to end of file. - /// - Important: It's a synchronous method. Don't use it on matin thread. + /// - Important: It's a synchronous method. Don't use it on main thread. public func fileByUniqueName(_ filePath: String) -> String { + assert(!Thread.isMainThread, "\(#function) is not recommended to be executed on Main Thread.") let fileUrl = URL(fileURLWithPath: filePath) let dirPath = fileUrl.deletingLastPathComponent().path let fileName = fileUrl.deletingPathExtension().lastPathComponent diff --git a/Sources/HTTPFileProvider.swift b/Sources/HTTPFileProvider.swift index 9297141..4946c11 100644 --- a/Sources/HTTPFileProvider.swift +++ b/Sources/HTTPFileProvider.swift @@ -9,10 +9,10 @@ import Foundation /** - Allows accessing to Dropbox stored files. This provider doesn't cache or save files internally, however you can - set `useCache` and `cache` properties to use Foundation `NSURLCache` system. + The abstract base class for all REST/Web based providers such as WebDAV, Dropbox, OneDrive, Google Drive, etc. and encapsulates basic + functionalitis such as downloading/uploading. - - Note: Uploading files and data are limited to 150MB, for now. + No instance of this class should (and can) be created. Use derivated classes instead. It leads to a crash with `fatalError()`. */ open class HTTPFileProvider: FileProviderBasicRemote, FileProviderOperations, FileProviderReadWrite { open class var type: String { fatalError("HTTPFileProvider is an abstract class. Please implement \(#function) in subclass.") } @@ -360,6 +360,7 @@ open class HTTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fi progress.cancel() } completionHandler(nil, error) + self.delegateNotify(operation, error: error) } downloadCompletionHandlersForTasks[session.sessionDescription!]?[task.taskIdentifier] = { tempURL in guard let httpResponse = task.response as? HTTPURLResponse , httpResponse.statusCode < 300 else { @@ -370,6 +371,7 @@ open class HTTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fi progress.cancel() } completionHandler(nil, serverError) + self.delegateNotify(operation, error: nil) return } @@ -387,16 +389,4 @@ open class HTTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fi } } -extension HTTPFileProvider { - internal func delegateNotify(_ operation: FileOperationType, error: Error?) { - DispatchQueue.main.async(execute: { - if error == nil { - self.delegate?.fileproviderSucceed(self, operation: operation) - } else { - self.delegate?.fileproviderFailed(self, operation: operation) - } - }) - } -} - extension HTTPFileProvider: FileProvider { } diff --git a/Sources/LocalFileProvider.swift b/Sources/LocalFileProvider.swift index 81d6c1f..54bc917 100644 --- a/Sources/LocalFileProvider.swift +++ b/Sources/LocalFileProvider.swift @@ -211,58 +211,67 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo @discardableResult open func create(folder folderName: String, at atPath: String, completionHandler: SimpleCompletionHandler) -> Progress? { - let opType = FileOperationType.create(path: (atPath as NSString).appendingPathComponent(folderName) + "/") - return self.doOperation(opType, completionHandler: completionHandler) + let operation = FileOperationType.create(path: (atPath as NSString).appendingPathComponent(folderName) + "/") + return self.doOperation(operation, completionHandler: completionHandler) } @discardableResult open func moveItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> Progress? { - let opType = FileOperationType.move(source: path, destination: toPath) + let operation = FileOperationType.move(source: path, destination: toPath) if !overwrite && self.fileManager.fileExists(atPath: self.url(of: toPath).path) { - completionHandler?(self.throwError(toPath, code: CocoaError.fileWriteFileExists as FoundationErrorEnum)) + let e = self.throwError(toPath, code: CocoaError.fileWriteFileExists as FoundationErrorEnum) + dispatch_queue.async { + completionHandler?(e) + } + self.delegateNotify(operation, error: e) return nil } - return self.doOperation(opType, completionHandler: completionHandler) + return self.doOperation(operation, completionHandler: completionHandler) } @discardableResult open func copyItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> Progress? { - let opType = FileOperationType.copy(source: path, destination: toPath) + let operation = FileOperationType.copy(source: path, destination: toPath) if !overwrite && self.fileManager.fileExists(atPath: self.url(of: toPath).path) { - self.dispatch_queue.async { - completionHandler?(self.throwError(toPath, code: CocoaError.fileWriteFileExists as FoundationErrorEnum)) + let e = self.throwError(toPath, code: CocoaError.fileWriteFileExists as FoundationErrorEnum) + dispatch_queue.async { + completionHandler?(e) } + self.delegateNotify(operation, error: e) return nil } - return self.doOperation(opType, completionHandler: completionHandler) + return self.doOperation(operation, completionHandler: completionHandler) } @discardableResult open func removeItem(path: String, completionHandler: SimpleCompletionHandler) -> Progress? { - let opType = FileOperationType.remove(path: path) - return self.doOperation(opType, completionHandler: completionHandler) + let operation = FileOperationType.remove(path: path) + return self.doOperation(operation, completionHandler: completionHandler) } @discardableResult open func copyItem(localFile: URL, to toPath: String, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> Progress? { + let operation = FileOperationType.copy(source: localFile.absoluteString, destination: toPath) + if !overwrite && self.fileManager.fileExists(atPath: self.url(of: toPath).path) { - self.dispatch_queue.async { - completionHandler?(self.throwError(toPath, code: CocoaError.fileWriteFileExists as FoundationErrorEnum)) + let e = self.throwError(toPath, code: CocoaError.fileWriteFileExists as FoundationErrorEnum) + dispatch_queue.async { + completionHandler?(e) } + self.delegateNotify(operation, error: e) return nil } - let opType = FileOperationType.copy(source: localFile.absoluteString, destination: toPath) - return self.doOperation(opType, forUploading: true, completionHandler: completionHandler) + return self.doOperation(operation, forUploading: true, completionHandler: completionHandler) } @discardableResult open func copyItem(path: String, toLocalURL: URL, completionHandler: SimpleCompletionHandler) -> Progress? { - let opType = FileOperationType.copy(source: path, destination: toLocalURL.absoluteString) - return self.doOperation(opType, completionHandler: completionHandler) + let operation = FileOperationType.copy(source: path, destination: toLocalURL.absoluteString) + return self.doOperation(operation, completionHandler: completionHandler) } @objc dynamic func doSimpleOperation(_ box: UndoBox) { @@ -273,9 +282,9 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo } @discardableResult - fileprivate func doOperation(_ opType: FileOperationType, data: Data? = nil, atomically: Bool = false, forUploading: Bool = false, completionHandler: SimpleCompletionHandler) -> Progress? { + fileprivate func doOperation(_ operation: FileOperationType, data: Data? = nil, atomically: Bool = false, forUploading: Bool = false, completionHandler: SimpleCompletionHandler) -> Progress? { let progress = Progress(parent: nil, userInfo: nil) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.isCancellable = false progress.setUserInfoObject(Progress.FileOperationKind.receiving, forKey: .fileOperationKindKey) @@ -289,8 +298,8 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo } } - let sourcePath = opType.source - let destPath = opType.destination + let sourcePath = operation.source + let destPath = operation.destination let source: URL = urlofpath(path: sourcePath) progress.setUserInfoObject(source, forKey: .fileURLKey) @@ -301,11 +310,11 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo dest = nil } - if let undoManager = self.undoManager, let undoOp = self.undoOperation(for: opType) { - let undoBox = UndoBox(provider: self, operation: opType, undoOperation: undoOp) + if let undoManager = self.undoManager, let undoOp = self.undoOperation(for: operation) { + let undoBox = UndoBox(provider: self, operation: operation, undoOperation: undoOp) undoManager.beginUndoGrouping() undoManager.registerUndo(withTarget: self, selector: #selector(LocalFileProvider.doSimpleOperation(_:)), object: undoBox) - undoManager.setActionName(opType.actionDescription) + undoManager.setActionName(operation.actionDescription) undoManager.endUndoGrouping() } @@ -314,7 +323,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo let operationHandler: (URL, URL?) -> Void = { source, dest in do { progress.setUserInfoObject(Date(), forKey: .startingTimeKey) - switch opType { + switch operation { case .create: if sourcePath.hasSuffix("/") { progress.totalUnitCount = 1 @@ -350,9 +359,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo self.dispatch_queue.async { completionHandler?(nil) } - DispatchQueue.main.async { - self.delegate?.fileproviderSucceed(self, operation: opType) - } + self.delegateNotify(operation, error: nil) } catch let e { if successfulSecurityScopedResourceAccess { source.stopAccessingSecurityScopedResource() @@ -361,16 +368,14 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo self.dispatch_queue.async { completionHandler?(e) } - DispatchQueue.main.async { - self.delegate?.fileproviderFailed(self, operation: opType) - } + self.delegateNotify(operation, error: e) } } if isCoorinating { successfulSecurityScopedResourceAccess = source.startAccessingSecurityScopedResource() var intents = [NSFileAccessIntent]() - switch opType { + switch operation { case .create, .modify: intents.append(NSFileAccessIntent.writingIntent(with: source, options: .forReplacing)) case .copy: @@ -390,9 +395,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo self.dispatch_queue.async { completionHandler?(error) } - DispatchQueue.main.async { - self.delegate?.fileproviderFailed(self, operation: opType) - } + self.delegateNotify(operation, error: error) }) } else { operation_queue.addOperation { @@ -404,11 +407,11 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo @discardableResult open func contents(path: String, completionHandler: @escaping ((_ contents: Data?, _ error: Error?) -> Void)) -> Progress? { - let opType = FileOperationType.fetch(path: path) + let operation = FileOperationType.fetch(path: path) let url = self.url(of: path) let progress = Progress(parent: nil, userInfo: nil) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.isCancellable = false progress.setUserInfoObject(Progress.FileOperationKind.receiving, forKey: .fileOperationKindKey) @@ -423,11 +426,13 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo self.dispatch_queue.async { completionHandler(data, nil) } + self.delegateNotify(operation, error: nil) } catch let e { progress.cancel() self.dispatch_queue.async { completionHandler(nil, e) } + self.delegateNotify(operation, error: e) } } @@ -437,9 +442,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo self.dispatch_queue.async { completionHandler(nil, error) } - DispatchQueue.main.async { - self.delegate?.fileproviderFailed(self, operation: opType) - } + self.delegateNotify(operation, error: error) }) } else { dispatch_queue.async { @@ -463,11 +466,11 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo return self.contents(path: path, completionHandler: completionHandler) } - let opType = FileOperationType.fetch(path: path) + let operation = FileOperationType.fetch(path: path) let url = self.url(of: path) let progress = Progress(parent: nil, userInfo: nil) - progress.setUserInfoObject(opType, forKey: .fileProvderOperationTypeKey) + progress.setUserInfoObject(operation, forKey: .fileProvderOperationTypeKey) progress.kind = .file progress.isCancellable = false progress.setUserInfoObject(url, forKey: .fileURLKey) @@ -476,7 +479,9 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo let operationHandler: (URL) -> Void = { url in guard let handle = FileHandle(forReadingAtPath: url.path) else { self.dispatch_queue.async { - completionHandler(nil, self.throwError(path, code: CocoaError.fileNoSuchFile as FoundationErrorEnum)) + let e = self.throwError(path, code: CocoaError.fileNoSuchFile as FoundationErrorEnum) + completionHandler(nil, e) + self.delegateNotify(operation, error: e) } return } @@ -490,7 +495,9 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo guard size > offset else { progress.cancel() self.dispatch_queue.async { - completionHandler(nil, self.throwError(path, code: CocoaError.fileReadTooLarge as FoundationErrorEnum)) + let e = self.throwError(path, code: CocoaError.fileReadTooLarge as FoundationErrorEnum) + completionHandler(nil, e) + self.delegateNotify(operation, error: e) } return } @@ -499,7 +506,9 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo guard Int64(handle.offsetInFile) == offset else { progress.cancel() self.dispatch_queue.async { - completionHandler(nil, self.throwError(path, code: CocoaError.fileReadTooLarge as FoundationErrorEnum)) + let e = self.throwError(path, code: CocoaError.fileReadTooLarge as FoundationErrorEnum) + completionHandler(nil, e) + self.delegateNotify(operation, error: e) } return } @@ -508,6 +517,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo progress.completedUnitCount = progress.totalUnitCount self.dispatch_queue.async { completionHandler(data, nil) + self.delegateNotify(operation, error: nil) } } @@ -515,9 +525,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo let intent = NSFileAccessIntent.readingIntent(with: url, options: .withoutChanges) coordinated(intents: [intent], completionHandler: operationHandler, errorHandler: { error in completionHandler(nil, error) - DispatchQueue.main.async { - self.delegate?.fileproviderFailed(self, operation: opType) - } + self.delegateNotify(operation, error: error) }) } else { dispatch_queue.async { @@ -531,8 +539,8 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo @discardableResult open func writeContents(path: String, contents data: Data?, atomically: Bool, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> Progress? { let fileExists = fileManager.fileExists(atPath: url(of: path).path) - let opType: FileOperationType = fileExists ? .modify(path: path) : .create(path: path) - return self.doOperation(opType, data: data ?? Data(), atomically: atomically, completionHandler: completionHandler) + let operation: FileOperationType = fileExists ? .modify(path: path) : .create(path: path) + return self.doOperation(operation, data: data ?? Data(), atomically: atomically, completionHandler: completionHandler) } fileprivate var monitors = [LocalFolderMonitor]() @@ -579,17 +587,14 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo */ open func create(symbolicLink path: String, withDestinationPath destPath: String, completionHandler: SimpleCompletionHandler) { operation_queue.addOperation { + let operation = FileOperationType.link(link: path, target: destPath) do { try self.opFileManager.createSymbolicLink(at: self.url(of: path), withDestinationURL: self.url(of: destPath)) completionHandler?(nil) - DispatchQueue.main.async { - self.delegate?.fileproviderSucceed(self, operation: .link(link: path, target: destPath)) - } + self.delegateNotify(operation, error: nil) } catch let e { completionHandler?(e) - DispatchQueue.main.async { - self.delegate?.fileproviderFailed(self, operation: .link(link: path, target: destPath)) - } + self.delegateNotify(operation, error: e) } } } diff --git a/Sources/OneDriveFileProvider.swift b/Sources/OneDriveFileProvider.swift index 29257f8..9f1dfb0 100644 --- a/Sources/OneDriveFileProvider.swift +++ b/Sources/OneDriveFileProvider.swift @@ -201,12 +201,18 @@ open class OneDriveFileProvider: HTTPFileProvider, FileProviderSharing { var request = URLRequest(url: url) request.httpMethod = method request.set(httpAuthentication: credential, with: .oAuth2) - if let dest = correctPath(operation.destination) as NSString?, !dest.hasPrefix("file://") { + + switch operation { + case .copy(let source, let dest) where !source.hasPrefix("file://") && !dest.hasPrefix("file://"), + .move(source: let source, destination: let dest): request.set(contentType: .json) + let cdest = (correctPath(dest) as NSString?)! var requestDictionary = [String: AnyObject]() - requestDictionary["parentReference"] = ("/drive/\(drive):" + dest.deletingLastPathComponent) as NSString - requestDictionary["name"] = dest.lastPathComponent as NSString + requestDictionary["parentReference"] = ("/drive/\(drive):" + cdest.deletingLastPathComponent) as NSString + requestDictionary["name"] = cdest.lastPathComponent as NSString request.httpBody = Data(jsonDictionary: requestDictionary) + default: + break } return request @@ -240,9 +246,7 @@ open class OneDriveFileProvider: HTTPFileProvider, FileProviderSharing { fileprivate func unregisterNotifcation(path: String) { NotImplemented() } -} - -extension OneDriveFileProvider { + open func publicLink(to path: String, completionHandler: @escaping ((_ link: URL?, _ attribute: FileObject?, _ expiration: Date?, _ error: Error?) -> Void)) { var request = URLRequest(url: self.url(of: path, modifier: "action.createLink")) request.httpMethod = "POST" diff --git a/Sources/WebDAVFileProvider.swift b/Sources/WebDAVFileProvider.swift index ca2e8e9..c615bad 100644 --- a/Sources/WebDAVFileProvider.swift +++ b/Sources/WebDAVFileProvider.swift @@ -77,7 +77,7 @@ open class WebDAVFileProvider: HTTPFileProvider, FileProviderSharing { - `error`: Error returned by system. */ open func contentsOfDirectory(path: String, including: [URLResourceKey], completionHandler: @escaping ((_ contents: [FileObject], _ error: Error?) -> Void)) { - let opType = FileOperationType.fetch(path: path) + let operation = FileOperationType.fetch(path: path) let url = self.url(of: path).appendingPathComponent("") var request = URLRequest(url: url) request.httpMethod = "PROPFIND" @@ -86,7 +86,7 @@ open class WebDAVFileProvider: HTTPFileProvider, FileProviderSharing { request.set(contentType: .xml) request.httpBody = "\n\n\(WebDavFileObject.propString(including))\n".data(using: .utf8) request.setValue(String(request.httpBody!.count), forHTTPHeaderField: "Content-Length") - runDataTask(with: request, operation: opType, completionHandler: { (data, response, error) in + runDataTask(with: request, operation: operation, completionHandler: { (data, response, error) in var responseError: FileProviderWebDavError? if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderWebDavError(code: rCode, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8), url: url)