Commit 1d615e93 authored by Roy Marmelstein's avatar Roy Marmelstein

Improving type safety, clearer variables

parent 075fc96f
...@@ -74,7 +74,7 @@ extension Zip { ...@@ -74,7 +74,7 @@ extension Zip {
*/ */
public func quickZipFiles(paths: [NSURL], fileName: String, progress: ((progress: Double) -> ())?) throws -> NSURL { public func quickZipFiles(paths: [NSURL], fileName: String, progress: ((progress: Double) -> ())?) throws -> NSURL {
let destinationUrl = documentsUrl.URLByAppendingPathComponent("\(fileName).zip") let destinationUrl = documentsUrl.URLByAppendingPathComponent("\(fileName).zip")
try self.zipFiles(paths, destination: destinationUrl, password: nil, progress: progress) try self.zipFiles(paths, zipFilePath: destinationUrl, password: nil, progress: progress)
return destinationUrl return destinationUrl
} }
......
...@@ -28,6 +28,9 @@ public enum ZipError: ErrorType { ...@@ -28,6 +28,9 @@ public enum ZipError: ErrorType {
public class Zip { public class Zip {
// File manager
let fileManager = NSFileManager.defaultManager()
// Documents folder // Documents folder
let documentsUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL let documentsUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
...@@ -46,31 +49,41 @@ public class Zip { ...@@ -46,31 +49,41 @@ public class Zip {
/** /**
Unzip file Unzip file
- parameter path: Path of zipped file. NSURL. - parameter zipFilePath: Local file path of zipped file. NSURL.
- parameter destination: Path to unzip to. NSURL. - parameter destination: Local file path to unzip to. NSURL.
- 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.
*/ */
public func unzipFile(path: NSURL, destination: NSURL, overwrite: Bool, password: String?, progress: ((progress: Double) -> ())?) throws {
public func unzipFile(zipFilePath: NSURL, destination: NSURL, overwrite: Bool, password: String?, progress: ((progress: Double) -> ())?) throws {
// Check whether a zip file exists at path. // Check whether a zip file exists at path.
let fileManager = NSFileManager.defaultManager() guard let path = zipFilePath.path, let destinationPath = destination.path else {
if fileManager.fileExistsAtPath(path.path!) == false || path.pathExtension != "zip" { throw ZipError.FileNotFound
}
if fileManager.fileExistsAtPath(path) == false || zipFilePath.pathExtension != "zip" {
throw ZipError.FileNotFound throw ZipError.FileNotFound
} }
// Unzip set up // Unzip set up
var ret: Int32 = 0 var ret: Int32 = 0
var crc_ret: Int32 = 0 var crc_ret: Int32 = 0
let bufferSize: UInt32 = 4096 let bufferSize: UInt32 = 4096
var buffer = Array<CUnsignedChar>(count: Int(bufferSize), repeatedValue: 0) var buffer = Array<CUnsignedChar>(count: Int(bufferSize), repeatedValue: 0)
// Begin unzipping
let zip = unzOpen64(path.path!)
let fileAttributes = try fileManager.attributesOfItemAtPath(path.path!) // Progress handler set up
let totalSize = fileAttributes[NSFileSize] as? Double var totalSize: Double = 0.0
var currentPosition: Double = 0.0 var currentPosition: Double = 0.0
let fileAttributes = try fileManager.attributesOfItemAtPath(path)
if let attributeFileSize = fileAttributes[NSFileSize] as? Double {
totalSize += attributeFileSize
}
// Begin unzipping
let zip = unzOpen64(path)
if unzGoToFirstFile(zip) != UNZ_OK { if unzGoToFirstFile(zip) != UNZ_OK {
throw ZipError.UnzipFail throw ZipError.UnzipFail
} }
...@@ -104,7 +117,7 @@ public class Zip { ...@@ -104,7 +117,7 @@ public class Zip {
} }
var isDirectory = false var isDirectory = false
let fileInfoSizeFileName = Int(fileInfo.size_filename-1) let fileInfoSizeFileName = Int(fileInfo.size_filename-1)
if (fileName[fileInfoSizeFileName] == "/".cStringUsingEncoding(NSUTF8StringEncoding)!.first! || fileName[fileInfoSizeFileName] == "\\".cStringUsingEncoding(NSUTF8StringEncoding)!.first!) { if (fileName[fileInfoSizeFileName] == "/".cStringUsingEncoding(NSUTF8StringEncoding)?.first || fileName[fileInfoSizeFileName] == "\\".cStringUsingEncoding(NSUTF8StringEncoding)?.first) {
isDirectory = true; isDirectory = true;
} }
free(fileName) free(fileName)
...@@ -121,7 +134,7 @@ public class Zip { ...@@ -121,7 +134,7 @@ public class Zip {
try fileManager.createDirectoryAtPath(fullPath, withIntermediateDirectories: true, attributes: directoryAttributes) try fileManager.createDirectoryAtPath(fullPath, withIntermediateDirectories: true, attributes: directoryAttributes)
} }
else { else {
try fileManager.createDirectoryAtPath(destination.path!, withIntermediateDirectories: true, attributes: directoryAttributes) try fileManager.createDirectoryAtPath(destinationPath, withIntermediateDirectories: true, attributes: directoryAttributes)
} }
} catch {} } catch {}
if fileManager.fileExistsAtPath(fullPath) && !isDirectory && !overwrite { if fileManager.fileExistsAtPath(fullPath) && !isDirectory && !overwrite {
...@@ -144,11 +157,16 @@ public class Zip { ...@@ -144,11 +157,16 @@ public class Zip {
if crc_ret == UNZ_CRCERROR { if crc_ret == UNZ_CRCERROR {
throw ZipError.UnzipFail throw ZipError.UnzipFail
} }
if let progressHandler = progress, let totalSize = totalSize{ ret = unzGoToNextFile(zip)
// Update progress handler
if let progressHandler = progress{
progressHandler(progress: (currentPosition/totalSize)) progressHandler(progress: (currentPosition/totalSize))
} }
ret = unzGoToNextFile(zip)
} 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.
if let progressHandler = progress{ if let progressHandler = progress{
progressHandler(progress: 1.0) progressHandler(progress: 1.0)
} }
...@@ -161,41 +179,53 @@ public class Zip { ...@@ -161,41 +179,53 @@ public class Zip {
Zip files. Zip files.
- parameter paths: Array of NSURL filepaths. - parameter paths: Array of NSURL filepaths.
- parameter destination: 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.
*/ */
public func zipFiles(paths: [NSURL], destination: NSURL, password: String?, progress: ((progress: Double) -> ())?) throws { public func zipFiles(paths: [NSURL], zipFilePath: NSURL, password: String?, progress: ((progress: Double) -> ())?) throws {
// Check whether a zip file exists at path.
guard let destinationPath = zipFilePath.path else {
throw ZipError.FileNotFound
}
// Zip set up
let chunkSize: Int = 16384 let chunkSize: Int = 16384
let fileManager = NSFileManager.defaultManager()
// Progress handler set up
var currentPosition: Double = 0.0 var currentPosition: Double = 0.0
var totalSize: Double = 0.0 var totalSize: Double = 0.0
// Check if paths exist and get totalSize for progress handler // Get totalSize for progress handler
for path in paths { for path in paths {
if fileManager.fileExistsAtPath(path.path!) == false {
throw ZipError.FileNotFound
}
do { do {
let fileAttributes = try fileManager.attributesOfItemAtPath(path.path!) if let filePath = path.path {
let fileSize = fileAttributes[NSFileSize] as? Double let fileAttributes = try fileManager.attributesOfItemAtPath(filePath)
if let fileSize = fileSize { let fileSize = fileAttributes[NSFileSize] as? Double
totalSize += fileSize if let fileSize = fileSize {
totalSize += fileSize
}
} }
} }
catch {} catch {}
} }
let zip = zipOpen(destination.path!, APPEND_STATUS_CREATE)
// Begin Zipping
let zip = zipOpen(destinationPath, APPEND_STATUS_CREATE)
for path in paths { for path in paths {
let input = fopen(path.path!, "r") guard let filePath = path.path else {
throw ZipError.ZipFail
}
let input = fopen(filePath, "r")
if input == nil { if input == nil {
throw ZipError.ZipFail throw ZipError.ZipFail
} }
let fileName = path.lastPathComponent let fileName = path.lastPathComponent
var zipInfo: zip_fileinfo = zip_fileinfo(tmz_date: tm_zip(tm_sec: 0, tm_min: 0, tm_hour: 0, tm_mday: 0, tm_mon: 0, tm_year: 0), dosDate: 0, internal_fa: 0, external_fa: 0) var zipInfo: zip_fileinfo = zip_fileinfo(tmz_date: tm_zip(tm_sec: 0, tm_min: 0, tm_hour: 0, tm_mday: 0, tm_mon: 0, tm_year: 0), dosDate: 0, internal_fa: 0, external_fa: 0)
do { do {
let fileAttributes = try fileManager.attributesOfItemAtPath(path.path!) let fileAttributes = try fileManager.attributesOfItemAtPath(filePath)
if let fileDate = fileAttributes[NSFileModificationDate] as? NSDate { if let fileDate = fileAttributes[NSFileModificationDate] as? NSDate {
let components = NSCalendar.currentCalendar().components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: fileDate) let components = NSCalendar.currentCalendar().components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: fileDate)
zipInfo.tmz_date.tm_sec = UInt32(components.second) zipInfo.tmz_date.tm_sec = UInt32(components.second)
...@@ -225,14 +255,23 @@ public class Zip { ...@@ -225,14 +255,23 @@ public class Zip {
length = fread(buffer, 1, chunkSize, input) length = fread(buffer, 1, chunkSize, input)
zipWriteInFileInZip(zip, buffer, UInt32(length)) zipWriteInFileInZip(zip, buffer, UInt32(length))
} }
// Update progress handler
if let progressHandler = progress{ if let progressHandler = progress{
progressHandler(progress: (currentPosition/totalSize)) progressHandler(progress: (currentPosition/totalSize))
} }
zipCloseFileInZip(zip) zipCloseFileInZip(zip)
free(buffer) free(buffer)
fclose(input) fclose(input)
} }
zipClose(zip, nil); zipClose(zip, nil)
// Completed. Update progress handler.
if let progressHandler = progress{
progressHandler(progress: 1.0)
}
} }
......
...@@ -68,6 +68,19 @@ class ZipTests: XCTestCase { ...@@ -68,6 +68,19 @@ class ZipTests: XCTestCase {
} }
} }
func testUnzipOnlineURL() {
do {
let fileAbsoluteURL = NSURL(string: "http://www.google.com/google.zip")!
let destinationURL = try Zip().quickUnzipFile(fileAbsoluteURL)
let fileManager = NSFileManager.defaultManager()
XCTAssertFalse(fileManager.fileExistsAtPath(destinationURL.path!))
}
catch {
XCTAssert(true)
}
}
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")!
......
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