In this tutorial, I'll show you how to compress and decompress files within an iOS app. We will use a third-party library called Ziparchive to implement this function. Although there are other solutions for compressing and decompressing files, I feel that ziparchive is the fastest and easiest to use.
Why do I need to unzip the file?
That's a good question. There are a number of reasons why your application needs to support compression and decompression files, which are some of them:
Apple's 50M download limit
Apple mandatory 3G Network download of the application size can not exceed 50M, the way to bypass this limit is to make your binary package is small enough, and then download the required resources in the application, of course, the best way is to first package the resources into a zip file. The complete steps (shown below) are: Open the app to detect if there are resources to update, download the zip file, unzip the zip file. If you do this, you can publish a smaller app, and then dynamically get the resources.
Dynamically update content
I've come across this problem. When your app needs to update resources, it usually publishes a new package to the app Store, but it may take a week for Apple to review it. The quicker way is to package and publish the resources to a server (even your dropbox) and then download and unzip the resources through your app. This way, whenever you want to publish updates that only modify resources, you don't need to publish a new version to the App Store.
Download the zip file from the Web
A big failure of safari and mail is the inability to open a zip file, which is great if you can support viewing a zip document on a mobile device. Many apps that are downloaded from the store support this feature, and you can also use Ziparchive to implement this feature.
Set up your project
Download a copy of ziparchive from http://code.google.com/p/ziparchive/, or you can get the following command from the terminal input:
SVN checkout http://ziparchive.googlecode.com/svn/trunk/ziparchive-read-only
After getting the code, delete the makefile file from the Minizip directory. We'll have Xcode compile these files. Drag the Minizip directory, ZipArchive.h, and ziparchive.mm to your project, making sure that Create groups for any added folders and targets are selected.
Note: ARC is not supported
If you use arc in your project, you need to tell the compiler not to use arc for ziparchive. To configure this click on the list on the left side of the project, then click on your target and select the "Build Phases" tab.
Expand "Compile Sources", locate ziparchive.mm and double-click, enter "-fno-objc-arc" in the pop-up box and click Done.
Connection Libz
The final step is to connect with libz.1.2.5.dylib, expand the link Binary with Libraries section in the Build Phases tab, and click the "+" button to add a new library. Find libz.1.2.5.dylib from the list, select and click Add.
Now, compiling your project should be successful and without any errors. One thing to note is that ziparchive may produce some caveats, which is no big deal, but if you have code cleanliness (you should have), dig deep into the code to see if you can solve them.
Download and Decompress files
Below I'll show you how easy it is to download, unzip, and use Zip files in your project from the Web. The download code used here is very basic and may not be available in the actual product if no more debugging is possible.
The example project has a view like this:
This is a uiimageview and Uilabel, in the view controller I added iboutlet for them, download the example project can see the specific implementation. We will download a zip file containing images and text from the Web, and you can see them from the top. After decompression, the picture will be set to Uiimageview, the content of the text will be displayed to Uilabel.
1. Apply Ziparchive header File
#import "ZipArchive.h"
2. Download the zip file
1dispatch_queue_tQueue=Dispatch_get_global_queue(Dispatch_queue_priority_default, 0);Dispatch_async(Queue, ^{Nsurl*Url= [NsurlURLWithString:@"Http://www.icodeblog.com/wp-content/uploads/2012/08/zipfile.zip"]; Nserror *Error= Nil; 2 NSData *Data= [NSDataDatawithcontentsofurl:URL options:0Error:&Error]; If(!Error) { 3 Nsarray *Paths= Nssearchpathfordirectoriesindomains(Nscachesdirectory, Nsuserdomainmask,YES); NSString *Path= [Paths Objectatindex:0]; NSString *Zippath= [Path stringbyappendingpathcomponent:@"Zipfile.zip"]; [Data WriteToFile:Zippath Options:0Error:&Error]; If(!Error) { //todo:unzip } else { nslog (@ "Error Saving file%@" ,error } } else { nslog (@ "Error downloading zip file:%@" , Error); Span class= "pun" >}});
The code above will download the zip file from Icodeblog and save it to the app's caches directory. The steps are:
1) Create a queue to run our code at the default priority level
2) Getting data from the Web
3) parse out the caches directory path and write the downloaded data to the local
Now that you have downloaded the files to a local disk, it is time to unzip and use the files.
3, unzip the downloaded file
The final step is to unzip the file you just downloaded. One thing to be clear about is that the zip is stored in /library/caches/zipfile.zip, and the extracted content is also in this directory.
Replace the //Todo:unzipin the upper code with the code below.
Ziparchive *Za= [[ZiparchiveAlloc]Init];1If ([ZaUnzipopenfile:Zippath]) { 2BOOL ret= [ZaUnzipfileto:Path OverWrite:YES]; If (NO==Ret){} [ZaUnzipclosefile]; 3 NSString *Imagefilepath= [Path stringbyappendingpathcomponent:@"Photo.png"]; NSString *Textfilepath= [Path stringbyappendingpathcomponent:@"Text.txt"]; NSData *ImageData= [NSDataDatawithcontentsoffile:Imagefilepath Options:0Error:Nil]; UIImage *Img= [UIImageImagewithdata:ImageData]; NSString *TextString= [NSStringStringwithcontentsoffile:Textfilepath encoding:nsasciistringencoding Error: nil); //4 Dispatch_async ( Dispatch_get_main_queue (), ^{self. Imageview. Image = Img;self. Label. Text = Textstring;
The following explains how this code works:
1) Open the file and unzip it in memory
2) write the extracted memory to the caches directory
3) Use extracted files
4) Update the UI with the data you just acquired
It's really that simple.
Compress files
Below you will see how to compress the files. This is handy when users need to share multiple files via the Web or email. If you complete the above steps, the caches directory will have some files for us to re-compress and send. I'll compress the two files you just unzipped, populate them in a new zip file, and write the new zip file to the documents directory.
In my example project, I created a button called "Zip Files," which, when pressed, would be linked to a ibaction called zipfilebuttonpressed, where we would compress the work:
- (Ibaction)Zipfilesbuttonpressed:(Id)Sender{ 1 Nsarray *Paths= Nssearchpathfordirectoriesindomains(NSDocumentDirectory, Nsuserdomainmask,YES); NSString *Docspath= [Paths Objectatindex:0]; 2Paths= Nssearchpathfordirectoriesindomains(Nscachesdirectory, Nsuserdomainmask,YES); NSString *CachePath= [Paths Objectatindex:0]; 3 NSString *ZipFile= [Docspath stringbyappendingpathcomponent:@"Newzipfile.zip"]; 4 Ziparchive *Za= [[ZiparchiveAlloc]Init]; [ZaCreateZipFile2:ZipFile]; 5 NSString *ImagePath= [CachePath stringbyappendingpathcomponent:@"Photo.png"]; NSString *Textpath= [CachePath stringbyappendingpathcomponent:@"Text.txt"]; 6 [za addfiletozip:imagepath newname:@ "newphotoname.png" ); [za addfiletozip::@ "NewTextName.txt" ]; Span class= "com" >//7 BOOL success = [za closezipfile2]; nslog (@ "Zipped file with result%d" ,success} /span>
Here's how the above code works:
1) resolves the path to the documents directory, which is required when a new zip file needs to be written.
2) parse out the path of the caches directory, we need to get the files that need to be compressed.
3) Get the path to the new zip file.
4) Create an instance of the Ziparchive class and tell it to create a new zip file in memory. Note: This new zip file will not be written to disk until the CloseZipFile2 method is called
5) Get the path to the file that will be compressed
6) Add the files you want to compress to an instance of ziparchive, you can add multiple files here, or even add directories (you can add the entire caches directory if you like).
7) write the zip file to disk, I output the result to confirm whether the compression is successful.
To run the app, click on the "Zip filse" button to view the application's documents directory, ~/library/application Support/iphone Simulator/[ios version]/applications /[unique id]/documents. This directory should contain a compressed file named Newzipfile.zip, and if you unzip it, you can see the files you have compressed.
Conclusion
You now know how to compress and decompress files on iOS devices using the Ziparchive library. You can download the example project below. If you have any questions or suggestions, please leave a message after this article or contact me on Twitter @brandontreb (original author).
http://ju.outofmemory.cn/entry/24090
"Go" compress and unzip files in the app with Ziparchive