Unzipping Files In iOS Using ZipArchive

http://www.icodeblog.com/2012/08/13/unzipping-files-using-zip-archive/

In this tutorial, I am going to demonstrate how you can zip and unzip files from within your iOS applications. We will be using a third party library called ZipArchive to achieve this. While there are a couple solutions out there to zip and unzip files, I feel that the ZipArchive library was the fastest and easiest way to get up and running.

Why Would I want To Unzip Files?

That’s a great question. There are a number of reasons why you might want to support zipping and unzipping files inside of your applications. Here are just a few:

Apple’s 50 MB App Store Download Cap

Apple has imposed a 50MB download limit over 3G on applications downloaded to appease carriers and not hog all of their bandwidth. One way to circumvent this is to keep your binaries very small, and download the resources your application needs. The best way to package these resources is of course, a zip file. So the process (as you will see demoed below), is to open your app, check for resource updates, download the zip file, and unzip it. Now you can ship smaller applications, that fetch their resources dynamically.

Dynamic Updates To Content

I touched on this above. When your application needs updated assets, the common practice is to submit an update to the App Store. This could take up to a week for Apple to Review and publish. A faster approach is to zip your assets up and stick them on a server somewhere (even your Dropbox) and have your app download and unzip them. This way, whenever you want to make asset-based changes to your application, you won’t need to submit another copy of it to the store.

Downloading Zip Files From The Web

One huge downfall of Safari and the Mail app is, they are unable to open zipped files. It would be nice to offer some sort of support to view zipped archives on your device. Many of the “download” apps in the store support this, and you can too with some help from ZipArchive.

Setting Up Your Project

Head over to http://code.google.com/p/ziparchive/ and checkout a copy of ZipArchive. Or you can just type this into your terminal.

svn checkout http://ziparchive.googlecode.com/svn/trunk/ziparchive-read-only

Once you have cloned the repository, delete the MakeFile file from the minizip folder. We will let XCode build our files. Now, drag this minizip folder as well as the ZipArchive.h and ZipArchive.mm files into your project, making sure to check “Create groups for any added folders”. Also, be sure your target is checked.

Note: No ARC Support

If you are using an ARC enabled project, you will need to tell the compiler not to use ARC for ZipArchive. To do this, click on the project in the left hand column. Then click on your target in the middle column and select the “Build Phases” tab.

Expand the “Compile Sources” area, locate ZipArchive.mm and double click on it. In the box that pops up, type in -fno-objc-arc and click Done.

Linking libz

The last step is to link your project against libz.1.2.5.dylib. From the Build Phases screen you navigated to above, expand the Link Binary With Librariessection and click the “+” button to add a new library. Search the list for libz.1.2.5.dylib, select it and click Add.

Now, compile your project and it should succeed with no errors. One thing to note is ZipArchive might produce some warnings, they are not a big deal, but if you are a warning Nazi (you should be), dig into the code and see if you can solve them yourself.

Downloading And Unzipping Files

I will now show you how easy it is to download a zip file from the web, unzip its contents, and use them in your project. The method of which we will download the files is very basic and most likely wouldn’t be used in production without further error reporting and checking.

The sample project has a view that looks like this:

It’s basically a UIImageView and a UILabel. Inside of the view controller I have set up IBOutlets for these two items. Make sure and download the sample project to see the implementation details. We will be downloading a zip file from the web that contains an image and a text file which you can see displayed in the screenshot above. Once unzipped, the image will be set as the viewable image in our UIImageView and the textual contents of the .txt file will be displayed inside of the UILabel.

**1. Import the ZipArchive headers **

#import "ZipArchive.h"

