Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 057c9fd940 | |||
| 6d63322779 | |||
| fc6b46d17a |
+18
-1
@@ -1,10 +1,27 @@
|
||||
language: objective-c
|
||||
osx_image: xcode8
|
||||
xcode_project: FileProvider.xcodeproj
|
||||
env:
|
||||
global:
|
||||
- FRAMEWORK_NAME=FileProvider.framework
|
||||
before_install:
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
- brew update
|
||||
- brew outdated carthage || brew upgrade carthage
|
||||
script:
|
||||
- set pipefail
|
||||
- xcodebuild -version
|
||||
- xcodebuild -project FileProvider.xcodeproj -scheme "FileProvider OSX" -sdk macosx | xcpretty
|
||||
- xcodebuild -project FileProvider.xcodeproj -scheme "FileProvider iOS" -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO | xcpretty
|
||||
- xcodebuild -project FileProvider.xcodeproj -scheme "FileProvider tvOS" -sdk appletvsimulator ONLY_ACTIVE_ARCH=NO | xcpretty
|
||||
- pod lib lint --quick
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
before_deploy:
|
||||
- carthage build --no-skip-current
|
||||
- carthage archive FileProvider
|
||||
deploy:
|
||||
file: FileProvider.framework.zip
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
|
||||
#
|
||||
|
||||
s.name = "FileProvider"
|
||||
s.version = "0.5.1"
|
||||
s.version = "0.5.2"
|
||||
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.
|
||||
|
||||
@@ -520,6 +520,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -544,6 +545,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -601,7 +603,6 @@
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@@ -654,7 +655,6 @@
|
||||
PRODUCT_NAME = FileProvider;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[![Swift Version][swift-image]][swift-url]
|
||||
[![License][license-image]][license-url]
|
||||
[]()
|
||||
[]()
|
||||
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
[](https://cocoapods.org/pods/FileProvider)
|
||||
@@ -16,7 +16,7 @@
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
--->
|
||||
|
||||
This library provides implementaion of WebDav and SMB/CIFS (incomplete) and local files.
|
||||
This library provides implementaion of WebDav and SMB2 (incomplete) and local files.
|
||||
|
||||
All functions are async calls and it wont block your main thread.
|
||||
|
||||
|
||||
@@ -127,6 +127,9 @@ extension DropboxFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
fileprivate func doOperation(_ operation: FileOperation, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: operation) ?? true == true else {
|
||||
return
|
||||
}
|
||||
let url: String
|
||||
var path: String?, fromPath: String?, toPath: String?
|
||||
switch operation {
|
||||
@@ -177,15 +180,21 @@ extension DropboxFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
public func copyItem(localFile: URL, to toPath: String, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .copy(source: localFile.absoluteString, destination: toPath)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
guard let data = try? Data(contentsOf: localFile) else {
|
||||
let error = throwError(localFile.uw_absoluteString, code: URLError.fileDoesNotExist as FoundationErrorEnum)
|
||||
let error = throwError(localFile.absoluteString, code: URLError.fileDoesNotExist as FoundationErrorEnum)
|
||||
completionHandler?(error)
|
||||
return
|
||||
}
|
||||
upload_simple(toPath, data: data, overwrite: true, operation: .copy(source: localFile.uw_absoluteString, destination: toPath), completionHandler: completionHandler)
|
||||
upload_simple(toPath, data: data, overwrite: true, operation: .copy(source: localFile.absoluteString, destination: toPath), completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
public func copyItem(path: String, toLocalURL destURL: URL, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .copy(source: path, destination: destURL.absoluteString)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
let url = URL(string: "https://content.dropboxapi.com/2/files/download")!
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "GET"
|
||||
@@ -207,7 +216,7 @@ extension DropboxFileProvider: FileProviderOperations {
|
||||
completionHandler?(e)
|
||||
}
|
||||
})
|
||||
task.taskDescription = dictionaryToJSON(["type": "Copy" as NSString, "source": path as NSString, "dest": destURL.uw_absoluteString as NSString])
|
||||
task.taskDescription = dictionaryToJSON(["type": "Copy" as NSString, "source": path as NSString, "dest": destURL.absoluteString as NSString])
|
||||
task.resume()
|
||||
}
|
||||
}
|
||||
@@ -242,6 +251,9 @@ extension DropboxFileProvider: FileProviderReadWrite {
|
||||
}
|
||||
|
||||
public func writeContents(path: String, contents data: Data, atomically: Bool = false, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .modify(path: path)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
// FIXME: remove 150MB restriction
|
||||
upload_simple(path, data: data, overwrite: true, operation: .modify(path: path), completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
@@ -162,12 +162,12 @@ extension FileProviderBasic {
|
||||
rpath = self.currentPath
|
||||
}
|
||||
if isPathRelative, let baseURL = baseURL {
|
||||
if rpath.hasPrefix("/") && baseURL.uw_absoluteString.hasSuffix("/") {
|
||||
if rpath.hasPrefix("/") && baseURL.absoluteString.hasSuffix("/") {
|
||||
var npath = rpath
|
||||
npath.remove(at: npath.startIndex)
|
||||
return baseURL.uw_URLByAppendingPathComponent(npath)
|
||||
return baseURL.appendingPathComponent(npath)
|
||||
} else {
|
||||
return baseURL.uw_URLByAppendingPathComponent(rpath)
|
||||
return baseURL.appendingPathComponent(rpath)
|
||||
}
|
||||
} else {
|
||||
return URL(fileURLWithPath: rpath).standardizedFileURL
|
||||
@@ -175,8 +175,8 @@ extension FileProviderBasic {
|
||||
}
|
||||
|
||||
public func relativePathOf(url: URL) -> String {
|
||||
guard let baseURL = self.baseURL else { return url.uw_absoluteString }
|
||||
return url.standardizedFileURL.uw_absoluteString.replacingOccurrences(of: baseURL.uw_absoluteString, with: "/").removingPercentEncoding!
|
||||
guard let baseURL = self.baseURL else { return url.absoluteString }
|
||||
return url.standardizedFileURL.absoluteString.replacingOccurrences(of: baseURL.absoluteString, with: "/").removingPercentEncoding!
|
||||
}
|
||||
|
||||
internal func correctPath(_ path: String?) -> String? {
|
||||
@@ -233,7 +233,7 @@ extension FileProviderBasic {
|
||||
default:
|
||||
domain = NSCocoaErrorDomain
|
||||
}
|
||||
return NSError(domain: domain, code: code.rawValue, userInfo: [NSURLErrorFailingURLErrorKey: fileURL, NSURLErrorFailingURLStringErrorKey: fileURL.uw_absoluteString])
|
||||
return NSError(domain: domain, code: code.rawValue, userInfo: [NSURLErrorFailingURLErrorKey: fileURL, NSURLErrorFailingURLStringErrorKey: fileURL.absoluteString])
|
||||
}
|
||||
|
||||
internal func NotImplemented() {
|
||||
@@ -323,23 +323,7 @@ public protocol FileOperationDelegate: class {
|
||||
|
||||
internal extension URL {
|
||||
var uw_scheme: String {
|
||||
#if swift(>=2.3)
|
||||
return self.scheme ?? ""
|
||||
#else
|
||||
return self.scheme
|
||||
#endif
|
||||
}
|
||||
|
||||
var uw_absoluteString: String {
|
||||
return self.absoluteString
|
||||
}
|
||||
|
||||
func uw_URLByAppendingPathComponent(_ pathComponent: String) -> URL {
|
||||
return self.appendingPathComponent(pathComponent)
|
||||
}
|
||||
|
||||
func uw_URLByAppendingPathExtension(_ pathExtension: String) -> URL {
|
||||
return self.appendingPathExtension(pathExtension)
|
||||
return self.scheme ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor {
|
||||
@objc(createWithFolder:at:completionHandler:) open func create(folder folderName: String, at atPath: String, completionHandler: SimpleCompletionHandler) {
|
||||
operation_queue.async {
|
||||
do {
|
||||
try self.opFileManager.createDirectory(at: self.absoluteURL(atPath).uw_URLByAppendingPathComponent(folderName), withIntermediateDirectories: true, attributes: [:])
|
||||
try self.opFileManager.createDirectory(at: self.absoluteURL(atPath).appendingPathComponent(folderName), withIntermediateDirectories: true, attributes: [:])
|
||||
completionHandler?(nil)
|
||||
DispatchQueue.main.async(execute: {
|
||||
self.delegate?.fileproviderSucceed(self, operation: .create(path: (atPath as NSString).appendingPathComponent(folderName) + "/"))
|
||||
@@ -121,7 +121,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor {
|
||||
|
||||
open func create(file fileAttribs: FileObject, at atPath: String, contents data: Data?, completionHandler: SimpleCompletionHandler) {
|
||||
operation_queue.async {
|
||||
let fileURL = self.absoluteURL(atPath).uw_URLByAppendingPathComponent(fileAttribs.name)
|
||||
let fileURL = self.absoluteURL(atPath).appendingPathComponent(fileAttribs.name)
|
||||
var attributes = [String : Any]()
|
||||
if let createdDate = fileAttribs.createdDate {
|
||||
attributes[FileAttributeKey.creationDate.rawValue] = createdDate as NSDate
|
||||
@@ -217,12 +217,12 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor {
|
||||
try self.opFileManager.copyItem(at: localFile, to: self.absoluteURL(toPath))
|
||||
completionHandler?(nil)
|
||||
DispatchQueue.main.async(execute: {
|
||||
self.delegate?.fileproviderSucceed(self, operation: .copy(source: localFile.uw_absoluteString, destination: toPath))
|
||||
self.delegate?.fileproviderSucceed(self, operation: .copy(source: localFile.absoluteString, destination: toPath))
|
||||
})
|
||||
} catch let e as NSError {
|
||||
completionHandler?(e)
|
||||
DispatchQueue.main.async(execute: {
|
||||
self.delegate?.fileproviderFailed(self, operation: .copy(source: localFile.uw_absoluteString, destination: toPath))
|
||||
self.delegate?.fileproviderFailed(self, operation: .copy(source: localFile.absoluteString, destination: toPath))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -234,12 +234,12 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor {
|
||||
try self.opFileManager.copyItem(at: self.absoluteURL(path), to: toLocalURL)
|
||||
completionHandler?(nil)
|
||||
DispatchQueue.main.async(execute: {
|
||||
self.delegate?.fileproviderSucceed(self, operation: .copy(source: path, destination: toLocalURL.uw_absoluteString))
|
||||
self.delegate?.fileproviderSucceed(self, operation: .copy(source: path, destination: toLocalURL.absoluteString))
|
||||
})
|
||||
} catch let e as NSError {
|
||||
completionHandler?(e)
|
||||
DispatchQueue.main.async(execute: {
|
||||
self.delegate?.fileproviderFailed(self, operation: .copy(source: path, destination: toLocalURL.uw_absoluteString))
|
||||
self.delegate?.fileproviderFailed(self, operation: .copy(source: path, destination: toLocalURL.absoluteString))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,26 +7,6 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
fileprivate func < <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case let (l?, r?):
|
||||
return l < r
|
||||
case (nil, _?):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func >= <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case let (l?, r?):
|
||||
return l >= r
|
||||
default:
|
||||
return !(lhs < rhs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final class WebDavFileObject: FileObject {
|
||||
public let contentType: String
|
||||
@@ -171,6 +151,9 @@ open class WebDAVFileProvider: NSObject, FileProviderBasic {
|
||||
|
||||
extension WebDAVFileProvider: FileProviderOperations {
|
||||
public func create(folder folderName: String, at atPath: String, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .create(path: (atPath as NSString).appendingPathComponent(folderName) + "/")) ?? true == true else {
|
||||
return
|
||||
}
|
||||
let url = absoluteURL((atPath as NSString).appendingPathComponent(folderName) + "/")
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "MKCOL"
|
||||
@@ -190,6 +173,9 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
public func create(file fileAttribs: FileObject, at path: String, contents data: Data?, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .create(path: path)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
let url = absoluteURL(path)
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "PUT"
|
||||
@@ -206,10 +192,16 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
public func moveItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .move(source: path, destination: toPath)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
self.copyMoveItem(move: true, path: path, toPath: toPath, overwrite: overwrite, completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
public func copyItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .copy(source: path, destination: toPath)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
self.copyMoveItem(move: false, path: path, toPath: toPath, overwrite: overwrite, completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
@@ -221,7 +213,7 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
} else {
|
||||
request.httpMethod = "COPY"
|
||||
}
|
||||
request.setValue(absoluteURL(path).uw_absoluteString, forHTTPHeaderField: "Destination")
|
||||
request.setValue(absoluteURL(path).absoluteString, forHTTPHeaderField: "Destination")
|
||||
if !overwrite {
|
||||
request.setValue("F", forHTTPHeaderField: "Overwrite")
|
||||
}
|
||||
@@ -233,7 +225,7 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
}
|
||||
if code == .multiStatus, let data = data {
|
||||
let xresponses = self.parseXMLResponse(data)
|
||||
for xresponse in xresponses where xresponse.status >= 300 {
|
||||
for xresponse in xresponses where (xresponse.status ?? 0) >= 300 {
|
||||
completionHandler?(FileProviderWebDavError(code: code, url: url))
|
||||
}
|
||||
} else {
|
||||
@@ -247,6 +239,9 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
public func removeItem(path: String, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .remove(path: path)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
let url = absoluteURL(path)
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "DELETE"
|
||||
@@ -257,7 +252,7 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
}
|
||||
if code == .multiStatus, let data = data {
|
||||
let xresponses = self.parseXMLResponse(data)
|
||||
for xresponse in xresponses where xresponse.status >= 300 {
|
||||
for xresponse in xresponses where (xresponse.status ?? 0) >= 300 {
|
||||
completionHandler?(FileProviderWebDavError(code: code, url: url))
|
||||
}
|
||||
} else {
|
||||
@@ -271,6 +266,9 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
}
|
||||
|
||||
public func copyItem(localFile: URL, to toPath: String, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .copy(source: localFile.absoluteString, destination: toPath)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
let url = absoluteURL(toPath)
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "PUT"
|
||||
@@ -280,13 +278,16 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
responseError = FileProviderWebDavError(code: rCode, url: url)
|
||||
}
|
||||
completionHandler?(responseError ?? error)
|
||||
self.delegateNotify(.move(source: localFile.uw_absoluteString, destination: toPath), error: responseError ?? error)
|
||||
self.delegateNotify(.move(source: localFile.absoluteString, destination: toPath), error: responseError ?? error)
|
||||
})
|
||||
task.taskDescription = dictionaryToJSON(["type": "Copy" as NSString, "source": localFile.uw_absoluteString as NSString, "dest": toPath as NSString])
|
||||
task.taskDescription = dictionaryToJSON(["type": "Copy" as NSString, "source": localFile.absoluteString as NSString, "dest": toPath as NSString])
|
||||
task.resume()
|
||||
}
|
||||
|
||||
public func copyItem(path: String, toLocalURL: URL, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .copy(source: path, destination: toLocalURL.absoluteString)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
let url = absoluteURL(path)
|
||||
let request = URLRequest(url: url)
|
||||
let task = session.downloadTask(with: request, completionHandler: { (sourceFileURL, response, error) in
|
||||
@@ -304,7 +305,7 @@ extension WebDAVFileProvider: FileProviderOperations {
|
||||
}
|
||||
completionHandler?(responseError ?? error)
|
||||
})
|
||||
task.taskDescription = dictionaryToJSON(["type": "Copy" as NSString, "source": path as NSString, "dest": toLocalURL.uw_absoluteString as NSString])
|
||||
task.taskDescription = dictionaryToJSON(["type": "Copy" as NSString, "source": path as NSString, "dest": toLocalURL.absoluteString as NSString])
|
||||
task.resume()
|
||||
}
|
||||
}
|
||||
@@ -334,8 +335,11 @@ extension WebDAVFileProvider: FileProviderReadWrite {
|
||||
}
|
||||
|
||||
public func writeContents(path: String, contents data: Data, atomically: Bool = false, completionHandler: SimpleCompletionHandler) {
|
||||
guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: .modify(path: path)) ?? true == true else {
|
||||
return
|
||||
}
|
||||
// FIXME: lock destination before writing process
|
||||
let url = atomically ? absoluteURL(path).uw_URLByAppendingPathExtension("tmp") : absoluteURL(path)
|
||||
let url = atomically ? absoluteURL(path).appendingPathExtension("tmp") : absoluteURL(path)
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "PUT"
|
||||
let task = session.uploadTask(with: request, from: data, completionHandler: { (data, response, error) in
|
||||
|
||||
Reference in New Issue
Block a user