zip-plugin-featToday, Corona Labs announced that Corona Plugins — code named “Project Gluon” — are live and available to Corona SDK Pro subscribers using Daily Build #1115 and above.

One of the new plugins handles the 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.


Using Corona Plugins

Corona Plugins are “managed” from the build.settings file in your core project directory. This makes it easy to add just the specific plugins you need for an app, ultimately resulting in a lighter compiled binary.

To use a plugin, simply add the plugins table within settings and configure the zip plugin within:

settings =
{
   orientation =
   {
      default = "portrait",
      supported = { "portrait", "portraitUpsideDown" },
   },
   plugins = 
   {
      ["plugin.zip"] =
      {
         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( "plugin.zip" )

That’s it! Now you’re ready to use the zip plugin. Note that when you run a project in the Corona Simulator that requires a plugin, you’ll be prompted to download the plugin; this only happens once, when you first use the plugin.


Implementing .zip in Code

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" )
   else
      print( "event.name:" .. event.name )
      print( "event.type:" .. event.type )
      if ( event.response and type(event.response) == "table" ) then
         for i = 1, #event.response do
            print( event.response[i] )
         end
      end    
   end
end

Now, let’s use use the network.download 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
      else

         local options = {
            zipFile = event.response.filename,
            zipBaseDir = event.response.baseDirectory,
            dstBaseDir = system.DocumentsDirectory,
            listener = zipListener,
         }

         zip.uncompress( options )
      end
   end
end

local params = {}
params.progress = true
local URL = "http://omnigeekmedia.com/coronasdk/test.zip"
network.download( URL, "GET", networkListener, params, "test.zip", system.TemporaryDirectory )

Let’s follow through the process step by step:

  1. When network.download 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 network.download “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 following documentation:

Plugin Documentation (zip.*) — http://docs.coronalabs.com/daily/plugin/zip/

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

  1. Currently, the zip plugin is only available to Corona SDK Pro subscribers using Daily Build #1115 and above.
  2. zip files can contain executable code which can be problematic, in particular on Windows machines. Please do not open zip files from unknown sources, and keep your virus scanning software up-to-date.
  3. On iOS, since you are downloading easily retrievable data, Apple expects those files to go into the system.CachesDirectory.
  4. On Android, remember to enable Internet access as detailed here.

Questions or comments? Please provide your input below.

  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( “plugin.zip” );

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=""> <strike> <strong>