Consistancy to delegate call in all contents(of:) methods
- renamed opType instances to operation - moved to v2 in Dropbox - removed redundant CloudFileProvider methods
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n\(WebDavFileObject.propString(including))\n</D:propfind>".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)
|
||||
|
||||
Reference in New Issue
Block a user