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.

Tuesday, December 13, 2011

UIView+Hierarchy

Today I came across a very handy category class, named UIView + Hierarchy. It provides some useful methods like below:
-(int)getSubviewIndex;
 
-(void)bringToFront;
-(void)sendToBack;
 
-(void)bringOneLevelUp;
-(void)sendOneLevelDown;
 
-(BOOL)isInFront;
-(BOOL)isAtBack;
 
-(void)swapDepthsWithView:(UIView*)swapView;

These aren't so hard to implement but having them in a category makes you have a cleaner code, since you encapsulate the hierarchy management in a category.
Here's a screenshot why I needed this: On the right hand side, there are two buttons (Program - Ziyaret Ozeti), that act like a folder cap. The active one should be one level up in the Z-order. When you deactivate it by selecting the other, then it should fall back one level and the other one should get in the front. Now it's so nice and easy :)
You can download the actual source from here

Saturday, December 10, 2011

Love your .pch files

Today is the day I got enlightened about the .pch files.  This is the prefix header for all of your source files in your project. If you have a utility class for example, that you want to import from all your sources, than you can import it in your .pch and then it gets imported from every class. Also if you like using macros for logging, and asserts, etc.. then you can also put them here. 


For example, I change the behavior of my logs and asserts according to my build configurations. To do this, I have a macro _NSLog that logs as usual if I'm in DEBUG configuration, and does nothing if I'm in other configurations. This lets me get a log free distribution package. I have the same logic for the ASSERTs.


This is the .pch file of my current project. BTW, you can see the integration with NSLogger here. When I call _NSLog from any class, LogMessageF of the utility gets called in DEBUG configuration and nothing happens in the others.  


Also see how I tag my logs by using _NSLogJSON, _NSLogDataMan, etc.. which in turn produces logs with tags "JSON" and "DataManager".



NSLogger, where were you all this time?

Today I integrated  a logging utility named NSLogger to my own iOS project. It has so many great features like letting you group your logs, view them easily in it's own viewer desktop application, log data and images, etc...And it's way too easy to get it working.


Another awesome thing that comes along by using this is that, when I hand in my iOS application to the testers who're in the same network with me, I can view the logs that their actions produce in my viewer app wuhuu!
Anyways, the github page of the project tells so much more, so go check it out:
https://github.com/fpillet/NSLogger



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