This library is deprecated. If you are still using it, you are encouraged to find alternatives.
Objective-Zip is a small Objective-C library that wraps ZLib and MiniZip in an object-oriented friendly way.
The source repository contains full sources for ZLib, MiniZip and Objective-Zip, together with some unit tests. The versions included are:
Please note that ZLib and MiniZip are included here only to provide a complete and self-contained package, but they are copyrighted by their respective authors and redistributed on respect of their software license. Please refer to their websites (linked above) for more informations.
Objective-Zip exposes basic functionalities to read and write zip files, encapsulating both ZLib for the compression mechanism and MiniZip for the zip wrapping.
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:
#import "Objective-Zip.h"
Alternatively you can use the following import statement if you plan to use Apple's NSError pattern:
#import "Objective-Zip+NSError.h"
More on error handling at the end of this document.
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:
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.
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:
OZZipWriteStream *stream= [zipFile writeFileInZipWithName:@"abc.txt"
compressionLevel:OZZipCompressionLevelBest];
[stream writeData:abcData];
[stream finishedWriting];
Objective-Zip supports only traditional PKWare encryption, which is also the format most widely supported by common unzip utilities.
To add a file with encryption, it is necessary to precompute a CRC32 of the file being added. This is needed by traditional PKWare encryption to later verify that the password provided for decryption is correct.
The library includes a handy crc32 method as an NSData category (automatically imported under the umbrella header):
NSData *fileData= // Your file data
uint32_t crc= [fileData crc32];
OZZipWriteStream *stream= [zipFile writeFileInZipWithName:@"abc.txt"
compressionLevel:OZZipCompressionLevelBest
password:@"password"
crc32:crc];
[stream writeData:fileData];
[stream finishedWriting];
Note that passing 0 (or any other non-CRC32 number) as the crc32 argument will make the decryption fail, even if the correct password is specified.
Note also that if your file is too large to be stored in a single NSData, you can still compute the CRC32 progressively by using a loop:
NSFileHandle *fileHandle= // Your file handle
uint32_t crc= 0;
do {
// Read a chunk of the file in data buffer
NSData *data= [fileHandle readDataOfLength:BUFFER_SIZE];
if ([data length] == 0)
break;
crc= [data crc32withInitialCrc32:crc];
} while (YES);
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).
Since the file may not fit into memory, you can read it block by block using a buffer:
OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:@"test.zip"
mode:OZZipFileModeUnzip];
[unzipFile goToFirstFileInZip];
OZZipReadStream *read= [unzipFile readCurrentFileInZip];
NSMutableData *data= [[NSMutableData alloc] initWithLength:BUFFER_SIZE];
do {
// Reset buffer length
[data setLength:BUFFER_SIZE];
// Read bytes and check for end of file
int bytesRead= [read readDataWithBuffer:data];
if (bytesRead <= 0)
break;
[data setLength:bytesRead];
// Do something with data
} while (YES);
[read finishedReading];
Alternatively, if you know in advance the file will fit into memory, you may preallocate a buffer big enough and read the all file at once. In the example below the buffer is preallocated with precisely the uncompressed size of the file:
OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:@"test.zip"
mode:OZZipFileModeUnzip];
[unzipFile goToFirstFileInZip];
OZFileInZipInfo *info= [unzipFile getCurrentFileInZipInfo];
OZZipReadStream *read= [unzipFile readCurrentFileInZip];
NSMutableData *data= [[NSMutableData alloc] initWithLength:info.length];
[read readDataWithBuffer:data];
// Do something with 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.
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: