diff --git a/Objective-Zip.xcodeproj/project.pbxproj b/Objective-Zip.xcodeproj/project.pbxproj index b37a9f4..558d22f 100755 --- a/Objective-Zip.xcodeproj/project.pbxproj +++ b/Objective-Zip.xcodeproj/project.pbxproj @@ -91,7 +91,6 @@ /* Begin PBXFileReference section */ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 8C14E8181773A09F00B84597 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; - 8C1D598B1771057D006D69C3 /* GETTING_STARTED.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GETTING_STARTED.md; sourceTree = ""; }; 8C1D598C1771057D006D69C3 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; 8C6D352410E56A9000B63EFA /* crypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crypt.h; path = MiniZip/crypt.h; sourceTree = ""; }; 8C6D352510E56A9000B63EFA /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ioapi.c; path = MiniZip/ioapi.c; sourceTree = ""; }; @@ -212,7 +211,6 @@ 8CC2FC661B91E63E00D5E05F /* Objective-Zip Tests */, 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, - 8C1D598B1771057D006D69C3 /* GETTING_STARTED.md */, 8C1D598C1771057D006D69C3 /* README.md */, ); name = CustomTemplate; diff --git a/README.md b/README.md index 06e038f..8edff06 100644 --- a/README.md +++ b/README.md @@ -29,19 +29,241 @@ informations. Getting started ---------------- +=============== + +Objective-Zip exposes basic functionalities to read and write zip files, +encapsulating both ZLib for the compression mechanism and MiniZip for +the zip wrapping. + + +Adding Objective-Zip to your project +------------------------------------ + +The library is distributed via CocoaPods, you can add a dependency in you pod +file with the following line: + +pod 'Objective-Zip', '~> 1.0' + +You can then access Objective-Zip classes with the following import +statement if you plan to use exception handling: + +```objective-c +#import "Objective-Zip.h" +``` + +Alternatively you can use the following import statement if you plan to use +Apple's NSError pattern: + +```objective-c +#import "Objective-Zip+NSError.h" +``` + +More on error handling at the end of this document. + + +Main concepts +------------- + +Objective-Zip is centered on a class called (with a lack of fantasy) +OZZipFile. It can be created with the common Objective-C procedure of an +alloc followed by an init, specifying in the latter if the zip file is +being created, appended or unzipped: + +```objective-c +OZZipFile *zipFile= [[OZZipFile alloc] initWithFileName:@"test.zip" + mode:OZZipFileModeCreate]; +``` + +Creating and appending are both write-only modalities, while unzipping +is a read-only modality. You can not request reading operations on a +write-mode zip file, nor request writing operations on a read-mode zip +file. + + +Adding a file to a zip file +--------------------------- + +The ZipFile class has a couple of methods to add new files to a zip +file, one of which keeps the file in clear and the other encrypts it +with a password. Both methods return an instance of a OZZipWriteStream +class, which will be used solely for the scope of writing the content of +the file, and then must be closed: + +```objective-c +OZZipWriteStream *stream= [zipFile writeFileInZipWithName:@"abc.txt" + compressionLevel:OZZipCompressionLevelBest]; + +[stream writeData:abcData]; +[stream finishedWriting]; +``` + + +Reading a file from a zip file +------------------------------ + +The OZZipFile class, when used in unzip mode, must be treated like a +cursor: you position the instance on a file at a time, either by +step-forwarding or by locating the file by name. Once you are on the +correct file, you can obtain an instance of a OZZipReadStream that will +let you read the content (and then must be closed): + +```objective-c +OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:@"test.zip" + mode:OZZipFileModeUnzip]; + +[unzipFile goToFirstFileInZip]; + +OZZipReadStream *read= [unzipFile readCurrentFileInZip]; +NSMutableData *data= [[NSMutableData alloc] initWithLength:256]; +int bytesRead= [read readDataWithBuffer:data]; + +[read finishedReading]; +``` + +Note that the NSMutableData instance that acts as the read buffer must +have been set with a length greater than 0: the readDataWithBuffer API +will use that length to know how many bytes it can fetch from the zip +file. + + +Listing files in a zip file +--------------------------- + +When the ZipFile class is used in unzip mode, it can also list the files +contained in zip by filling an NSArray with instances of FileInZipInfo +class. You can then use its name property to locate the file inside the +zip and expand it: + +```objective-c +OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:@"test.zip" + mode:ZipFileModeUnzip]; + +NSArray *infos= [unzipFile listFileInZipInfos]; +for (OZFileInZipInfo *info in infos) { + NSLog(@"- %@ %@ %d (%d)", info.name, info.date, info.size, + info.level); + + // Locate the file in the zip + [unzipFile locateFileInZip:info.name]; + + // Expand the file in memory + OZZipReadStream *read= [unzipFile readCurrentFileInZip]; + NSMutableData *data= [[NSMutableData alloc] initWithLength:256]; + int bytesRead= [read readDataWithBuffer:data]; + [read finishedReading]; +} +``` + +Note that the OZFileInZipInfo class provide two sizes: + +- **length** is the original (uncompressed) file size, while +- **size** is the compressed file size. + + +Closing the zip file +-------------------- + +Remember, when you are done, to close your OZZipFile instance to avoid +file corruption problems: + +```objective-c +[zipFile close]; +``` + + +File/folder hierarchy inide the zip +----------------------------------- + +Please note that inside the zip files there is no representation of a +file-folder hierarchy: it is simply embedded in file names (i.e.: a file +with a name like "x/y/z/file.txt"). It is up to the program that +extracts files to consider these file names as expressing a structure and +rebuild it on the file system (and viceversa during creation). Common +zippers/unzippers simply follow this rule. + + +Memory management +----------------- + +If you need to extract huge files that cannot be contained in memory, +you can do so using a read-then-write buffered loop like this: + +```objective-c +NSFileHandle *file= [NSFileHandle fileHandleForWritingAtPath:filePath]; +NSMutableData *buffer= [[NSMutableData alloc] + initWithLength:BUFFER_SIZE]; + +OZZipReadStream *read= [unzipFile readCurrentFileInZip]; + +// Read-then-write buffered loop +do { + + // Reset buffer length + [buffer setLength:BUFFER_SIZE]; + + // Expand next chunk of bytes + int bytesRead= [read readDataWithBuffer:buffer]; + if (bytesRead > 0) { + + // Write what we have read + [buffer setLength:bytesRead]; + [file writeData:buffer]; + + } else + break; + +} while (YES); + +// Clean up +[file closeFile]; +[read finishedReading]; +[buffer release]; +``` + + +Error handling +-------------- + +Objective-Zip provides two kinds of error handling: + +- standard exception handling; +- Apple's NSError pattern. + +With standard exception handling, Objective-Zip will throw an exception of +class OZZipException any time an error occurs (programmer or runtime errors). + +To use standard exception handling import Objective-Zip in your project with +this statement: + +```objective-c +#import "Objective-Zip.h" +``` + +With Apple's NSError pattern, Objective-Zip will expect a NSError +pointer-to-pointer argument and will fill it with an NSError instance +whenever a runtime error occurs. Will revert to throwing an exception (of +OZZipException class) in case of programmer errors. + +To use Apple's NSError pattern import Objective-Zip in your project with this +statement: + +```objective-c +#import "Objective-Zip+NSError.h" +``` + +Apple's NSError pattern is of course mandatory with Swift programming +language, since it does not support exception handling. -Please see [Getting Started](https://github.com/gianlucabertani/Objective-Zip/blob/master/GETTING_STARTED.md). License -------- +======= The library is distributed under the New BSD License. Version history ---------------- +=============== Version 1.0.0: @@ -101,7 +323,7 @@ Version 0.7.0: Compatibility -------------- +============= Version 1.0.0 has been tested with iOS up to 8.4.1 and OS X up to 10.10.5, but should be compatible with earlier versions too, down to iOS 5.1 and OS X 10.7.