diff --git a/FilesProvider.podspec b/FilesProvider.podspec index b1f3b27..1ea3870 100644 --- a/FilesProvider.podspec +++ b/FilesProvider.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| # s.name = "FilesProvider" - s.version = "0.22.0" + s.version = "0.23.0" s.summary = "FileManager replacement for Local and Remote (WebDAV/FTP/Dropbox/OneDrive/SMB2) files on iOS and macOS." # This description is used to generate tags and improve search results. diff --git a/FilesProvider.xcodeproj/project.pbxproj b/FilesProvider.xcodeproj/project.pbxproj index 5dba4f7..3dde556 100644 --- a/FilesProvider.xcodeproj/project.pbxproj +++ b/FilesProvider.xcodeproj/project.pbxproj @@ -72,9 +72,6 @@ 799396B91D48C02300086753 /* SMBFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799396981D48C02300086753 /* SMBFileProvider.swift */; }; 799396BA1D48C02300086753 /* SMBFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799396981D48C02300086753 /* SMBFileProvider.swift */; }; 799396BB1D48C02300086753 /* SMBFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799396981D48C02300086753 /* SMBFileProvider.swift */; }; - 799396BC1D48C02300086753 /* CIFSTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7993969A1D48C02300086753 /* CIFSTypes.swift */; }; - 799396BD1D48C02300086753 /* CIFSTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7993969A1D48C02300086753 /* CIFSTypes.swift */; }; - 799396BE1D48C02300086753 /* CIFSTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7993969A1D48C02300086753 /* CIFSTypes.swift */; }; 799396BF1D48C02300086753 /* SMB2DataTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7993969B1D48C02300086753 /* SMB2DataTypes.swift */; }; 799396C01D48C02300086753 /* SMB2DataTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7993969B1D48C02300086753 /* SMB2DataTypes.swift */; }; 799396C11D48C02300086753 /* SMB2DataTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7993969B1D48C02300086753 /* SMB2DataTypes.swift */; }; @@ -593,7 +590,6 @@ 799396B91D48C02300086753 /* SMBFileProvider.swift in Sources */, 794C220E1D591A4B00EC49B8 /* SMB2QueryTypes.swift in Sources */, 794C21FE1D58912A00EC49B8 /* DropboxHelper.swift in Sources */, - 799396BC1D48C02300086753 /* CIFSTypes.swift in Sources */, 794C220A1D5893F800EC49B8 /* SMB2Notification.swift in Sources */, 799396D11D48C02300086753 /* SMB2SetInfo.swift in Sources */, 7924B1961D89DAE000589DB7 /* Document.swift in Sources */, @@ -638,7 +634,6 @@ 799396BA1D48C02300086753 /* SMBFileProvider.swift in Sources */, 794C220F1D591A4B00EC49B8 /* SMB2QueryTypes.swift in Sources */, 794C21FF1D58912A00EC49B8 /* DropboxHelper.swift in Sources */, - 799396BD1D48C02300086753 /* CIFSTypes.swift in Sources */, 794C220B1D5893F800EC49B8 /* SMB2Notification.swift in Sources */, 799396D21D48C02300086753 /* SMB2SetInfo.swift in Sources */, 7924B1971D89DAE000589DB7 /* Document.swift in Sources */, @@ -683,7 +678,6 @@ 799396BB1D48C02300086753 /* SMBFileProvider.swift in Sources */, 794C22101D591A4B00EC49B8 /* SMB2QueryTypes.swift in Sources */, 794C22001D58912A00EC49B8 /* DropboxHelper.swift in Sources */, - 799396BE1D48C02300086753 /* CIFSTypes.swift in Sources */, 794C220C1D5893F800EC49B8 /* SMB2Notification.swift in Sources */, 799396D31D48C02300086753 /* SMB2SetInfo.swift in Sources */, 7924B1981D89DAE000589DB7 /* Document.swift in Sources */, @@ -802,6 +796,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; + BUNDLE_VERSION_STRING = 0.23.0; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -837,6 +832,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; + BUNDLE_VERSION_STRING = 0.23.0; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; diff --git a/Sources/CloudFileProvider.swift b/Sources/CloudFileProvider.swift index 5a7c775..3079abf 100644 --- a/Sources/CloudFileProvider.swift +++ b/Sources/CloudFileProvider.swift @@ -283,9 +283,9 @@ open class CloudFileProvider: LocalFileProvider, FileProviderSharing { return progress } - open override func isReachable(completionHandler: @escaping (Bool) -> Void) { + open override func isReachable(completionHandler: @escaping (_ success: Bool, _ error: Error?) -> Void) { dispatch_queue.async { - completionHandler(self.fileManager.ubiquityIdentityToken != nil) + completionHandler(self.fileManager.ubiquityIdentityToken != nil, nil) } } diff --git a/Sources/FTPFileProvider.swift b/Sources/FTPFileProvider.swift index 46dad1a..8322098 100644 --- a/Sources/FTPFileProvider.swift +++ b/Sources/FTPFileProvider.swift @@ -343,9 +343,9 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil return relativePath.replacingOccurrences(of: "/", with: "", options: .anchored) } - open func isReachable(completionHandler: @escaping (Bool) -> Void) { + open func isReachable(completionHandler: @escaping (_ success: Bool, _ error: Error?) -> Void) { self.attributesOfItem(path: "/") { (file, error) in - completionHandler(file != nil) + completionHandler(file != nil, error) } } diff --git a/Sources/FileProvider.swift b/Sources/FileProvider.swift index 92546b5..99b1afe 100644 --- a/Sources/FileProvider.swift +++ b/Sources/FileProvider.swift @@ -153,7 +153,8 @@ public protocol FileProviderBasic: class, NSSecureCoding { /// - Note: To prevent race condition, use this method wisely and avoid it as far possible. /// /// - Parameter success: indicated server is reachable or not. - func isReachable(completionHandler: @escaping(_ success: Bool) -> Void) + /// - Parameter error: `Error` returned by server if occured. + func isReachable(completionHandler: @escaping(_ success: Bool, _ error: Error?) -> Void) } extension FileProviderBasic { diff --git a/Sources/HTTPFileProvider.swift b/Sources/HTTPFileProvider.swift index af14712..6714a1c 100644 --- a/Sources/HTTPFileProvider.swift +++ b/Sources/HTTPFileProvider.swift @@ -153,9 +153,16 @@ open class HTTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fi fatalError("HTTPFileProvider is an abstract class. Please implement \(#function) in subclass.") } - open func isReachable(completionHandler: @escaping (Bool) -> Void) { + open func isReachable(completionHandler: @escaping (_ success: Bool, _ error: Error?) -> Void) { self.storageProperties { volume in - completionHandler(volume != nil) + if volume != nil { + completionHandler(volume != nil, nil) + return + } else { + self.contentsOfDirectory(path: "", completionHandler: { (files, error) in + completionHandler(false, error) + }) + } } } diff --git a/Sources/LocalFileProvider.swift b/Sources/LocalFileProvider.swift index 8b37696..fc27194 100644 --- a/Sources/LocalFileProvider.swift +++ b/Sources/LocalFileProvider.swift @@ -215,9 +215,14 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor { return progress } - open func isReachable(completionHandler: @escaping (_ success: Bool) -> Void) { + open func isReachable(completionHandler: @escaping (_ success: Bool, _ error: Error?) -> Void) { dispatch_queue.async { - completionHandler(self.fileManager.isReadableFile(atPath: self.baseURL!.path)) + do { + let isReachable = try self.baseURL!.checkResourceIsReachable() + completionHandler(isReachable, nil) + } catch { + completionHandler(false, error) + } } } diff --git a/Sources/OneDriveFileProvider.swift b/Sources/OneDriveFileProvider.swift index 55fc2c2..a9b4b1d 100644 --- a/Sources/OneDriveFileProvider.swift +++ b/Sources/OneDriveFileProvider.swift @@ -361,13 +361,19 @@ open class OneDriveFileProvider: HTTPFileProvider, FileProviderSharing { /// - Note: To prevent race condition, use this method wisely and avoid it as far possible. /// /// - Parameter success: indicated server is reachable or not. - open override func isReachable(completionHandler: @escaping (Bool) -> Void) { + open override func isReachable(completionHandler: @escaping (_ success: Bool, _ error: Error?) -> Void) { var request = URLRequest(url: url(of: "")) request.httpMethod = "HEAD" request.setValue(authentication: credential, with: .oAuth2) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in let status = (response as? HTTPURLResponse)?.statusCode ?? 400 - completionHandler(status == 200) + if status >= 400, let code = FileProviderHTTPErrorCode(rawValue: status) { + let errorDesc = data.flatMap({ String(data: $0, encoding: .utf8) }) + let error = FileProviderOneDriveError(code: code, path: "", serverDescription: errorDesc) + completionHandler(false, error) + return + } + completionHandler(status == 200, error) }) task.resume() } diff --git a/Sources/SMBFileProvider.swift b/Sources/SMBFileProvider.swift index 6f5338d..d87cc14 100644 --- a/Sources/SMBFileProvider.swift +++ b/Sources/SMBFileProvider.swift @@ -68,7 +68,7 @@ class SMBFileProvider: FileProvider, FileProviderMonitor { NotImplemented() } - func isReachable(completionHandler: @escaping (Bool) -> Void) { + func isReachable(completionHandler: @escaping (_ success: Bool, _ error: Error?) -> Void) { NotImplemented() } diff --git a/Sources/WebDAVFileProvider.swift b/Sources/WebDAVFileProvider.swift index 784827f..b103dc2 100644 --- a/Sources/WebDAVFileProvider.swift +++ b/Sources/WebDAVFileProvider.swift @@ -267,7 +267,7 @@ open class WebDAVFileProvider: HTTPFileProvider, FileProviderSharing { return progress } - override open func isReachable(completionHandler: @escaping (Bool) -> Void) { + override open func isReachable(completionHandler: @escaping (_ success: Bool, _ error: Error?) -> Void) { var request = URLRequest(url: baseURL!) request.httpMethod = "PROPFIND" request.setValue("0", forHTTPHeaderField: "Depth") @@ -276,7 +276,13 @@ open class WebDAVFileProvider: HTTPFileProvider, FileProviderSharing { request.httpBody = WebDavFileObject.xmlProp([.volumeTotalCapacityKey, .volumeAvailableCapacityKey]) runDataTask(with: request, completionHandler: { (data, response, error) in let status = (response as? HTTPURLResponse)?.statusCode ?? 400 - completionHandler(status < 300) + if status >= 400, let code = FileProviderHTTPErrorCode(rawValue: status) { + let errorDesc = data.flatMap({ String(data: $0, encoding: .utf8) }) + let error = FileProviderWebDavError(code: code, path: "", serverDescription: errorDesc, url: self.baseURL!) + completionHandler(false, error) + return + } + completionHandler(status < 300, error) }) }