Commit 82686f86 authored by Roy Marmelstein's avatar Roy Marmelstein

Merge pull request #10 from jay18001/master

added NSProgress support
parents 5b0f8066 661c8509
...@@ -11,7 +11,7 @@ import Foundation ...@@ -11,7 +11,7 @@ import Foundation
extension Zip { extension Zip {
//MARK: Quick Unzip //MARK: Quick Unzip
/** /**
Quick unzip a file. Unzips to a new folder inside the app's documents folder with the zip file's name. Quick unzip a file. Unzips to a new folder inside the app's documents folder with the zip file's name.
...@@ -33,6 +33,8 @@ extension Zip { ...@@ -33,6 +33,8 @@ extension Zip {
- throws: Error if unzipping fails or if file is not found. Can be printed with a description variable. - throws: Error if unzipping fails or if file is not found. Can be printed with a description variable.
- notes: Supports implicit progress composition
- returns: NSURL of the destination folder. - returns: NSURL of the destination folder.
*/ */
public class func quickUnzipFile(path: NSURL, progress: ((progress: Double) -> ())?) throws -> NSURL { public class func quickUnzipFile(path: NSURL, progress: ((progress: Double) -> ())?) throws -> NSURL {
...@@ -50,30 +52,34 @@ extension Zip { ...@@ -50,30 +52,34 @@ extension Zip {
//MARK: Quick Zip //MARK: Quick Zip
/** /**
Quick zip files. Quick zip files.
- parameter paths: Array of NSURL filepaths. - parameter paths: Array of NSURL filepaths.
- parameter fileName: File name for the resulting zip file. - parameter fileName: File name for the resulting zip file.
- throws: Error if zipping fails. - throws: Error if zipping fails.
- returns: NSURL of the destination folder. - notes: Supports implicit progress composition
*/
- returns: NSURL of the destination folder.
*/
public class func quickZipFiles(paths: [NSURL], fileName: String) throws -> NSURL { public class func quickZipFiles(paths: [NSURL], fileName: String) throws -> NSURL {
return try quickZipFiles(paths, fileName: fileName, progress: nil) return try quickZipFiles(paths, fileName: fileName, progress: nil)
} }
/**
Quick zip files.
- parameter paths: Array of NSURL filepaths.
- parameter fileName: File name for the resulting zip file.
- parameter progress: A progress closure called after unzipping each file in the archive. Double value betweem 0 and 1.
- throws: Error if zipping fails.
- returns: NSURL of the destination folder. /**
*/ Quick zip files.
- parameter paths: Array of NSURL filepaths.
- parameter fileName: File name for the resulting zip file.
- parameter progress: A progress closure called after unzipping each file in the archive. Double value betweem 0 and 1.
- throws: Error if zipping fails.
- notes: Supports implicit progress composition
- returns: NSURL of the destination folder.
*/
public class func quickZipFiles(paths: [NSURL], fileName: String, progress: ((progress: Double) -> ())?) throws -> NSURL { public class func quickZipFiles(paths: [NSURL], fileName: String, progress: ((progress: Double) -> ())?) throws -> NSURL {
let fileManager = NSFileManager.defaultManager() let fileManager = NSFileManager.defaultManager()
let documentsUrl = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL let documentsUrl = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
...@@ -82,5 +88,5 @@ extension Zip { ...@@ -82,5 +88,5 @@ extension Zip {
return destinationUrl return destinationUrl
} }
} }
\ No newline at end of file
...@@ -17,7 +17,7 @@ public enum ZipError: ErrorType { ...@@ -17,7 +17,7 @@ public enum ZipError: ErrorType {
case UnzipFail case UnzipFail
/// Zip fail /// Zip fail
case ZipFail case ZipFail
/// User readable description /// User readable description
public var description: String { public var description: String {
switch self { switch self {
...@@ -42,7 +42,7 @@ public class Zip { ...@@ -42,7 +42,7 @@ public class Zip {
} }
// MARK: Unzip // MARK: Unzip
/** /**
Unzip file Unzip file
...@@ -51,15 +51,17 @@ public class Zip { ...@@ -51,15 +51,17 @@ public class Zip {
- parameter overwrite: Overwrite bool. - parameter overwrite: Overwrite bool.
- parameter password: Optional password if file is protected. - parameter password: Optional password if file is protected.
- parameter progress: A progress closure called after unzipping each file in the archive. Double value betweem 0 and 1. - parameter progress: A progress closure called after unzipping each file in the archive. Double value betweem 0 and 1.
- throws: Error if unzipping fails or if fail is not found. Can be printed with a description variable. - throws: Error if unzipping fails or if fail is not found. Can be printed with a description variable.
- notes: Supports implicit progress composition
*/ */
public class func unzipFile(zipFilePath: NSURL, destination: NSURL, overwrite: Bool, password: String?, progress: ((progress: Double) -> ())?) throws { public class func unzipFile(zipFilePath: NSURL, destination: NSURL, overwrite: Bool, password: String?, progress: ((progress: Double) -> ())?) throws {
// File manager // File manager
let fileManager = NSFileManager.defaultManager() let fileManager = NSFileManager.defaultManager()
// Check whether a zip file exists at path. // Check whether a zip file exists at path.
guard let path = zipFilePath.path where destination.path != nil else { guard let path = zipFilePath.path where destination.path != nil else {
throw ZipError.FileNotFound throw ZipError.FileNotFound
...@@ -81,7 +83,12 @@ public class Zip { ...@@ -81,7 +83,12 @@ public class Zip {
if let attributeFileSize = fileAttributes[NSFileSize] as? Double { if let attributeFileSize = fileAttributes[NSFileSize] as? Double {
totalSize += attributeFileSize totalSize += attributeFileSize
} }
let progressTracker = NSProgress(totalUnitCount: Int64(totalSize))
progressTracker.cancellable = false
progressTracker.pausable = false
progressTracker.kind = NSProgressKindFile
// Begin unzipping // Begin unzipping
let zip = unzOpen64(path) let zip = unzOpen64(path)
if unzGoToFirstFile(zip) != UNZ_OK { if unzGoToFirstFile(zip) != UNZ_OK {
...@@ -165,27 +172,33 @@ public class Zip { ...@@ -165,27 +172,33 @@ public class Zip {
progressHandler(progress: (currentPosition/totalSize)) progressHandler(progress: (currentPosition/totalSize))
} }
progressTracker.completedUnitCount = Int64(currentPosition)
} while (ret == UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE) } while (ret == UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE)
// Completed. Update progress handler. // Completed. Update progress handler.
if let progressHandler = progress{ if let progressHandler = progress{
progressHandler(progress: 1.0) progressHandler(progress: 1.0)
} }
progressTracker.completedUnitCount = Int64(totalSize)
} }
// MARK: Zip // MARK: Zip
/** /**
Zip files. Zip files.
- parameter paths: Array of NSURL filepaths. - parameter paths: Array of NSURL filepaths.
- parameter zipFilePath: Destination NSURL, should lead to a .zip filepath. - parameter zipFilePath: Destination NSURL, should lead to a .zip filepath.
- parameter password: Password string. Optional. - parameter password: Password string. Optional.
- parameter progress: A progress closure called after unzipping each file in the archive. Double value betweem 0 and 1. - parameter progress: A progress closure called after unzipping each file in the archive. Double value betweem 0 and 1.
- throws: Error if zipping fails. - throws: Error if zipping fails.
*/
- notes: Supports implicit progress composition
*/
public class func zipFiles(paths: [NSURL], zipFilePath: NSURL, password: String?, progress: ((progress: Double) -> ())?) throws { public class func zipFiles(paths: [NSURL], zipFilePath: NSURL, password: String?, progress: ((progress: Double) -> ())?) throws {
// File manager // File manager
...@@ -218,6 +231,11 @@ public class Zip { ...@@ -218,6 +231,11 @@ public class Zip {
catch {} catch {}
} }
let progressTracker = NSProgress(totalUnitCount: Int64(totalSize))
progressTracker.cancellable = false
progressTracker.pausable = false
progressTracker.kind = NSProgressKindFile
// Begin Zipping // Begin Zipping
let zip = zipOpen(destinationPath, APPEND_STATUS_CREATE) let zip = zipOpen(destinationPath, APPEND_STATUS_CREATE)
for path in processedPaths { for path in processedPaths {
...@@ -268,6 +286,8 @@ public class Zip { ...@@ -268,6 +286,8 @@ public class Zip {
progressHandler(progress: (currentPosition/totalSize)) progressHandler(progress: (currentPosition/totalSize))
} }
progressTracker.completedUnitCount = Int64(currentPosition)
zipCloseFileInZip(zip) zipCloseFileInZip(zip)
free(buffer) free(buffer)
fclose(input) fclose(input)
...@@ -279,8 +299,10 @@ public class Zip { ...@@ -279,8 +299,10 @@ public class Zip {
if let progressHandler = progress{ if let progressHandler = progress{
progressHandler(progress: 1.0) progressHandler(progress: 1.0)
} }
progressTracker.completedUnitCount = Int64(totalSize)
} }
} }
\ No newline at end of file
...@@ -43,7 +43,7 @@ class ZipTests: XCTestCase { ...@@ -43,7 +43,7 @@ class ZipTests: XCTestCase {
XCTAssert(true) XCTAssert(true)
} }
} }
func testQuickUnzipNonZipPath() { func testQuickUnzipNonZipPath() {
do { do {
let filePath = NSBundle(forClass: ZipTests.self).URLForResource("3crBXeO", withExtension: "gif")! let filePath = NSBundle(forClass: ZipTests.self).URLForResource("3crBXeO", withExtension: "gif")!
...@@ -84,9 +84,11 @@ class ZipTests: XCTestCase { ...@@ -84,9 +84,11 @@ class ZipTests: XCTestCase {
do { do {
let filePath = NSBundle(forClass: ZipTests.self).URLForResource("bb8", withExtension: "zip")! let filePath = NSBundle(forClass: ZipTests.self).URLForResource("bb8", withExtension: "zip")!
let documentsFolder = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL let documentsFolder = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
try Zip.unzipFile(filePath, destination: documentsFolder, overwrite: true, password: "password", progress: { (progress) -> () in try Zip.unzipFile(filePath, destination: documentsFolder, overwrite: true, password: "password", progress: { (progress) -> () in
print(progress) print(progress)
}) })
let fileManager = NSFileManager.defaultManager() let fileManager = NSFileManager.defaultManager()
XCTAssertTrue(fileManager.fileExistsAtPath(documentsFolder.path!)) XCTAssertTrue(fileManager.fileExistsAtPath(documentsFolder.path!))
} }
...@@ -95,6 +97,48 @@ class ZipTests: XCTestCase { ...@@ -95,6 +97,48 @@ class ZipTests: XCTestCase {
} }
} }
func testImplicitProgressUnzip() {
do {
let progress = NSProgress()
progress.totalUnitCount = 1
let filePath = NSBundle(forClass: ZipTests.self).URLForResource("bb8", withExtension: "zip")!
let documentsFolder = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
progress.becomeCurrentWithPendingUnitCount(1)
try Zip.unzipFile(filePath, destination: documentsFolder, overwrite: true, password: "password", progress: nil)
progress.resignCurrent()
XCTAssertTrue(progress.totalUnitCount == progress.completedUnitCount)
}
catch {
XCTFail()
}
}
func testImplicitProgressZip() {
do {
let progress = NSProgress()
progress.totalUnitCount = 1
let imageURL1 = NSBundle(forClass: ZipTests.self).URLForResource("3crBXeO", withExtension: "gif")!
let imageURL2 = NSBundle(forClass: ZipTests.self).URLForResource("kYkLkPf", withExtension: "gif")!
let documentsFolder = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
let zipFilePath = documentsFolder.URLByAppendingPathComponent("archive.zip")
progress.becomeCurrentWithPendingUnitCount(1)
try Zip.zipFiles([imageURL1, imageURL2], zipFilePath: zipFilePath, password: nil, progress: nil)
progress.resignCurrent()
XCTAssertTrue(progress.totalUnitCount == progress.completedUnitCount)
}
catch {
XCTFail()
}
}
func testQuickZip() { func testQuickZip() {
do { do {
let imageURL1 = NSBundle(forClass: ZipTests.self).URLForResource("3crBXeO", withExtension: "gif")! let imageURL1 = NSBundle(forClass: ZipTests.self).URLForResource("3crBXeO", withExtension: "gif")!
...@@ -129,7 +173,7 @@ class ZipTests: XCTestCase { ...@@ -129,7 +173,7 @@ class ZipTests: XCTestCase {
XCTFail() XCTFail()
} }
} }
func testZip() { func testZip() {
do { do {
...@@ -164,6 +208,6 @@ class ZipTests: XCTestCase { ...@@ -164,6 +208,6 @@ class ZipTests: XCTestCase {
XCTFail() XCTFail()
} }
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment