The Zip plugin handles compression and un-compression of files using the popular zip algorithm. For anybody who’s unfamiliar with zip files, the most common usage is when you need to group several related files into a “package” so it’s easier to move them around and share them with others. For example, if you contract a set of artwork from a designer, he/she can compress them into a zip archive and send them via email, Dropbox, etc. All of the artwork will be contained in that one file with the .zip extension, and when you open it locally, the file will “unzip” and all of the files will be available to you, exactly as the designer intended. Another use of zip files is to compress one large file into a smaller overall .zip file. The format and type of the original file will dictate the amount of compression achieved, but in virtually every instance, you’ll save valuable storage space.

Why is this important to mobile app developers? For one, you gain the ability to expand your app’s contents. You can create a zip file containing expansion art and sounds, download it into your app, unzip it, and use those assets. Secondly, you can now produce zip files which you can upload to web servers for distribution.

In today’s tutorial, let’s examine how to download a zip file from a web server, unzip the contents, and show a list of the files within.

Including the Zip plugin

To use the Zip plugin, first add it to the plugins table within settings of the build.settings file:

settings =
    plugins = 
        [""] =
            publisherId = "com.coronalabs",

Next, in your main project code, you must require the plugin, similar to how you’d require a core Corona library or external Lua module.

local zip = require( "" )

That’s it! Now you’re ready to use the Zip plugin.

Implementing the plugin

Like many API calls in Corona, a callback function is required so that you can determine when the process is complete and then take the appropriate action.

local function zipListener( event )
    if ( event.isError ) then 
        print( "Unzip error" )
        print( "" .. )
        print( "event.type:" .. event.type )
        if ( event.response and type(event.response) == "table" ) then
            for i = 1, #event.response do
                print( event.response[i] )

Now, let’s use use the API call to retrieve the zip file from a remote server and, in its callback listener, initiate the unzip process. The callback function will list all files that are successfully uncompressed.

local function networkListener( event )

    if ( event.isError ) then
        print( "Network error - download failed" )
    elseif ( event.phase == "began" ) then
        print( "Progress Phase: began" )
    elseif ( event.phase == "ended" ) then
        if ( math.floor(event.status/100) > 3 ) then
            print( "Network error - download failed", event.status )
            --NOTE: 404 errors (file not found) is actually a successful return,
            --though you did not get a file, so trap for that
            local options = {
                zipFile = event.response.filename,
                zipBaseDir = event.response.baseDirectory,
                dstBaseDir = system.DocumentsDirectory,
                listener = zipListener,
            zip.uncompress( options )

local params = {}
params.progress = true
local URL = "" URL, "GET", networkListener, params, "", system.TemporaryDirectory )

Let’s follow through the process step by step:

  1. When finishes, the networkListener function is called.
  2. After checking for and catching possible error conditions, create a table of options to pass to the Zip plugin. The zipFile and zipBaseDir will be given to you in the “event” table. Optionally, you can specify whether to unzip all files or just some files — see the documentation for details.
  3. Provide the destination directory as dstBaseDir and the zipListener function that you wrote (above) will handle the rest!

In summary

As you can see, using the Zip plugin is simple… just include the plugin in your build.settings file, set up a basic callback function, and pass a table of options to the plugin. For full details and instructions on how to use the zip.compress() and zip.list() APIs, please review the Zip plugin documentation.

Finally, before we conclude today’s tutorial, there are just a few more important points:

  1. Compressed zip files may contain executable code which can be problematic. Please do not open zip files from unknown sources, and keep your virus scanning software up-to-date.
  2. On iOS, since you are downloading easily retrievable data, Apple expects those files to go into the system.CachesDirectory.
  3. On Android, remember to enable Internet access as detailed here.

  1. Oh my goodness, this is wonderful news. Just got my app set up using the TAR module, but this will be the much better tool to use. Thank you for this!

    +1 on password protecting zip files as well.

  2. I have read that Apple expects downloadable content to be stored in the system.CachesDirectory. But in my case, my users will be downloading a chunk of new content for my app, it will be about 20mb big. I can’t have my users have to redownload the content each time they restart theri device and the cache is cleared.

    I can’t just put this content in the DocumentsDirectory?

  3. The documentation should be updated to reflect the requirement to add something like this to your .lua file using the Zip plug-in:

    local zip = require( “” );

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>