Thursday, December 15, 2011

ZipArchive

Yesterday's challenge was about to integrate a zip library to my project.  My goal was to download a zip file from the server onto my iPad and then extract it to the Documents folder of my project's sandbox, and then use the files inside it to display to the user. So, I decided to use this ZipArchive class from here. ZipArchive is a simple to use class which depends on the minizip library, and minizip classes are written in plain C. 


In order to integrate this, it's adviced that you put all the ZipArchive classes and the minizip classes to your project and then add libz.dylib framework to your project. However, when I do these steps in my project's source code, strange compiler errors about my NSZone and NSObject classes appeared, which I wasn't able to rationalize in any ways. Why do my iOS SDK classes get messed up when I try to compile some C code? 


Then to bring the mystery one level further, I tried to compile this zip library by putting them in a new XCode project. There everything goes nice and easy with no compile errors. So I couldn't understand this, but as always, I found a workaround :] 


I compiled the zip classes into a static library, in the new XCode project where everything is smooth. Then, added the header files of ZipArchive and the minizip classes to my project, along with the .a output of the static library. Then I had no compile errors in my project because the library was already compiled, yay!


Another thing I learned from this was: When I was compiling the zip API source code to get the static library, if the simulator was the target, then the library contains x86 code. And when you want to use this static library in your project that you want to compile for running on the device, the compiler gives an error saying that the static library was not built for this architecture and it's quite right. The vice versa is also true, if the device is the target while building the library, then it contains ARM code. And when you want to use this library to run your own code on the simulator, again the compiler doesn't like this.




So, the solution is to get a fat static library that contains both x86 and ARM code. This is how you get it: You compile your library once for the simulator and once for the device and now you have two .a files. Then you open the good old terminal and type:

lipo -create libdevice.a libsimulator.a -output libcombined.a
Now you can use the combined .a file whether for running on a device or the simulator.

No comments:

Post a Comment

.widget { margin-top: 30px; margin-bottom: 30px; }