Compare commits

...

3 Commits

Author SHA1 Message Date
Amir Abbas Mousavian 057c9fd940 Update podspec to 0.5.2 2016-09-30 14:08:25 +03:30
Amir Abbas Mousavian 6d63322779 FileProviderOperationDelegate methods will call for WebDav and Dropbox providers
- Added Carthage to Travis
2016-09-30 14:07:02 +03:30
Amir Abbas Mousavian fc6b46d17a Updated swift 3 semantics 2016-09-28 19:15:05 +03:30
8 changed files with 82 additions and 65 deletions
+18 -1
View File
@@ -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
+1 -1
View File
@@ -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.
+2 -2
View File
@@ -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";
+2 -2
View File
@@ -4,7 +4,7 @@
[![Swift Version][swift-image]][swift-url]
[![License][license-image]][license-url]
[![Platform](https://img.shields.io/badge/Platform-iOS%2C%20macOS-lightgray.svg)]()
[![Platform](https://img.shields.io/badge/Platform-iOS%2C%20macOS%2C%20tvOS-lightgray.svg)]()
[![Build Status][travis-image]][travis-url]
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/FileProvider.svg)](https://cocoapods.org/pods/FileProvider)
@@ -16,7 +16,7 @@
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](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.
+15 -3
View File
@@ -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)
}
+7 -23
View File
@@ -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 ?? ""
}
}
+6 -6
View File
@@ -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))
})
}
}
+31 -27
View File
@@ -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