diff --git a/FileProvider.podspec b/FileProvider.podspec index 473fe13..c4475eb 100644 --- a/FileProvider.podspec +++ b/FileProvider.podspec @@ -16,8 +16,8 @@ Pod::Spec.new do |s| # s.name = "FileProvider" - s.version = "0.6.0" - s.summary = "FileManager replacement for Local and Remote (WebDAV/Dropbox/SMB2) files on iOS and MacOS." + s.version = "0.6.1" + s.summary = "FileManager replacement for Local and Remote (WebDAV/Dropbox/SMB2) files on iOS and macOS." # This description is used to generate tags and improve search results. # * Think: What does it do? Why did you write it? What is the focus? @@ -26,8 +26,8 @@ Pod::Spec.new do |s| # * Finally, don't worry about the indent, CocoaPods strips it! s.description = <<-DESC This Swift library provide a swifty way to deal with local and remote files - and directories in same way. For now Local and WebDAV providers are ready to use - and SMB2, Dropbox, FTP and AmazonS3 is planned for future. + and directories in same way. For now Local, WebDAV and Dropbox providers are ready to use. + SMB2, FTP and AmazonS3 is planned for future. DESC s.homepage = "https://github.com/amosavian/FileProvider" diff --git a/FileProvider.xcodeproj/project.pbxproj b/FileProvider.xcodeproj/project.pbxproj index 7203ba2..aa662f9 100644 --- a/FileProvider.xcodeproj/project.pbxproj +++ b/FileProvider.xcodeproj/project.pbxproj @@ -218,9 +218,9 @@ 799396911D48C02300086753 /* Sources */ = { isa = PBXGroup; children = ( + 7924B18B1D89DAE000589DB7 /* AEXML */, 799396991D48C02300086753 /* SMBTypes */, 799396931D48C02300086753 /* DropboxFileProvider.swift */, - 7924B18B1D89DAE000589DB7 /* AEXML */, 794C21FD1D58912A00EC49B8 /* DropboxHelper.swift */, 799396941D48C02300086753 /* FileProvider.h */, 799396951D48C02300086753 /* FileProvider.swift */, @@ -513,7 +513,7 @@ 799396601D48B7BF00086753 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_VERSION_STRING = 0.6.0; + BUNDLE_VERSION_STRING = 0.6.1; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -524,6 +524,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -542,7 +543,7 @@ 799396611D48B7BF00086753 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_VERSION_STRING = 0.6.0; + BUNDLE_VERSION_STRING = 0.6.1; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -553,6 +554,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; diff --git a/Sources/DropboxFileProvider.swift b/Sources/DropboxFileProvider.swift index 16a2104..c2d48a4 100644 --- a/Sources/DropboxFileProvider.swift +++ b/Sources/DropboxFileProvider.swift @@ -64,20 +64,16 @@ open class DropboxFileProvider: NSObject, FileProviderBasic { let requestDictionary = ["path": correctPath(path)! as NSString] request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in + var dbError: FileProviderDropboxError? + var fileObject: DropboxFileObject? if let response = response as? HTTPURLResponse { - defer { - self.delegateNotify(.create(path: path), error: error) - } let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) - let dbError: FileProviderDropboxError? = code != nil ? FileProviderDropboxError(code: code!, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil + dbError = code != nil ? FileProviderDropboxError(code: code!, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr), let file = self.mapToFileObject(json) { - completionHandler(file, dbError) - return + fileObject = file } - completionHandler(nil, dbError) - return } - completionHandler(nil, error) + completionHandler(fileObject, dbError ?? error) }) task.resume() } @@ -88,13 +84,13 @@ open class DropboxFileProvider: NSObject, FileProviderBasic { request.httpMethod = "POST" request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") let task = session.dataTask(with: request, completionHandler: { (data, response, error) in + var totalSize: Int64 = -1 + var usedSize: Int64 = 0 if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr) { - let totalSize = ((json["allocation"] as? NSDictionary)?["allocated"] as? NSNumber)?.int64Value ?? -1 - let usedSize = (json["used"] as? NSNumber)?.int64Value ?? 0 - completionHandler(totalSize, usedSize) - return + totalSize = ((json["allocation"] as? NSDictionary)?["allocated"] as? NSNumber)?.int64Value ?? -1 + usedSize = (json["used"] as? NSNumber)?.int64Value ?? 0 } - completionHandler(-1, 0) + completionHandler(totalSize, usedSize) }) task.resume() } @@ -144,11 +140,11 @@ extension DropboxFileProvider: FileProviderOperations { url = "https://api.dropboxapi.com/2/files/move" fromPath = fp toPath = tp - case .modify(path: let p): - return nil case .remove(path: let p): url = "https://api.dropboxapi.com/2/files/delete" path = p + case .modify(path: _): + return nil case .link(link: _, target: _): return nil } @@ -162,19 +158,12 @@ extension DropboxFileProvider: FileProviderOperations { requestDictionary["to_path"] = correctPath(toPath) as NSString? request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in - if let response = response as? HTTPURLResponse { - let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) - let dbError: FileProviderDropboxError? = code != nil ? FileProviderDropboxError(code: code!, path: path ?? fromPath ?? "", errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil - defer { - self.delegateNotify(operation, error: error ?? dbError) - } - /*if let data = data, let jsonStr = String(data: data, encoding: NSUTF8StringEncoding) { - let json = self.jsonToDictionary(jsonStr) - }*/ - completionHandler?(dbError) - return + var dbError: FileProviderDropboxError? + if let response = response as? HTTPURLResponse, response.statusCode >= 300, let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) { + dbError = FileProviderDropboxError(code: code, path: path ?? fromPath ?? "", errorDescription: String(data: data ?? Data(), encoding: .utf8)) } - completionHandler?(error) + completionHandler?(dbError ?? error) + self.delegateNotify(operation, error: dbError ?? error) }) task.resume() return RemoteOperationHandle(tasks: [task]) @@ -240,14 +229,13 @@ extension DropboxFileProvider: FileProviderReadWrite { } let requestDictionary = ["path": path] request.setValue(dictionaryToJSON(requestDictionary as [String : AnyObject]), forHTTPHeaderField: "Dropbox-API-Arg") - let task = session.dataTask(with: request, completionHandler: { (datam, response, error) in - guard let data = datam, let httpResponse = response as? HTTPURLResponse , httpResponse.statusCode < 300 else { - let code = FileProviderHTTPErrorCode(rawValue: (response as? HTTPURLResponse)?.statusCode ?? -1) - let dbError: FileProviderDropboxError? = code != nil ? FileProviderDropboxError(code: code!, path: path, errorDescription: String(data: datam ?? Data(), encoding: .utf8)) : nil - completionHandler(nil, dbError ?? error) - return + let task = session.dataTask(with: request, completionHandler: { (data, response, error) in + var dbError: FileProviderDropboxError? + if let httpResponse = response as? HTTPURLResponse , httpResponse.statusCode >= 300, let code = FileProviderHTTPErrorCode(rawValue: httpResponse.statusCode) { + dbError = FileProviderDropboxError(code: code, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) } - completionHandler(data, error) + let filedata = dbError ?? error == nil ? data : nil + completionHandler(filedata, dbError ?? error) }) task.resume() return RemoteOperationHandle(tasks: [task]) diff --git a/Sources/DropboxHelper.swift b/Sources/DropboxHelper.swift index 2a30705..feff42d 100644 --- a/Sources/DropboxHelper.swift +++ b/Sources/DropboxHelper.swift @@ -53,13 +53,13 @@ internal extension DropboxFileProvider { request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var responseError: FileProviderDropboxError? + var files = prevContents if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderDropboxError(code: rCode, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) } if let data = data, let jsonStr = String(data: data, encoding: .utf8) { let json = jsonToDictionary(jsonStr) if let entries = json?["entries"] as? [AnyObject] , entries.count > 0 { - var files = prevContents for entry in entries { if let entry = entry as? [String: AnyObject], let file = self.mapToFileObject(entry) { files.append(file) @@ -69,13 +69,11 @@ internal extension DropboxFileProvider { let hasmore = (json?["has_more"] as? NSNumber)?.boolValue ?? false if hasmore { self.list(path, cursor: ncursor, prevContents: files, completionHandler: completionHandler) - } else { - completionHandler(files, ncursor, responseError ?? error) + return } - return } } - completionHandler([], nil, responseError ?? error) + completionHandler(files, nil, responseError ?? error) }) task.resume() } @@ -101,10 +99,8 @@ internal extension DropboxFileProvider { if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderDropboxError(code: rCode, path: targetPath, errorDescription: String(data: data ?? Data(), encoding: .utf8)) } - defer { - self.delegateNotify(.create(path: targetPath), error: responseError ?? error) - } completionHandler?(responseError ?? error) + self.delegateNotify(.create(path: targetPath), error: responseError ?? error) }) var dic: [String: AnyObject] = ["type": operation.description as NSString] switch operation { diff --git a/Sources/WebDAVFileProvider.swift b/Sources/WebDAVFileProvider.swift index af26e6d..d75501c 100644 --- a/Sources/WebDAVFileProvider.swift +++ b/Sources/WebDAVFileProvider.swift @@ -76,19 +76,17 @@ open class WebDAVFileProvider: NSObject, FileProviderBasic { if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderWebDavError(code: rCode, url: url) } + var fileObjects = [WebDavFileObject]() if let data = data { let xresponse = self.parseXMLResponse(data) - var fileObjects = [WebDavFileObject]() for attr in xresponse { if attr.href.path == url.path { continue } fileObjects.append(self.mapToFileObject(attr)) } - completionHandler(fileObjects, responseError ?? error) - return } - completionHandler([], responseError ?? error) + completionHandler(fileObjects, responseError ?? error) }) task.resume() } @@ -132,16 +130,16 @@ open class WebDAVFileProvider: NSObject, FileProviderBasic { request.httpBody = "\n\n\n".data(using: .utf8) request.setValue(String(request.httpBody!.count), forHTTPHeaderField: "Content-Length") let task = session.dataTask(with: request, completionHandler: { (data, response, error) in + var totalSize: Int64 = -1 + var usedSize: Int64 = 0 if let data = data { let xresponse = self.parseXMLResponse(data) if let attr = xresponse.first { - let totalSize = Int64(attr.prop["quota-available-bytes"] ?? "") - let usedSize = Int64(attr.prop["quota-used-bytes"] ?? "") - completionHandler(totalSize ?? -1, usedSize ?? 0) - return + totalSize = Int64(attr.prop["quota-available-bytes"] ?? "") ?? -1 + usedSize = Int64(attr.prop["quota-used-bytes"] ?? "") ?? 0 } } - completionHandler(-1, 0) + completionHandler(totalSize, usedSize) }) task.resume() } @@ -163,13 +161,9 @@ extension WebDAVFileProvider: FileProviderOperations { if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderWebDavError(code: rCode, url: url) } - if let response = response as? HTTPURLResponse, let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) , code != .ok { - completionHandler?(FileProviderWebDavError(code: code, url: url)) - return - } completionHandler?(responseError ?? error) self.delegateNotify(.create(path: (atPath as NSString).appendingPathComponent(folderName) + "/"), error: responseError ?? error) - }) + }) task.resume() return RemoteOperationHandle(tasks: [task]) } @@ -189,7 +183,7 @@ extension WebDAVFileProvider: FileProviderOperations { } completionHandler?(responseError ?? error) self.delegateNotify(.create(path: (path as NSString).appendingPathComponent(fileAttribs.name)), error: responseError ?? error) - }) + }) task.taskDescription = dictionaryToJSON(["type": "Create" as NSString, "source": (path as NSString).appendingPathComponent(fileAttribs.name) as NSString]) task.resume() return RemoteOperationHandle(tasks: [task]) @@ -224,23 +218,24 @@ extension WebDAVFileProvider: FileProviderOperations { request.setValue("F", forHTTPHeaderField: "Overwrite") } let task = session.dataTask(with: request, completionHandler: { (data, response, error) in + var responseError: FileProviderWebDavError? if let response = response as? HTTPURLResponse, let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) { - defer { - let op = move ? FileOperationType.move(source: path, destination: toPath) : .copy(source: path, destination: toPath) - self.delegateNotify(op, error: error) + if response.statusCode >= 300 { + responseError = FileProviderWebDavError(code: code, url: url) } if code == .multiStatus, let data = data { let xresponses = self.parseXMLResponse(data) for xresponse in xresponses where (xresponse.status ?? 0) >= 300 { completionHandler?(FileProviderWebDavError(code: code, url: url)) } - } else { - completionHandler?(FileProviderWebDavError(code: code, url: url)) } - return } - completionHandler?(error) - }) + if (response as? HTTPURLResponse)?.statusCode ?? 0 != FileProviderHTTPErrorCode.multiStatus.rawValue { + completionHandler?(responseError ?? error) + } + let op = move ? FileOperationType.move(source: path, destination: toPath) : .copy(source: path, destination: toPath) + self.delegateNotify(op, error: responseError ?? error) + }) task.resume() return RemoteOperationHandle(tasks: [task]) } @@ -254,22 +249,23 @@ extension WebDAVFileProvider: FileProviderOperations { var request = URLRequest(url: url) request.httpMethod = "DELETE" let task = session.dataTask(with: request, completionHandler: { (data, response, error) in + var responseError: FileProviderWebDavError? if let response = response as? HTTPURLResponse, let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) { - defer { - self.delegateNotify(.remove(path: path), error: error) + if response.statusCode >= 300 { + responseError = FileProviderWebDavError(code: code, url: url) } if code == .multiStatus, let data = data { let xresponses = self.parseXMLResponse(data) for xresponse in xresponses where (xresponse.status ?? 0) >= 300 { completionHandler?(FileProviderWebDavError(code: code, url: url)) } - } else { - completionHandler?(FileProviderWebDavError(code: code, url: url)) } - return } - completionHandler?(error) - }) + if (response as? HTTPURLResponse)?.statusCode ?? 0 != FileProviderHTTPErrorCode.multiStatus.rawValue { + completionHandler?(responseError ?? error) + } + self.delegateNotify(.remove(path: path), error: responseError ?? error) + }) task.resume() return RemoteOperationHandle(tasks: [task]) } @@ -288,7 +284,7 @@ extension WebDAVFileProvider: FileProviderOperations { responseError = FileProviderWebDavError(code: rCode, url: url) } completionHandler?(responseError ?? error) - self.delegateNotify(.move(source: localFile.absoluteString, destination: toPath), error: responseError ?? error) + self.delegateNotify(.copy(source: localFile.absoluteString, destination: toPath), error: responseError ?? error) }) task.taskDescription = dictionaryToJSON(["type": "Copy" as NSString, "source": localFile.absoluteString as NSString, "dest": toPath as NSString]) task.resume() @@ -316,6 +312,7 @@ extension WebDAVFileProvider: FileProviderOperations { } } completionHandler?(responseError ?? error) + self.delegateNotify(.copy(source: path, destination: toLocalURL.absoluteString), error: responseError ?? error) }) task.taskDescription = dictionaryToJSON(["type": "Copy" as NSString, "source": path as NSString, "dest": toLocalURL.absoluteString as NSString]) task.resume()