I just wanted to add some zip file handling capacity to my code, well, it ended in some confusion. While there is no genuine support for zip files in Cocoa and Objective-C, there are several ways to achieve that which are described here and there on developer sites. I tried to categorize these possibilities while evaluating how to add zip support to my application, so let’s see what I found. Of course I will have missed something somewhere, please give me a hint if you know of additional zip support possibilities.
To sum it all up in the first place, there seem to be seven typical ways to read and write compressed data as zip files inside your Objective-C code. We’ll have a look at these all. I tried to summarize the seven coding options in this diagram which also shows the several layers of code used to enable zip support:
We can see that most of the solutions adding zip support use zlib, a library pre-installed on OS X. zlib supplies a couple of low-level zip handling routines and can be included in your Xcode projects. However, as it only provides low-level routines (and is written in C), you need to have some wrapper code, not least in order to find compressed files inside a zip archive etc. Several solutions rely on minizip which is such a wrapper library (but not pre-installed on OS X), and then only add Objective-C wrapper code on top of it (numbers 1 to 3, more or less). Other solutions combine the zlib wrapper layer and Objective-C wrapping code without using minizip (numbers 4 to 5). If you don’t like third party wrapper code you can also write your own custom wrappers, there are several examples of those custom wrappers (number 6). All available wrapping frameworks (numbers 1 to 5) aren’t really ready to deploy out of the box- there’s only their source code which you have to build either inside your project or as a linked framework. They will work on a Mac as well as on iPhone/iPad. Another thing they all have in common is the missing documentation – you’re lucky if there’s a sample application source code.
The three available minizip wrapping frameworks are ziparchive by acsolu, objective-zip by Gianluca Bertani and osxzip by Dmitry Chestnykh. All are available in source code and are provided under liberal licenses (MIT License, New BSD License and zlib license). ziparchive is a rather small framework with only 8 kb in source code and one Objective-C class, it can zip/unzip files on disk but not in memory. objective-zip is somewhat more sophisticated than ziparchive, provides for a full implementation of minizip and has 34 kb in source code. It comes with an iPhone sample application. osxzip doesn’t define any new classes but is a modified minizip library to add Mac OS X features (resource forks, extended attributes).
Wrapper Frameworks w/o Minizip
The two zlib wrapper frameworks which don’t use minizip are rather different. Obviously they need to have more code as they have to replace the functionality of the minizip layer, but one layer less is good in terms of less complexity. The development of zip-framework by Joris Kluivers (published under New BSD License) seems to have ceased in 2008, of the framework only version 0.1 has been published. It provides read-only access to zip archives. ZipKit by Karl Moskowski is published under a BSD-style license and looks like a full-scale, very Objectice-C like framework. It comes with several sample applications and a guide to embed the framework in your own projects. Development is still active.
Write Your Custom Wrapper
You may also want to write your own wrapper code for the zlib library. This is the hard way as you need to implement at least parts of the zip specification not already covered by the zlib tool yourself. Depending on your application’s needs this will mean to read and understand the specification and to figure out how to communicate with zlib. However, it can turn out to be the most suitable approach if you need only some small zip functionality and don’t want to use external wrappers whose code you don’t quite understand. There is an example of such custom wrapper code implemented as a NSData category (on CocoaDev) and the ZipBrowser sample application in Apple’s Mac OS X Reference Library which also uses custom wrapper code. It is quite possible to open an zip archive, find and readout a specific file inside the archive in just a couple of lines of code.
If you want the quick and easy solution or don’t like the zlib library, just drop a call to an zip command line tool in your code. There are the ditto and zip/unzip tools installed on your Mac which you can call from your code by using an NSTask object, for example like this:
NSTask * task = [[NSTask alloc] init]; [task setLaunchPath:@"/usr/bin/ditto"] or [...@"/usr/bin/zip"]; [task setArguments: ...]; [task launch]; [task waitUntilExit];
There are some examples on CocoaDev for this, see the UsingZipFilesExamples page. This can (and will) work but you need to rely that the external tools are actually present and that their syntax hasn’t changed since deployment of your code. It is a solution, but in my eyes not a very elegant one. If you develop for iPhone/iPad, however, you cannot use this way but have to go for one of the wrapping solutions (see above).
Which Way to Go?
There are pro and cons for most of the seven ways to get zip support. Personally, I ended in following way number 6 and went into the city of custom wrappers for zlib because I needed only read-only support for a special type of zip files which was easy enough to write. If you need full-scale zip support probably ZipKit or the NSTask approach are the best choices for you.