Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ff5e13931f | |||
| 75af738d2e | |||
| f54a1253e4 | |||
| 1394a92662 |
+1
-1
@@ -56,7 +56,7 @@ script:
|
||||
after_success:
|
||||
# Run `pod trunk push` if specified
|
||||
- if [ $POD == "YES" ] && [ -n "$TRAVIS_TAG" ]; then
|
||||
pod trunk push;
|
||||
pod trunk push --allow-warnings;
|
||||
fi
|
||||
|
||||
# - bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
|
||||
#
|
||||
|
||||
s.name = "FileProvider"
|
||||
s.version = "0.15.2"
|
||||
s.version = "0.15.3"
|
||||
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.
|
||||
@@ -58,7 +58,7 @@ Pod::Spec.new do |s|
|
||||
s.author = { "Amir Abbas Mousavian" => "a.mosavian@gmail.com" }
|
||||
# Or just: s.author = "Amir Abbas Mousavian"
|
||||
# s.authors = { "Amir Abbas Mousavian" => "a.mosavian@gmail.com" }
|
||||
s.social_media_url = "https://twitter.com/amosavian"
|
||||
# s.social_media_url = "https://twitter.com/amosavian"
|
||||
|
||||
# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
|
||||
#
|
||||
|
||||
@@ -116,9 +116,9 @@
|
||||
79BD63BE1E2CC3C20035128C /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79BD63BD1E2CC3C20035128C /* ImageIO.framework */; };
|
||||
79BD63C01E2CC3CD0035128C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79BD63BF1E2CC3CD0035128C /* CoreGraphics.framework */; };
|
||||
79BD63C21E2CC3D30035128C /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79BD63C11E2CC3D30035128C /* AVFoundation.framework */; };
|
||||
79BD63C51E2D17880035128C /* OneDriveFileProvide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C31E2D17880035128C /* OneDriveFileProvide.swift */; };
|
||||
79BD63C61E2D17880035128C /* OneDriveFileProvide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C31E2D17880035128C /* OneDriveFileProvide.swift */; };
|
||||
79BD63C71E2D17880035128C /* OneDriveFileProvide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C31E2D17880035128C /* OneDriveFileProvide.swift */; };
|
||||
79BD63C51E2D17880035128C /* OneDriveFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C31E2D17880035128C /* OneDriveFileProvider.swift */; };
|
||||
79BD63C61E2D17880035128C /* OneDriveFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C31E2D17880035128C /* OneDriveFileProvider.swift */; };
|
||||
79BD63C71E2D17880035128C /* OneDriveFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C31E2D17880035128C /* OneDriveFileProvider.swift */; };
|
||||
79BD63C81E2D17880035128C /* OneDriveHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C41E2D17880035128C /* OneDriveHelper.swift */; };
|
||||
79BD63C91E2D17880035128C /* OneDriveHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C41E2D17880035128C /* OneDriveHelper.swift */; };
|
||||
79BD63CA1E2D17880035128C /* OneDriveHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD63C41E2D17880035128C /* OneDriveHelper.swift */; };
|
||||
@@ -182,7 +182,7 @@
|
||||
79BD63BD1E2CC3C20035128C /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.1.sdk/System/Library/Frameworks/ImageIO.framework; sourceTree = DEVELOPER_DIR; };
|
||||
79BD63BF1E2CC3CD0035128C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.1.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
|
||||
79BD63C11E2CC3D30035128C /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.1.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
79BD63C31E2D17880035128C /* OneDriveFileProvide.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OneDriveFileProvide.swift; sourceTree = "<group>"; };
|
||||
79BD63C31E2D17880035128C /* OneDriveFileProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OneDriveFileProvider.swift; sourceTree = "<group>"; };
|
||||
79BD63C41E2D17880035128C /* OneDriveHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OneDriveHelper.swift; sourceTree = "<group>"; };
|
||||
79F5745A1DFDB10A00179ABF /* FileObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileObject.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -304,7 +304,7 @@
|
||||
794C21FD1D58912A00EC49B8 /* DropboxHelper.swift */,
|
||||
7936BC111E880F5700A6C81C /* FTPFileProvider.swift */,
|
||||
798654321E8874BC002FA550 /* FTPHelper.swift */,
|
||||
79BD63C31E2D17880035128C /* OneDriveFileProvide.swift */,
|
||||
79BD63C31E2D17880035128C /* OneDriveFileProvider.swift */,
|
||||
79BD63C41E2D17880035128C /* OneDriveHelper.swift */,
|
||||
7924B1A81D89F79200589DB7 /* FPSStreamTask.swift */,
|
||||
799396971D48C02300086753 /* SMBClient.swift */,
|
||||
@@ -498,7 +498,7 @@
|
||||
7936BC121E880F5700A6C81C /* FTPFileProvider.swift in Sources */,
|
||||
79480FF61E3ABDD0007E7275 /* CloudFileProvider.swift in Sources */,
|
||||
79F5745B1DFDB10B00179ABF /* FileObject.swift in Sources */,
|
||||
79BD63C51E2D17880035128C /* OneDriveFileProvide.swift in Sources */,
|
||||
79BD63C51E2D17880035128C /* OneDriveFileProvider.swift in Sources */,
|
||||
7924B1991D89DAE000589DB7 /* Element.swift in Sources */,
|
||||
799396C81D48C02300086753 /* SMB2IOCtl.swift in Sources */,
|
||||
799396D71D48C02300086753 /* SMB2Types.swift in Sources */,
|
||||
@@ -541,7 +541,7 @@
|
||||
7936BC131E880F5700A6C81C /* FTPFileProvider.swift in Sources */,
|
||||
79480FF71E3ABDD0007E7275 /* CloudFileProvider.swift in Sources */,
|
||||
79F5745C1DFDB10B00179ABF /* FileObject.swift in Sources */,
|
||||
79BD63C61E2D17880035128C /* OneDriveFileProvide.swift in Sources */,
|
||||
79BD63C61E2D17880035128C /* OneDriveFileProvider.swift in Sources */,
|
||||
7924B1B01D89F7DE00589DB7 /* FPSStreamTask.swift in Sources */,
|
||||
7924B19A1D89DAE000589DB7 /* Element.swift in Sources */,
|
||||
799396C91D48C02300086753 /* SMB2IOCtl.swift in Sources */,
|
||||
@@ -584,7 +584,7 @@
|
||||
7936BC141E880F5700A6C81C /* FTPFileProvider.swift in Sources */,
|
||||
79480FF81E3ABDD0007E7275 /* CloudFileProvider.swift in Sources */,
|
||||
79F5745D1DFDB10B00179ABF /* FileObject.swift in Sources */,
|
||||
79BD63C71E2D17880035128C /* OneDriveFileProvide.swift in Sources */,
|
||||
79BD63C71E2D17880035128C /* OneDriveFileProvider.swift in Sources */,
|
||||
7924B1B11D89F7DF00589DB7 /* FPSStreamTask.swift in Sources */,
|
||||
7924B19B1D89DAE000589DB7 /* Element.swift in Sources */,
|
||||
799396CA1D48C02300086753 /* SMB2IOCtl.swift in Sources */,
|
||||
@@ -621,7 +621,7 @@
|
||||
799396601D48B7BF00086753 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_VERSION_STRING = 0.15.2;
|
||||
BUNDLE_VERSION_STRING = 0.15.3;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -631,6 +631,7 @@
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@@ -651,7 +652,7 @@
|
||||
799396611D48B7BF00086753 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_VERSION_STRING = 0.15.2;
|
||||
BUNDLE_VERSION_STRING = 0.15.3;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
||||
@@ -717,8 +717,11 @@ public enum UbiquitousScope: RawRepresentable {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get progress of CloudFileProvider operations
|
||||
open class CloudOperationHandle: OperationHandle {
|
||||
/// Url of file which operation is doing on
|
||||
public let baseURL: URL?
|
||||
/// Type of operation
|
||||
public let operationType: FileOperationType
|
||||
|
||||
init (operationType: FileOperationType, baseURL: URL?) {
|
||||
|
||||
@@ -48,7 +48,7 @@ open class DropboxFileProvider: FileProviderBasicRemote {
|
||||
public var session: URLSession {
|
||||
get {
|
||||
if _session == nil {
|
||||
self.sessionDelegate = SessionDelegate(fileProvider: self, credential: credential)
|
||||
self.sessionDelegate = SessionDelegate(fileProvider: self)
|
||||
let config = URLSessionConfiguration.default
|
||||
config.urlCache = cache
|
||||
config.requestCachePolicy = .returnCacheDataElseLoad
|
||||
@@ -65,6 +65,7 @@ open class DropboxFileProvider: FileProviderBasicRemote {
|
||||
if session.sessionDescription?.isEmpty ?? true {
|
||||
_session?.sessionDescription = UUID().uuidString
|
||||
}
|
||||
self.sessionDelegate = newValue.delegate as? SessionDelegate
|
||||
initEmptySessionHandler(_session!.sessionDescription!)
|
||||
}
|
||||
}
|
||||
@@ -295,6 +296,14 @@ extension DropboxFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
open func copyItem(localFile: URL, to toPath: String, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> OperationHandle? {
|
||||
// check file is not a folder
|
||||
guard (try? localFile.resourceValues(forKeys: [.fileResourceTypeKey]))?.fileResourceType ?? .unknown == .regular else {
|
||||
dispatch_queue.async {
|
||||
completionHandler?(self.throwError(localFile.path, code: URLError.fileIsDirectory))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
let opType = FileOperationType.copy(source: localFile.absoluteString, destination: toPath)
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else {
|
||||
return nil
|
||||
|
||||
@@ -47,7 +47,7 @@ open class FTPFileProvider: FileProviderBasicRemote {
|
||||
public var session: URLSession {
|
||||
get {
|
||||
if _session == nil {
|
||||
self.sessionDelegate = SessionDelegate(fileProvider: self, credential: credential)
|
||||
self.sessionDelegate = SessionDelegate(fileProvider: self)
|
||||
let config = URLSessionConfiguration.default
|
||||
config.urlCache = cache
|
||||
config.requestCachePolicy = .returnCacheDataElseLoad
|
||||
@@ -64,6 +64,7 @@ open class FTPFileProvider: FileProviderBasicRemote {
|
||||
if session.sessionDescription?.isEmpty ?? true {
|
||||
_session?.sessionDescription = UUID().uuidString
|
||||
}
|
||||
self.sessionDelegate = newValue.delegate as? SessionDelegate
|
||||
initEmptySessionHandler(_session!.sessionDescription!)
|
||||
}
|
||||
}
|
||||
@@ -230,9 +231,8 @@ open class FTPFileProvider: FileProviderBasicRemote {
|
||||
}
|
||||
|
||||
guard let response = response, response.hasPrefix("250") || (response.hasPrefix("50") && rfc3659enabled) else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
self.dispatch_queue.async {
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError(path, code: URLError.badServerResponse))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -243,9 +243,8 @@ open class FTPFileProvider: FileProviderBasicRemote {
|
||||
|
||||
let lines = response.components(separatedBy: "\n").flatMap { $0.isEmpty ? nil : $0.trimmingCharacters(in: .whitespacesAndNewlines) }
|
||||
guard lines.count > 2 else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
self.dispatch_queue.async {
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError(path, code: URLError.badServerResponse))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -347,10 +346,9 @@ extension FTPFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
self.dispatch_queue.async {
|
||||
completionHandler?(error)
|
||||
self.delegateNotify(opType, error: error)
|
||||
self.delegateNotify(opType, error: self.throwError(sourcePath, code: URLError.badServerResponse))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -382,9 +380,7 @@ extension FTPFileProvider: FileProviderOperations {
|
||||
default:
|
||||
errorCode = URLError.cannotOpenFile
|
||||
}
|
||||
let escapedPath = sourcePath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? sourcePath
|
||||
let url = NSURL(string: escapedPath, relativeTo: self.baseURL) ?? self.baseURL! as NSURL
|
||||
let error = NSError(domain: URLError.errorDomain, code: errorCode.rawValue, userInfo: [NSURLErrorFailingURLErrorKey: url])
|
||||
let error = self.throwError(sourcePath, code: errorCode)
|
||||
self.dispatch_queue.async {
|
||||
completionHandler?(error)
|
||||
self.delegateNotify(opType, error: error)
|
||||
@@ -442,7 +438,7 @@ extension FTPFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
let error = self.throwError(sourcePath, code: URLError.badServerResponse)
|
||||
self.dispatch_queue.async {
|
||||
completionHandler?(error)
|
||||
self.delegateNotify(opType, error: error)
|
||||
@@ -455,9 +451,7 @@ extension FTPFileProvider: FileProviderOperations {
|
||||
return
|
||||
}
|
||||
|
||||
let escapedPath = sourcePath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? sourcePath
|
||||
let url = NSURL(string: escapedPath, relativeTo: self.baseURL) ?? self.baseURL! as NSURL
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.cannotRemoveFile.rawValue, userInfo: [NSURLErrorFailingURLErrorKey: url])
|
||||
let error = self.throwError(sourcePath, code: URLError.cannotRemoveFile)
|
||||
self.dispatch_queue.async {
|
||||
completionHandler?(error)
|
||||
self.delegateNotify(opType, error: error)
|
||||
@@ -468,6 +462,14 @@ extension FTPFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
open func copyItem(localFile: URL, to toPath: String, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> OperationHandle? {
|
||||
// check file is not a folder
|
||||
guard (try? localFile.resourceValues(forKeys: [.fileResourceTypeKey]))?.fileResourceType ?? .unknown == .regular else {
|
||||
dispatch_queue.async {
|
||||
completionHandler?(self.throwError(localFile.path, code: URLError.fileIsDirectory))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
let opType = FileOperationType.copy(source: localFile.absoluteString, destination: toPath)
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else {
|
||||
return nil
|
||||
|
||||
+22
-42
@@ -69,8 +69,7 @@ extension FTPFileProvider {
|
||||
if let data = data, let response = String(data: data, encoding: .utf8) {
|
||||
completionHandler(response.trimmingCharacters(in: CharacterSet(charactersIn: FTPFileProvider.carriage)), nil)
|
||||
} else {
|
||||
let badResponseError = NSError(domain: URLError.errorDomain, code: URLError.cannotParseResponse.rawValue, userInfo: nil)
|
||||
completionHandler(nil, badResponseError)
|
||||
completionHandler(nil, self.throwError("", code: URLError.cannotParseResponse))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -92,8 +91,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let data = data, let response = String(data: data, encoding: .utf8) else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.cannotParseResponse.rawValue, userInfo: nil)
|
||||
completionHandler(error)
|
||||
completionHandler(self.throwError("", code: URLError.cannotParseResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -114,8 +112,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler(error)
|
||||
completionHandler(self.throwError("", code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -131,8 +128,7 @@ extension FTPFileProvider {
|
||||
if response?.hasPrefix("2") ?? false {
|
||||
completionHandler(nil)
|
||||
} else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.userAuthenticationRequired.rawValue, userInfo: nil)
|
||||
completionHandler(error)
|
||||
completionHandler(self.throwError("", code: URLError.userAuthenticationRequired))
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -166,8 +162,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler(error)
|
||||
completionHandler(self.throwError(path, code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -200,15 +195,13 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let response = response, let destString = response.components(separatedBy: " ").flatMap({ $0 }).last else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError("", code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
let destArray = destString.components(separatedBy: ",").flatMap({ UInt32(trimmedNumber($0)) })
|
||||
guard destArray.count == 6 else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError("", code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -239,14 +232,12 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError("", code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
guard !response.hasPrefix("5") else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.cannotConnectToHost.rawValue, userInfo: nil)
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError("", code: URLError.cannotConnectToHost))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -296,8 +287,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let dataTask = dataTask else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler([], error)
|
||||
completionHandler([], self.throwError(path, code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -329,15 +319,13 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
if waitResult == .timedOut {
|
||||
error = NSError(domain: URLError.errorDomain, code: URLError.timedOut.rawValue, userInfo: nil)
|
||||
completionHandler([], error)
|
||||
completionHandler([], self.throwError(path, code: URLError.timedOut))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
guard let response = String(data: finalData, encoding: .utf8) else {
|
||||
error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler([], error)
|
||||
completionHandler([], self.throwError(path, code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -353,8 +341,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let badResponseError = NSError(domain: URLError.errorDomain, code: URLError.cannotParseResponse.rawValue, userInfo: nil)
|
||||
completionHandler([], badResponseError)
|
||||
completionHandler([], self.throwError(path, code: URLError.cannotParseResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -402,8 +389,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let dataTask = dataTask else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError(filePath, code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -440,8 +426,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
if waitResult == .timedOut {
|
||||
error = NSError(domain: URLError.errorDomain, code: URLError.timedOut.rawValue, userInfo: nil)
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError(filePath, code: URLError.timedOut))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -463,8 +448,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let badResponseError = NSError(domain: URLError.errorDomain, code: URLError.cannotParseResponse.rawValue, userInfo: nil)
|
||||
completionHandler(nil, badResponseError)
|
||||
completionHandler(nil, self.throwError(filePath, code: URLError.cannotParseResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -511,8 +495,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let dataTask = dataTask else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler(nil, error)
|
||||
completionHandler(nil, self.throwError(filePath, code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -549,7 +532,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
if waitResult == .timedOut {
|
||||
error = NSError(domain: URLError.errorDomain, code: URLError.timedOut.rawValue, userInfo: nil)
|
||||
error = self.throwError("", code: URLError.timedOut)
|
||||
completionHandler(nil, error)
|
||||
return
|
||||
}
|
||||
@@ -580,8 +563,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let badResponseError = NSError(domain: URLError.errorDomain, code: URLError.cannotParseResponse.rawValue, userInfo: nil)
|
||||
completionHandler(nil, badResponseError)
|
||||
completionHandler(nil, self.throwError(filePath, code: URLError.cannotParseResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -610,8 +592,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let dataTask = dataTask else {
|
||||
let error = NSError(domain: URLError.errorDomain, code: URLError.badServerResponse.rawValue, userInfo: nil)
|
||||
completionHandler(error)
|
||||
completionHandler(self.throwError(filePath, code: URLError.badServerResponse))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -658,7 +639,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
if waitResult == .timedOut {
|
||||
error = NSError(domain: URLError.errorDomain, code: URLError.timedOut.rawValue, userInfo: nil)
|
||||
error = self.throwError(filePath, code: URLError.timedOut)
|
||||
completionHandler(error)
|
||||
return
|
||||
}
|
||||
@@ -674,8 +655,7 @@ extension FTPFileProvider {
|
||||
}
|
||||
|
||||
guard let response = response else {
|
||||
let badResponseError = NSError(domain: URLError.errorDomain, code: URLError.cannotParseResponse.rawValue, userInfo: nil)
|
||||
completionHandler(badResponseError)
|
||||
completionHandler(self.throwError(filePath, code: URLError.cannotParseResponse))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -939,6 +939,8 @@ public enum FileOperationType: CustomStringConvertible {
|
||||
}
|
||||
let dest = json["dest"] as? String
|
||||
switch type {
|
||||
case "Fetch":
|
||||
self = .fetch(path: source)
|
||||
case "Create":
|
||||
self = .create(path: source)
|
||||
case "Modify":
|
||||
|
||||
@@ -216,9 +216,11 @@ internal class LocalFileProviderManagerDelegate: NSObject, FileManagerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
/// Local operation handling is limited. Please don't use as much as possible.
|
||||
/// - Note: Local operation handling is limited. Please don't use as much as possible.
|
||||
open class LocalOperationHandle: OperationHandle {
|
||||
/// Url of file which operation is doing on
|
||||
public let baseURL: URL
|
||||
/// Type of operation
|
||||
public let operationType: FileOperationType
|
||||
|
||||
init (operationType: FileOperationType, baseURL: URL?) {
|
||||
|
||||
@@ -47,7 +47,7 @@ open class OneDriveFileProvider: FileProviderBasicRemote {
|
||||
public var session: URLSession {
|
||||
get {
|
||||
if _session == nil {
|
||||
self.sessionDelegate = SessionDelegate(fileProvider: self, credential: credential)
|
||||
self.sessionDelegate = SessionDelegate(fileProvider: self)
|
||||
let queue = OperationQueue()
|
||||
//queue.underlyingQueue = dispatch_queue
|
||||
let config = URLSessionConfiguration.default
|
||||
@@ -66,6 +66,7 @@ open class OneDriveFileProvider: FileProviderBasicRemote {
|
||||
if session.sessionDescription?.isEmpty ?? true {
|
||||
_session?.sessionDescription = UUID().uuidString
|
||||
}
|
||||
self.sessionDelegate = newValue.delegate as? SessionDelegate
|
||||
initEmptySessionHandler(_session!.sessionDescription!)
|
||||
}
|
||||
}
|
||||
@@ -300,6 +301,14 @@ extension OneDriveFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
open func copyItem(localFile: URL, to toPath: String, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> OperationHandle? {
|
||||
// check file is not a folder
|
||||
guard (try? localFile.resourceValues(forKeys: [.fileResourceTypeKey]))?.fileResourceType ?? .unknown == .regular else {
|
||||
dispatch_queue.async {
|
||||
completionHandler?(self.throwError(localFile.path, code: URLError.fileIsDirectory))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
let opType = FileOperationType.copy(source: localFile.absoluteString, destination: toPath)
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else {
|
||||
return nil
|
||||
@@ -101,9 +101,9 @@ internal func initEmptySessionHandler(_ uuid: String) {
|
||||
}
|
||||
|
||||
internal func removeSessionHandler(for uuid: String) {
|
||||
completionHandlersForTasks.removeValue(forKey: uuid)
|
||||
downloadCompletionHandlersForTasks.removeValue(forKey: uuid)
|
||||
dataCompletionHandlersForTasks.removeValue(forKey: uuid)
|
||||
_ = completionHandlersForTasks.removeValue(forKey: uuid)
|
||||
_ = downloadCompletionHandlersForTasks.removeValue(forKey: uuid)
|
||||
_ = dataCompletionHandlersForTasks.removeValue(forKey: uuid)
|
||||
}
|
||||
|
||||
/// All objects set to `FileProviderRemote.session` must be an instance of this class
|
||||
@@ -121,9 +121,9 @@ final public class SessionDelegate: NSObject, URLSessionDataDelegate, URLSession
|
||||
/// Forwardng URLSessionStreamTaskDelegate call
|
||||
public var didBecomeStream :((_ session: URLSession, _ taskId: Int, _ didBecome: InputStream, _ outputStream: OutputStream) -> Void)?
|
||||
|
||||
init(fileProvider: FileProviderBasicRemote & FileProviderOperations, credential: URLCredential?) {
|
||||
public init(fileProvider: FileProviderBasicRemote & FileProviderOperations) {
|
||||
self.fileProvider = fileProvider
|
||||
self.credential = credential
|
||||
self.credential = fileProvider.credential
|
||||
}
|
||||
|
||||
// codebeat:disable[ARITY]
|
||||
@@ -131,7 +131,7 @@ final public class SessionDelegate: NSObject, URLSessionDataDelegate, URLSession
|
||||
if !(error == nil && task is URLSessionDownloadTask) {
|
||||
let completionHandler = completionHandlersForTasks[session.sessionDescription!]?[task.taskIdentifier] ?? nil
|
||||
completionHandler?(error)
|
||||
completionHandlersForTasks[session.sessionDescription!]?.removeValue(forKey: task.taskIdentifier)
|
||||
_ = completionHandlersForTasks[session.sessionDescription!]?.removeValue(forKey: task.taskIdentifier)
|
||||
}
|
||||
|
||||
guard let json = task.taskDescription?.deserializeJSON(),
|
||||
@@ -139,6 +139,9 @@ final public class SessionDelegate: NSObject, URLSessionDataDelegate, URLSession
|
||||
return
|
||||
}
|
||||
|
||||
if !(task is URLSessionDownloadTask), case FileOperationType.fetch = op {
|
||||
return
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
if error != nil {
|
||||
fileProvider.delegate?.fileproviderFailed(fileProvider, operation: op)
|
||||
@@ -151,7 +154,7 @@ final public class SessionDelegate: NSObject, URLSessionDataDelegate, URLSession
|
||||
public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
|
||||
let completionHandler = dataCompletionHandlersForTasks[session.sessionDescription!]?[dataTask.taskIdentifier] ?? nil
|
||||
completionHandler?(data)
|
||||
dataCompletionHandlersForTasks[session.sessionDescription!]?.removeValue(forKey: dataTask.taskIdentifier)
|
||||
_ = dataCompletionHandlersForTasks[session.sessionDescription!]?.removeValue(forKey: dataTask.taskIdentifier)
|
||||
}
|
||||
|
||||
public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
|
||||
@@ -159,8 +162,8 @@ final public class SessionDelegate: NSObject, URLSessionDataDelegate, URLSession
|
||||
|
||||
let dcompletionHandler = downloadCompletionHandlersForTasks[session.sessionDescription!]?[downloadTask.taskIdentifier]
|
||||
dcompletionHandler?(location)
|
||||
downloadCompletionHandlersForTasks[session.sessionDescription!]?.removeValue(forKey: downloadTask.taskIdentifier)
|
||||
completionHandlersForTasks[session.sessionDescription!]?.removeValue(forKey: downloadTask.taskIdentifier)
|
||||
_ = downloadCompletionHandlersForTasks[session.sessionDescription!]?.removeValue(forKey: downloadTask.taskIdentifier)
|
||||
_ = completionHandlersForTasks[session.sessionDescription!]?.removeValue(forKey: downloadTask.taskIdentifier)
|
||||
}
|
||||
|
||||
public func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
|
||||
@@ -171,6 +174,15 @@ final public class SessionDelegate: NSObject, URLSessionDataDelegate, URLSession
|
||||
return
|
||||
}
|
||||
|
||||
switch op {
|
||||
case .create(path: let path):
|
||||
if path.hasSuffix("/") { return }
|
||||
case .modify:
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
+10
-10
@@ -11,11 +11,11 @@ import Foundation
|
||||
// This client implementation is for little-endian platform, namely x86, x64 & arm
|
||||
// For big-endian platforms like PowerPC, there must be a huge overhaul
|
||||
|
||||
protocol SMBProtocolClientDelegate: class {
|
||||
func receivedResponse(client: SMB2ProtocolClient, response: SMBResponse, for: SMBRequest)
|
||||
protocol FileProviderSMBTaskDelegate: class {
|
||||
func receivedResponse(client: FileProviderSMBTask, response: SMBResponse, for: SMBRequest)
|
||||
}
|
||||
|
||||
class SMB2ProtocolClient: FileProviderStreamTask {
|
||||
class FileProviderSMBTask: FileProviderStreamTask {
|
||||
var timeout: TimeInterval = 30
|
||||
|
||||
private(set) var lastMessageID: UInt64 = 0
|
||||
@@ -31,14 +31,14 @@ class SMB2ProtocolClient: FileProviderStreamTask {
|
||||
private(set) var requestStack = [Int: SMBRequest]()
|
||||
private(set) var responseStack = [Int: SMBResponse]()
|
||||
|
||||
weak var delegate: SMBProtocolClientDelegate?
|
||||
weak var delegate: FileProviderSMBTaskDelegate?
|
||||
|
||||
func sendNegotiate(completionHandler: SimpleCompletionHandler) -> UInt64 {
|
||||
let mId = messageId()
|
||||
let smbHeader = SMB2.Header(command: .NEGOTIATE, creditRequestResponse: UInt16(126), messageId: mId, treeId: UInt32(0), sessionId: UInt64(0))
|
||||
let msg = SMB2.NegotiateRequest()
|
||||
let data = createSMB2Message(header: smbHeader, message: msg)
|
||||
self.write(data, timeout: 0, completionHandler: { (e) in
|
||||
self.write(data, timeout: timeout, completionHandler: { (e) in
|
||||
completionHandler?(e)
|
||||
})
|
||||
return mId
|
||||
@@ -50,7 +50,7 @@ class SMB2ProtocolClient: FileProviderStreamTask {
|
||||
let smbHeader = SMB2.Header(command: SMB2.Command.SESSION_SETUP, creditRequestResponse: credit, messageId: mId, treeId: UInt32(0), sessionId: sessionId)
|
||||
let msg = SMB2.SessionSetupRequest(singing: [])
|
||||
let data = createSMB2Message(header: smbHeader, message: msg)
|
||||
self.write(data, timeout: 0, completionHandler: { (e) in
|
||||
self.write(data, timeout: timeout, completionHandler: { (e) in
|
||||
if self.sessionId == 0 {
|
||||
self.readData(ofMinLength: 64, maxLength: 65536, timeout: self.timeout, completionHandler: { (data, eof, e2) in
|
||||
// TODO: set session id
|
||||
@@ -73,7 +73,7 @@ class SMB2ProtocolClient: FileProviderStreamTask {
|
||||
let tcHeader = SMB2.TreeConnectRequest.Header(flags: [])
|
||||
let msg = SMB2.TreeConnectRequest(header: tcHeader, host: host, share: share)
|
||||
let data = createSMB2Message(header: smbHeader, message: msg!)
|
||||
self.write(data, timeout: 0, completionHandler: { (e) in
|
||||
self.write(data, timeout: timeout, completionHandler: { (e) in
|
||||
completionHandler?(e)
|
||||
|
||||
})
|
||||
@@ -85,7 +85,7 @@ class SMB2ProtocolClient: FileProviderStreamTask {
|
||||
let smbHeader = SMB2.Header(command: .TREE_DISCONNECT, creditRequestResponse: 111, messageId: mId, treeId: treeId, sessionId: sessionId)
|
||||
let msg = SMB2.TreeDisconnect()
|
||||
let data = createSMB2Message(header: smbHeader, message: msg)
|
||||
self.write(data, timeout: 0, completionHandler: { (e) in
|
||||
self.write(data, timeout: timeout, completionHandler: { (e) in
|
||||
completionHandler?(e)
|
||||
})
|
||||
return mId
|
||||
@@ -96,7 +96,7 @@ class SMB2ProtocolClient: FileProviderStreamTask {
|
||||
let smbHeader = SMB2.Header(command: .LOGOFF, creditRequestResponse: 0, messageId: mId, treeId: 0, sessionId: sessionId)
|
||||
let msg = SMB2.LogOff()
|
||||
let data = createSMB2Message(header: smbHeader, message: msg)
|
||||
self.write(data, timeout: 0, completionHandler: { (e) in
|
||||
self.write(data, timeout: timeout, completionHandler: { (e) in
|
||||
completionHandler?(e)
|
||||
})
|
||||
return mId
|
||||
@@ -108,7 +108,7 @@ class SMB2ProtocolClient: FileProviderStreamTask {
|
||||
}
|
||||
|
||||
// MARK: create and analyse messages
|
||||
extension SMB2ProtocolClient {
|
||||
extension FileProviderSMBTask {
|
||||
func determineSMBVersion(_ data: Data) -> Float {
|
||||
let smbverChar: Int8 = Int8(bitPattern: data.first ?? 0)
|
||||
let version = 0 - smbverChar
|
||||
|
||||
@@ -46,7 +46,7 @@ open class WebDAVFileProvider: FileProviderBasicRemote {
|
||||
public var session: URLSession {
|
||||
get {
|
||||
if _session == nil {
|
||||
self.sessionDelegate = SessionDelegate(fileProvider: self, credential: credential)
|
||||
self.sessionDelegate = SessionDelegate(fileProvider: self)
|
||||
let queue = OperationQueue()
|
||||
//queue.underlyingQueue = dispatch_queue
|
||||
let config = URLSessionConfiguration.default
|
||||
@@ -65,6 +65,7 @@ open class WebDAVFileProvider: FileProviderBasicRemote {
|
||||
if session.sessionDescription?.isEmpty ?? true {
|
||||
_session?.sessionDescription = UUID().uuidString
|
||||
}
|
||||
self.sessionDelegate = newValue.delegate as? SessionDelegate
|
||||
initEmptySessionHandler(_session!.sessionDescription!)
|
||||
}
|
||||
}
|
||||
@@ -392,6 +393,14 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
|
||||
@discardableResult
|
||||
open func copyItem(localFile: URL, to toPath: String, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> OperationHandle? {
|
||||
// check file is not a folder
|
||||
guard (try? localFile.resourceValues(forKeys: [.fileResourceTypeKey]))?.fileResourceType ?? .unknown == .regular else {
|
||||
dispatch_queue.async {
|
||||
completionHandler?(self.throwError(localFile.path, code: URLError.fileIsDirectory))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
let opType = FileOperationType.copy(source: localFile.absoluteString, destination: toPath)
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else {
|
||||
return nil
|
||||
@@ -487,6 +496,8 @@ extension WebDAVFileProvider: FileProviderReadWrite {
|
||||
completionHandler(nil, e)
|
||||
}
|
||||
}
|
||||
task.taskDescription = opType.json
|
||||
task.resume()
|
||||
return handle
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user