Fixed FTP/SSL issue, Fixed error descriptions for HTTP and FTP

- Changed thumbnail and properties method signature to support progress
This commit is contained in:
Amir Abbas
2018-02-24 23:41:45 +03:30
parent 1bf42b489d
commit fd89a04c8e
10 changed files with 65 additions and 45 deletions
+6 -4
View File
@@ -268,7 +268,7 @@ open class DropboxFileProvider: HTTPFileProvider, FileProviderSharing {
} else {
errorDesc = data.flatMap({ String(data: $0, encoding: .utf8) })
}
return FileProviderDropboxError(code: code, path: path ?? "", errorDescription: errorDesc)
return FileProviderDropboxError(code: code, path: path ?? "", serverDescription: errorDesc)
}
override var maxUploadSimpleSupported: Int64 {
@@ -417,7 +417,7 @@ extension DropboxFileProvider: ExtendedFileProvider {
}
/// Default value for dimension is 64x64, according to Dropbox documentation
open func thumbnailOfFile(path: String, dimension: CGSize?, completionHandler: @escaping ((_ image: ImageClass?, _ error: Error?) -> Void)) {
open func thumbnailOfFile(path: String, dimension: CGSize?, completionHandler: @escaping ((_ image: ImageClass?, _ error: Error?) -> Void)) -> Progress? {
let url: URL
let thumbAPI: Bool
switch (path as NSString).pathExtension.lowercased() {
@@ -432,7 +432,7 @@ extension DropboxFileProvider: ExtendedFileProvider {
url = URL(string: "files/get_preview", relativeTo: contentURL)!
thumbAPI = false
default:
return
return nil
}
var request = URLRequest(url: url)
request.setValue(authentication: credential, with: .oAuth2)
@@ -469,9 +469,10 @@ extension DropboxFileProvider: ExtendedFileProvider {
completionHandler(image, error)
})
task.resume()
return nil
}
open func propertiesOfFile(path: String, completionHandler: @escaping ((_ propertiesDictionary: [String : Any], _ keys: [String], _ error: Error?) -> Void)) {
open func propertiesOfFile(path: String, completionHandler: @escaping ((_ propertiesDictionary: [String : Any], _ keys: [String], _ error: Error?) -> Void)) -> Progress? {
let url = URL(string: "files/get_metadata", relativeTo: apiURL)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
@@ -493,5 +494,6 @@ extension DropboxFileProvider: ExtendedFileProvider {
completionHandler(dic, keys, serverError ?? error)
})
task.resume()
return nil
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ import Foundation
public struct FileProviderDropboxError: FileProviderHTTPError {
public let code: FileProviderHTTPErrorCode
public let path: String
public let errorDescription: String?
public let serverDescription: String?
}
/// Containts path, url and attributes of a Dropbox file or resource.
+4 -2
View File
@@ -54,7 +54,7 @@ extension LocalFileProvider: ExtendedFileProvider {
}
}
open func thumbnailOfFile(path: String, dimension: CGSize? = nil, completionHandler: @escaping ((_ image: ImageClass?, _ error: Error?) -> Void)) {
open func thumbnailOfFile(path: String, dimension: CGSize? = nil, completionHandler: @escaping ((_ image: ImageClass?, _ error: Error?) -> Void)) -> Progress? {
let dimension = dimension ?? CGSize(width: 64, height: 64)
(dispatch_queue).async {
var thumbnailImage: ImageClass? = nil
@@ -84,9 +84,10 @@ extension LocalFileProvider: ExtendedFileProvider {
completionHandler(scaledImage, nil)
}
}
return nil
}
open func propertiesOfFile(path: String, completionHandler: @escaping ((_ propertiesDictionary: [String: Any], _ keys: [String], _ error: Error?) -> Void)) {
open func propertiesOfFile(path: String, completionHandler: @escaping ((_ propertiesDictionary: [String: Any], _ keys: [String], _ error: Error?) -> Void)) -> Progress? {
(dispatch_queue).async {
let fileExt = (path as NSString).pathExtension.lowercased()
var getter: ((_ fileURL: URL) -> (prop: [String: Any], keys: [String]))?
@@ -117,6 +118,7 @@ extension LocalFileProvider: ExtendedFileProvider {
completionHandler(dic, keys, nil)
}
return nil
}
}
+16 -12
View File
@@ -418,13 +418,19 @@ public class FileProviderStreamTask: URLSessionTask, StreamDelegate {
return
}
if isSecure {
inputStream.setProperty(securityLevel.rawValue, forKey: .socketSecurityLevelKey)
outputStream.setProperty(securityLevel.rawValue, forKey: .socketSecurityLevelKey)
} else {
inputStream.setProperty(StreamSocketSecurityLevel.none.rawValue, forKey: .socketSecurityLevelKey)
outputStream.setProperty(StreamSocketSecurityLevel.none.rawValue, forKey: .socketSecurityLevelKey)
}
inputStream.delegate = self
outputStream.delegate = self
operation_queue.addOperation {
inputStream.schedule(in: RunLoop.main, forMode: .defaultRunLoopMode)
outputStream.schedule(in: RunLoop.main, forMode: .defaultRunLoopMode)
}
inputStream.schedule(in: RunLoop.main, forMode: .defaultRunLoopMode)
outputStream.schedule(in: RunLoop.main, forMode: .defaultRunLoopMode)
inputStream.open()
outputStream.open()
@@ -629,6 +635,9 @@ public class FileProviderStreamTask: URLSessionTask, StreamDelegate {
}
}
fileprivate var isSecure = false
public var securityLevel: StreamSocketSecurityLevel = .tlSv1
/**
* Completes any enqueued reads and writes, and establishes a secure connection.
*
@@ -643,10 +652,7 @@ public class FileProviderStreamTask: URLSessionTask, StreamDelegate {
}
}
operation_queue.addOperation {
self.inputStream!.setProperty(StreamSocketSecurityLevel.negotiatedSSL.rawValue, forKey: .socketSecurityLevelKey)
self.outputStream!.setProperty(StreamSocketSecurityLevel.negotiatedSSL.rawValue, forKey: .socketSecurityLevelKey)
}
isSecure = true
}
/**
@@ -659,10 +665,8 @@ public class FileProviderStreamTask: URLSessionTask, StreamDelegate {
return
}
}
operation_queue.addOperation {
self.inputStream!.setProperty(StreamSocketSecurityLevel.none.rawValue, forKey: .socketSecurityLevelKey)
self.outputStream!.setProperty(StreamSocketSecurityLevel.none.rawValue, forKey: .socketSecurityLevelKey)
}
isSecure = false
}
open func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
+11 -7
View File
@@ -936,18 +936,18 @@ internal extension FTPFileProvider {
}
/// Contains error code and description returned by FTP/S provider.
public struct FileProviderFTPError: Error {
public struct FileProviderFTPError: LocalizedError {
/// HTTP status code returned for error by server.
public let code: Int
/// Path of file/folder casued that error
public let path: String
/// Contents returned by server as error description
public let errorDescription: String?
public let serverDescription: String?
init(code: Int, path: String, errorDescription: String?) {
init(code: Int, path: String, serverDescription: String?) {
self.code = code
self.path = path
self.errorDescription = errorDescription
self.serverDescription = serverDescription
}
init(message response: String, path: String = "") {
@@ -962,12 +962,16 @@ public struct FileProviderFTPError: Error {
self.path = path
if code > 0 {
#if swift(>=4.0)
self.errorDescription = message[startIndex...].trimmingCharacters(in: .whitespacesAndNewlines)
self.serverDescription = message[startIndex...].trimmingCharacters(in: .whitespacesAndNewlines)
#else
self.errorDescription = message.substring(from: startIndex).trimmingCharacters(in: .whitespacesAndNewlines)
self.serverDescription = message.substring(from: startIndex).trimmingCharacters(in: .whitespacesAndNewlines)
#endif
} else {
self.errorDescription = message
self.serverDescription = message
}
}
public var errorDescription: String? {
return serverDescription
}
}
+9 -5
View File
@@ -815,7 +815,8 @@ public protocol ExtendedFileProvider: FileProviderBasic {
- image: `NSImage`/`UIImage` object contains preview.
- error: `Error` returned by system.
*/
func thumbnailOfFile(path: String, completionHandler: @escaping (_ image: ImageClass?, _ error: Error?) -> Void)
@discardableResult
func thumbnailOfFile(path: String, completionHandler: @escaping (_ image: ImageClass?, _ error: Error?) -> Void) -> Progress?
/**
Generates and returns a thumbnail preview of document asynchronously. The defualt dimension of returned image is different
@@ -831,7 +832,8 @@ public protocol ExtendedFileProvider: FileProviderBasic {
- image: `NSImage`/`UIImage` object contains preview.
- error: `Error` returned by system.
*/
func thumbnailOfFile(path: String, dimension: CGSize?, completionHandler: @escaping (_ image: ImageClass?, _ error: Error?) -> Void)
@discardableResult
func thumbnailOfFile(path: String, dimension: CGSize?, completionHandler: @escaping (_ image: ImageClass?, _ error: Error?) -> Void) -> Progress?
/**
Fetching properties of file like dimensions, duration, etc. It's variant depending on file type.
@@ -847,12 +849,14 @@ public protocol ExtendedFileProvider: FileProviderBasic {
- keys: An `Array` contains ordering of keys.
- error: Error returned by system.
*/
func propertiesOfFile(path: String, completionHandler: @escaping (_ propertiesDictionary: [String: Any], _ keys: [String], _ error: Error?) -> Void)
@discardableResult
func propertiesOfFile(path: String, completionHandler: @escaping (_ propertiesDictionary: [String: Any], _ keys: [String], _ error: Error?) -> Void) -> Progress?
}
extension ExtendedFileProvider {
public func thumbnailOfFile(path: String, completionHandler: @escaping ((_ image: ImageClass?, _ error: Error?) -> Void)) {
self.thumbnailOfFile(path: path, dimension: nil, completionHandler: completionHandler)
@discardableResult
public func thumbnailOfFile(path: String, completionHandler: @escaping ((_ image: ImageClass?, _ error: Error?) -> Void)) -> Progress? {
return self.thumbnailOfFile(path: path, dimension: nil, completionHandler: completionHandler)
}
internal static func convertToImage(pdfData: Data?, page: Int = 1) -> ImageClass? {
+5 -3
View File
@@ -510,7 +510,7 @@ open class OneDriveFileProvider: HTTPFileProvider, FileProviderSharing {
} else {
errorDesc = data.flatMap({ String(data: $0, encoding: .utf8) })
}
return FileProviderOneDriveError(code: code, path: path ?? "", errorDescription: errorDesc)
return FileProviderOneDriveError(code: code, path: path ?? "", serverDescription: errorDesc)
}
override var maxUploadSimpleSupported: Int64 {
@@ -574,7 +574,7 @@ extension OneDriveFileProvider: ExtendedFileProvider {
}
}
open func thumbnailOfFile(path: String, dimension: CGSize?, completionHandler: @escaping ((_ image: ImageClass?, _ error: Error?) -> Void)) {
open func thumbnailOfFile(path: String, dimension: CGSize?, completionHandler: @escaping ((_ image: ImageClass?, _ error: Error?) -> Void)) -> Progress? {
let url: URL
if let dimension = dimension {
url = self.url(of: path, modifier: "thumbnails/0/=c\(dimension.width)x\(dimension.height)/content")
@@ -595,9 +595,10 @@ extension OneDriveFileProvider: ExtendedFileProvider {
completionHandler(image, error)
})
task.resume()
return nil
}
open func propertiesOfFile(path: String, completionHandler: @escaping ((_ propertiesDictionary: [String : Any], _ keys: [String], _ error: Error?) -> Void)) {
open func propertiesOfFile(path: String, completionHandler: @escaping ((_ propertiesDictionary: [String : Any], _ keys: [String], _ error: Error?) -> Void)) -> Progress? {
var request = URLRequest(url: url(of: path))
request.httpMethod = "GET"
request.setValue(authentication: credential, with: .oAuth2)
@@ -615,5 +616,6 @@ extension OneDriveFileProvider: ExtendedFileProvider {
completionHandler(dic, keys, serverError ?? error)
})
task.resume()
return nil
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ import Foundation
public struct FileProviderOneDriveError: FileProviderHTTPError {
public let code: FileProviderHTTPErrorCode
public let path: String
public let errorDescription: String?
public let serverDescription: String?
}
/// Containts path, url and attributes of a OneDrive file or resource.
+5 -5
View File
@@ -10,7 +10,7 @@ import Foundation
/// A protocol defines properties for errors returned by HTTP/S based providers.
/// Including Dropbox, OneDrive and WebDAV.
public protocol FileProviderHTTPError: Error, CustomStringConvertible {
public protocol FileProviderHTTPError: LocalizedError, CustomStringConvertible {
/// HTTP status codes as an enum.
typealias Code = FileProviderHTTPErrorCode
/// HTTP status code returned for error by server.
@@ -18,16 +18,16 @@ public protocol FileProviderHTTPError: Error, CustomStringConvertible {
/// Path of file/folder casued that error
var path: String { get }
/// Contents returned by server as error description
var errorDescription: String? { get }
var serverDescription: String? { get }
}
extension FileProviderHTTPError {
public var description: String {
return code.description
return "Status \(code.rawValue): \(code.description)"
}
public var localizedDescription: String {
return description
public var errorDescription: String? {
return "Status \(code.rawValue): \(code.description)"
}
}
+7 -5
View File
@@ -360,7 +360,7 @@ open class WebDAVFileProvider: HTTPFileProvider, FileProviderSharing {
}
override func serverError(with code: FileProviderHTTPErrorCode, path: String?, data: Data?) -> FileProviderHTTPError {
return FileProviderWebDavError(code: code, path: path ?? "", errorDescription: data.flatMap({ String(data: $0, encoding: .utf8) }), url: self.url(of: path ?? ""))
return FileProviderWebDavError(code: code, path: path ?? "", serverDescription: data.flatMap({ String(data: $0, encoding: .utf8) }), url: self.url(of: path ?? ""))
}
override func multiStatusHandler(source: String, data: Data, completionHandler: SimpleCompletionHandler) {
@@ -397,12 +397,12 @@ extension WebDAVFileProvider: ExtendedFileProvider {
return supportedExt.contains((path as NSString).pathExtension)
}
open func thumbnailOfFile(path: String, dimension: CGSize?, completionHandler: @escaping ((ImageClass?, Error?) -> Void)) {
open func thumbnailOfFile(path: String, dimension: CGSize?, completionHandler: @escaping ((ImageClass?, Error?) -> Void)) -> Progress? {
guard self.baseURL?.host?.contains("dav.yandex.") ?? false else {
dispatch_queue.async {
completionHandler(nil, self.urlError(path, code: .resourceUnavailable))
}
return
return nil
}
let dimension = dimension ?? CGSize(width: 64, height: 64)
@@ -421,16 +421,18 @@ extension WebDAVFileProvider: ExtendedFileProvider {
completionHandler(data.flatMap({ ImageClass(data: $0) }), nil)
})
task.resume()
return nil
}
open func propertiesOfFileSupported(path: String) -> Bool {
return false
}
open func propertiesOfFile(path: String, completionHandler: @escaping (([String : Any], [String], Error?) -> Void)) {
open func propertiesOfFile(path: String, completionHandler: @escaping (([String : Any], [String], Error?) -> Void)) -> Progress? {
dispatch_queue.async {
completionHandler([:], [], self.urlError(path, code: .resourceUnavailable))
}
return nil
}
}
@@ -629,7 +631,7 @@ public final class WebDavFileObject: FileObject {
public struct FileProviderWebDavError: FileProviderHTTPError {
public let code: FileProviderHTTPErrorCode
public let path: String
public let errorDescription: String?
public let serverDescription: String?
/// URL of resource caused error.
public let url: URL
}