diff --git a/FileProvider.podspec b/FileProvider.podspec index 17f3273..8e2831b 100644 --- a/FileProvider.podspec +++ b/FileProvider.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| # s.name = "FileProvider" - s.version = "0.12.7" + s.version = "0.12.8" s.summary = "FileManager replacement for Local and Remote (WebDAV/Dropbox/OneDrive/SMB2) files on iOS and macOS." # This description is used to generate tags and improve search results. diff --git a/FileProvider.xcodeproj/project.pbxproj b/FileProvider.xcodeproj/project.pbxproj index 2de0574..ee9843c 100644 --- a/FileProvider.xcodeproj/project.pbxproj +++ b/FileProvider.xcodeproj/project.pbxproj @@ -597,7 +597,7 @@ 799396601D48B7BF00086753 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_VERSION_STRING = 0.12.7; + BUNDLE_VERSION_STRING = 0.12.8; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -627,7 +627,7 @@ 799396611D48B7BF00086753 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_VERSION_STRING = 0.12.7; + BUNDLE_VERSION_STRING = 0.12.8; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; diff --git a/Sources/CloudFileProvider.swift b/Sources/CloudFileProvider.swift index f4d695c..4670a69 100644 --- a/Sources/CloudFileProvider.swift +++ b/Sources/CloudFileProvider.swift @@ -197,6 +197,12 @@ open class CloudFileProvider: LocalFileProvider { } } + open override func isReachable(completionHandler: @escaping (Bool) -> Void) { + dispatch_queue.async { + completionHandler(self.fileManager.ubiquityIdentityToken != nil) + } + } + /** Creates a new directory at the specified path asynchronously. This will create any necessary intermediate directories. @@ -609,7 +615,7 @@ open class CloudFileProvider: LocalFileProvider { } /// Returns a pulic url with expiration date, can be shared with other people. - open func temporaryLink(to path: String, completionHandler: @escaping ((_ link: URL?, _ attribute: FileObject?, _ expiration: Date?, _ error: Error?) -> Void)) { + open func publicLink(to path: String, completionHandler: @escaping ((_ link: URL?, _ attribute: FileObject?, _ expiration: Date?, _ error: Error?) -> Void)) { operation_queue.addOperation { do { var expiration: NSDate? diff --git a/Sources/DropboxFileProvider.swift b/Sources/DropboxFileProvider.swift index 3bc01b4..0f7a8f2 100644 --- a/Sources/DropboxFileProvider.swift +++ b/Sources/DropboxFileProvider.swift @@ -129,6 +129,12 @@ open class DropboxFileProvider: FileProviderBasicRemote { task.resume() } + open func isReachable(completionHandler: @escaping (Bool) -> Void) { + self.storageProperties { total, _ in + completionHandler(total > 0) + } + } + open weak var fileOperationDelegate: FileOperationDelegate? } diff --git a/Sources/FileProvider.swift b/Sources/FileProvider.swift index 4d92c6c..e65e465 100644 --- a/Sources/FileProvider.swift +++ b/Sources/FileProvider.swift @@ -95,6 +95,9 @@ public protocol FileProviderBasic: class { - Returns: An url, can be used to access to file directly. */ func url(of path: String?) -> URL + + /// Checks the connection to server or permission on local + func isReachable(completionHandler: @escaping(_ success: Bool) -> Void) } extension FileProviderBasic { diff --git a/Sources/LocalFileProvider.swift b/Sources/LocalFileProvider.swift index 9e067f9..2415433 100644 --- a/Sources/LocalFileProvider.swift +++ b/Sources/LocalFileProvider.swift @@ -139,6 +139,12 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo } } + open func isReachable(completionHandler: @escaping (Bool) -> Void) { + dispatch_queue.async { + completionHandler(self.fileManager.isReadableFile(atPath: self.baseURL!.path)) + } + } + open weak var fileOperationDelegate : FileOperationDelegate? @discardableResult @@ -247,8 +253,9 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo undoManager.endUndoGrouping() } + var successfulSecurityScopedResourceAccess = false + let operationHandler: (URL, URL?) -> Void = { source, dest in - let successfulSecurityScopedResourceAccess = source.startAccessingSecurityScopedResource() do { switch opType { case .create: @@ -295,9 +302,9 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo if isCoorinating { var intents = [NSFileAccessIntent]() - + successfulSecurityScopedResourceAccess = source.startAccessingSecurityScopedResource() switch opType { - case .create, .remove, .modify: + case .create, .modify: intents.append(NSFileAccessIntent.writingIntent(with: source, options: .forReplacing)) case .copy: guard let dest = dest else { return nil } @@ -305,8 +312,10 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo intents.append(NSFileAccessIntent.writingIntent(with: dest, options: .forReplacing)) case .move: guard let dest = dest else { return nil } - intents.append(NSFileAccessIntent.writingIntent(with: source, options: .forDeleting)) + intents.append(NSFileAccessIntent.writingIntent(with: source, options: .forMoving)) intents.append(NSFileAccessIntent.writingIntent(with: dest, options: .forReplacing)) + case .remove: + intents.append(NSFileAccessIntent.writingIntent(with: source, options: .forDeleting)) default: return nil } diff --git a/Sources/OneDriveFileProvide.swift b/Sources/OneDriveFileProvide.swift index 2921030..af0ea64 100644 --- a/Sources/OneDriveFileProvide.swift +++ b/Sources/OneDriveFileProvide.swift @@ -132,6 +132,18 @@ open class OneDriveFileProvider: FileProviderBasicRemote { task.resume() } + open func isReachable(completionHandler: @escaping (Bool) -> Void) { + let url = URL(string: "/drive/root", relativeTo: baseURL)! + var request = URLRequest(url: url) + request.httpMethod = "HEAD" + request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") + let task = session.dataTask(with: request, completionHandler: { (data, response, error) in + let status = (response as? HTTPURLResponse)?.statusCode ?? 400 + completionHandler(status == 200) + }) + task.resume() + } + open weak var fileOperationDelegate: FileOperationDelegate? } diff --git a/Sources/SMBFileProvider.swift b/Sources/SMBFileProvider.swift index 7c35069..e34b8da 100644 --- a/Sources/SMBFileProvider.swift +++ b/Sources/SMBFileProvider.swift @@ -44,6 +44,10 @@ class SMBFileProvider: FileProvider, FileProviderMonitor { NotImplemented() } + func isReachable(completionHandler: @escaping (Bool) -> Void) { + NotImplemented() + } + open weak var fileOperationDelegate: FileOperationDelegate? open func create(folder folderName: String, at atPath: String, completionHandler: SimpleCompletionHandler) -> OperationHandle? { diff --git a/Sources/WebDAVFileProvider.swift b/Sources/WebDAVFileProvider.swift index 2c9195b..a0f7847 100644 --- a/Sources/WebDAVFileProvider.swift +++ b/Sources/WebDAVFileProvider.swift @@ -156,6 +156,19 @@ open class WebDAVFileProvider: FileProviderBasicRemote { }) } + open func isReachable(completionHandler: @escaping (Bool) -> Void) { + var request = URLRequest(url: baseURL!) + request.httpMethod = "PROPFIND" + request.setValue("0", forHTTPHeaderField: "Depth") + request.setValue("text/xml; charset=\"utf-8\"", forHTTPHeaderField: "Content-Type") + request.httpBody = "\n\n\n".data(using: .utf8) + request.setValue(String(request.httpBody!.count), forHTTPHeaderField: "Content-Length") + runDataTask(with: request, completionHandler: { (data, response, error) in + let status = (response as? HTTPURLResponse)?.statusCode ?? 400 + completionHandler(status < 300) + }) + } + open weak var fileOperationDelegate: FileOperationDelegate? } diff --git a/fileprovider.png b/fileprovider.png index 9ee294e..5f0ccee 100644 Binary files a/fileprovider.png and b/fileprovider.png differ