2. Download the the zip file

    // 1 
    dispatch_queue_t queue = dispatch_get_global_queue(
                                                       DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSURL *url = [NSURL URLWithString:@"http://www.icodeblog.com/wp-content/uploads/2012/08/zipfile.zip"];
        NSError *error = nil;
        // 2
        NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&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:0 error:&error];
 
            if(!error)
            {
                // TODO: Unzip
            }
            else
            {
                NSLog(@"Error saving file %@",error);
            }
        }
        else
        {
            NSLog(@"Error downloading zip file: %@", error);
        }
 
    });

This preliminary code downloads a zip file from iCodeBlog and saves it to the caches directory for the application.

  1. Creates a dispatch queue in which to run our code on with default priority.
  2. Quick and dirty way of fetching data from the web.
  3. Resolves the path to the caches directory and writes out the downloaded data to a local zip file

Now that you have it downloading the file to disk, it’s time to unzip that file and make use of it’s contents.

3. Unzipping the downloaded file

The last step here is to unzip the file you just downloaded. To be clear, it was save to the path /Library/Caches/zipfile.zip and once extracted, it’s contents will be inside of the Caches folder as well.

Replace the //TODO: Unzip in the code above, with the following code:

ZipArchive *za = [[ZipArchive alloc] init];
// 1
if ([za UnzipOpenFile: zipPath]) {      
    // 2      
    BOOL ret = [za UnzipFileTo: path overWrite: YES];
    if (NO == ret){} [za UnzipCloseFile];
 
    // 3
    NSString *imageFilePath = [path stringByAppendingPathComponent:@"photo.png"];
    NSString *textFilePath = [path stringByAppendingPathComponent:@"text.txt"];
    NSData *imageData = [NSData dataWithContentsOfFile:imageFilePath options:0 error:nil];
    UIImage *img = [UIImage imageWithData:imageData];
    NSString *textString = [NSString stringWithContentsOfFile:textFilePath 
        encoding:NSASCIIStringEncoding error:nil];
 
    // 4           
    dispatch_async(dispatch_get_main_queue(), ^{
        self.imageView.image = img;
        self.label.text = textString;
    });

Here is an explanation of what’s going on.

  1. Opens the file and unzips it in memory
  2. Writes the unzipped contents out to a given path (Caches folder)
  3. Makes use of the unzipped files
  4. Updates the UI (on the main thread of course) with the newly fetched data.

It really is that simple.

Zipping Files

Now you are going to see how to go the other way and zip up some files on disk. Again, this could be particularly handy when you want to allow your users to share groups of files via the web or email.

If you completed the steps above, your caches folder should have some files lying around that we can just zip up again and send off. We are going to zip up the two files you previously unzipped, stuff them into a new zip file, and write that out to the documents directory.

In my sample project, I have created a new button at the top that says “Zip Files” which links to an IBAction called zipFilesButtonPressed: when tapped. That is where I will be doing the zipping:

- (IBAction)zipFilesButtonPressed:(id)sender
{
    // 1
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docspath = [paths objectAtIndex:0];
 
    // 2
    paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachePath = [paths objectAtIndex:0];
 
    // 3
    NSString *zipFile = [docspath stringByAppendingPathComponent:@"newzipfile.zip"];       
 
    // 4
    ZipArchive *za = [[ZipArchive alloc] init];
    [za CreateZipFile2:zipFile];
 
    // 5
    NSString *imagePath = [cachePath stringByAppendingPathComponent:@"photo.png"];
    NSString *textPath = [cachePath stringByAppendingPathComponent:@"text.txt"];
 
    // 6
    [za addFileToZip:imagePath newname:@"NewPhotoName.png"];
    [za addFileToZip:textPath newname:@"NewTextName.txt"];
 
    // 7
    BOOL success = [za CloseZipFile2];    
    NSLog(@"Zipped file with result %d",success);
 
}

Here is what’s going on:

  1. Resolve the path to the documents directory. We will need this when determining the path to write out our new zip file.
  2. Resolve the path to the caches directory. This is used to fetch the files that will be zipped up.
  3. Determines the path the zip file we will be writing out.
  4. Instantiates the ZipArchive object and tells it to create a new “in-memory” zip file. Note, the file won’t be written out until you call the corresponding CloseZipFile2 method.
  5. Resolve the path to the files that will be zipped up.
  6. Add the files to the zip archive. You can add as many files as you would like here. You can even add directories (ie you could have added the entire caches directory if you wanted to).
  7. Write out the zip file and close it. Just to test, we log the result to ensure that the zipping was successful.

After running through the application, tapping on the “Zip Files” button, look inside of the Application’s Documents folder (located ~/Library/Application Support/iPhone Simulator/[iOS Version]/Applications/[Unique ID]/Documents]. It should contain a single zip file called newzipfile.zip. If you unzip it, you should see the two files that you stuffed in there extracted.

Conclusion

You have now seen how to zip and unzip files on iOS devices using the ZipArchive library. You can download the sample project at the bottom of this post. As always, if you have any questions or comments, feel free to write them in the comments of this post or write them to me on Twitter @brandontreb.

Happy iCoding!

Download The Sample Project


内容概要:《2024年中国城市低空经济发展指数报告》由36氪研究院发布,指出低空经济作为新质生产力的代表,已成为中国经济新的增长点。报告从发展环境、资金投入、创新能力、基础支撑和发展成效五个维度构建了综合指数评价体系,评估了全国重点城市的低空经济发展状况。北京和深圳在总指数中名列前茅,分别以91.26和84.53的得分领先,展现出强大的资金投入、创新能力和基础支撑。低空经济主要涉及无人机、eVTOL(电动垂直起降飞行器)和直升机等产品,广泛应用于农业、物流、交通、应急救援等领域。政策支持、市场需求和技术进步共同推动了低空经济的快速发展,预计到2026年市场规模将突破万亿元。 适用人群:对低空经济发展感兴趣的政策制定者、投资者、企业和研究人员。 使用场景及目标:①了解低空经济的定义、分类和发展驱动力;②掌握低空经济的主要应用场景和市场规模预测;③评估各城市在低空经济发展中的表现和潜力;④为政策制定、投资决策和企业发展提供参考依据。 其他说明:报告强调了政策监管、产业生态建设和区域融合错位的重要性,提出了加强法律法规建设、人才储备和基础设施建设等建议。低空经济正加速向网络化、智能化、规模化和集聚化方向发展,各地应找准自身比较优势,实现差异化发展。
数据集一个高质量的医学图像数据集,专门用于脑肿瘤的检测和分类研究以下是关于这个数据集的详细介绍:该数据集包含5249张脑部MRI图像,分为训练集和验证集。每张图像都标注了边界框(Bounding Boxes),并按照脑肿瘤的类型分为四个类别:胶质瘤(Glioma)、脑膜瘤(Meningioma)、无肿瘤(No Tumor)和垂体瘤(Pituitary)。这些图像涵盖了不同的MRI扫描角度,包括矢状面、轴面和冠状面,能够全面覆盖脑部解剖结构,为模型训练提供了丰富多样的数据基础。高质量标注:边界框是通过LabelImg工具手动标注的,标注过程严谨,确保了标注的准确性和可靠性。多角度覆盖:图像从不同的MRI扫描角度拍摄,包括矢状面、轴面和冠状面,能够全面覆盖脑部解剖结构。数据清洗与筛选:数据集在创建过程中经过了彻底的清洗,去除了噪声、错误标注和质量不佳的图像,保证了数据的高质量。该数据集非常适合用于训练和验证深度学习模型,以实现脑肿瘤的检测和分类。它为开发医学图像处理中的计算机视觉应用提供了坚实的基础,能够帮助研究人员和开发人员构建更准确、更可靠的脑肿瘤诊断系统。这个数据集为脑肿瘤检测和分类的研究提供了宝贵的资源,能够帮助研究人员开发出更准确、更高效的诊断工具,从而为脑肿瘤患者的早期诊断和治疗规划提供支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值