Zip/Unzip files on iPhone/iPad/iOS


  1. Download ZipArchive from http://code.google.com/p/ziparchive/downloads/list.
  2. Drag into project.
  3. Add to project existing framework libz.1.2.3.dylib (last version).
  4. Import to project:
    #import "ZipArchive.h"
    
  5. Uncompress zip file example:
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    
    NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:@"myZipFileName.zip"];
    
    NSString *output = [documentsDirectory stringByAppendingPathComponent:@"unZipDirName"];
    
    ZipArchive* za = [[ZipArchive alloc] init];
    
    if( [za UnzipOpenFile:zipFilePath] ) {
        if( [za UnzipFileTo:output overWrite:YES] != NO ) {
            //unzip data success
            //do something
        }
    
        [za UnzipCloseFile];
    }
    
    [za release];
    
  6. Compress directory or file example:
    BOOL isDir=NO;
    
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    
    NSArray *subpaths;
    
    NSString *toCompress = [NSString stringWithString:@"dirToZip_OR_fileNameToZip"];
    NSString *pathToCompress = [documentsDirectory stringByAppendingPathComponent:toCompress];
    
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    if ([fileManager fileExistsAtPath:pathToCompress isDirectory:&isDir] && isDir){
        subpaths = [fileManager subpathsAtPath:pathToCompress];
    } else if ([fileManager fileExistsAtPath:pathToCompress]) {
        subpaths = [NSArray arrayWithObject:pathToCompress];
    }
    
    NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:@"myZipFileName.zip"];
      
    ZipArchive *za = [[ZipArchive alloc] init];
    [za CreateZipFile2:zipFilePath];
    if (isDir) {
        for(NSString *path in subpaths){  
            NSString *fullPath = [pathToCompress stringByAppendingPathComponent:path];
            if([fileManager fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir){
                [za addFileToZip:fullPath newname:path];  
            }
        }
    } else {
        [za addFileToZip:pathToCompress newname:toCompress];
    }
    
    BOOL successCompressing = [archiver CloseZipFile2];
    
    

WP7 - Load local HTML files and all related files (js, css) to WebBrowser

Agenda : we have several files html, css, js interconnected and we would start our web application in WebBrowser.
0. Create new project "SilverlightWebBrowser"
1. In the project navigator will create a new folder and name "HTML".
2. Copy all our files in that folder (if you want include image files don't forget change "Build Action" property of the images to "Content" from "Resource").


3. Add to MainPage.xaml code for show WebBrowser:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0">
    <phone:WebBrowser IsScriptEnabled="True" Name="webBrowser1" Width="450" Height="548"/>
</Grid>

4. MainPage.xaml.cs

#define DEBUG

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Resources;
using Microsoft.Phone.Controls;

namespace SilverlightWebBrowser
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            SaveFilesInHTMLFolderToIsoStore();

            webBrowser1.Navigate(new Uri("HTML/Index.html", UriKind.Relative));

        }

        private static void SaveFilesInHTMLFolderToIsoStore()
        {
#if DEBUG
            // This deletes all existing files in IsolatedStorage - Useful in testing
            // In live should not do this, but only load files once - this speeds subsequent loading of the app
            using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                isoStore.Remove();
            }
#endif
            string[] files = AllFilesInHTMLFolder();

            using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                Debug.WriteLine("check for exist " + files[0]);
                if (!isoStore.FileExists(files[0]))
                {
                    foreach (string f in files)
                    {
                        Debug.WriteLine("copy to isolated storage " + f.ToString());
                        StreamResourceInfo sr = Application.GetResourceStream(new Uri(f, UriKind.Relative));

                        // T4 Template includes all files in source folder(s). This may include some which are not in the project
                        if (sr != null)
                        {
                            using (BinaryReader br = new BinaryReader(sr.Stream))
                            {
                                byte[] data = br.ReadBytes((int)sr.Stream.Length);
                                SaveFileToIsoStore(f, data);
                            }
                        }
                    }
                }
            }
        }

        private static void SaveFileToIsoStore(string fileName, byte[] data)
        {
            string strBaseDir = string.Empty;
            const string DelimStr = "/";
            char[] delimiter = DelimStr.ToCharArray();
            string[] dirsPath = fileName.Split(delimiter);

            // Get the IsoStore
            using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                // Recreate the directory structure
                for (int i = 0; i < dirsPath.Length - 1; i++)
                {
                    strBaseDir = Path.Combine(strBaseDir, dirsPath[i]);
                    isoStore.CreateDirectory(strBaseDir);
                }

                // Create the file if not exists
                // or override if exist
                using (BinaryWriter bw = new BinaryWriter(new IsolatedStorageFileStream(fileName,
                        FileMode.Create, FileAccess.Write, FileShare.Write, isoStore)))
                {
                    bw.Write(data);
                }
            }
        }



        //generated from MainPage.xaml.tt -> Run Custom Tool
        private static string[] AllFilesInHTMLFolder()
        {
            return new[] {
                           "HTML/index.css",
                           "HTML/Index.html",
                           "HTML/inner.js",
                        };
        }
    
    }
}

5. And then run emulator
6. Now We see our page with our css and js
7. But if we don't know in advance a list of files or it's large enough that would get lost, you can use preprocessed text template.

MainPage.xaml.tt

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".gen.cs" #>
<#@ import namespace="System.IO"#>
// <auto-generated />
using Microsoft.Phone.Controls;

namespace SilverlightWebBrowser
{
    public partial class MainPage : PhoneApplicationPage
    {
        private static string[] AllFilesInHTMLFolder()
        {
            return new[] {
<#
            DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(Host.TemplateFile), "HTML"));

            foreach(FileInfo file in directoryInfo.GetFiles("*.*", SearchOption.AllDirectories))
            {
    if (!file.FullName.Contains(@"\."))
    {#>
                           "<#= file.FullName.Substring(file.FullName.IndexOf("HTML")).Replace(@"\", "/") #>",
<#           }
   }
#>
                        };
        }
    }
}

8. Copy file MainPage.xaml.tt into project
    -> select file in navigation project
    -> right click -> Run Custom Tools
    -> open generated file MainPage.xaml.gen.cs
    -> we see our function AllFilesInHTMLFolder() with all exist files
    -> if you want to see all code in one place as copy/paste to MainPage.xaml.cs and delete MainPage.xaml.gen.cs. If no as go to 10.
10. It's all.

How to create additional localization on your iOS app - Files (plist, ...)

 1. Create a directory under project directory (in Finder) in format: language_region.lproj or language.lproj

languages list: ISO 639-2 Language Codes
regions list: ISO - Maintenance Agency

2. Right click on "Resource" in xCode project.
         Add ->
         New File ->
         Choose "Other" from Mac OS X ->
         Choose "Empty File" ->
         Next ->
         In "File Name" field change from "untitle" to "MyFileName.MyExtention" (usually Localizable.strings or MyFileName.plist) ->
         In "Location" field choose language_region.lproj folder you created ->
         Finish

3. Fill file with content do you want (copy/paste or replace file in Finder)

jQuery Equivalent of Prototype Function.bind with the transfer of arguments

MyClass = Class.create( {
...  
    displayFeeds: function(items){
        var ul = $('itemsList');
        for (var i = 0; i < items.length; i++) {
            var li = new Element('li');
            var text = new Element('a', {'href': '#'}).update(items[i].title);
            li.insert(text);
            ul.insert(li);
            text.observe('click', this.printDynamic.bind(this,items[i].link));
        }
    },

    localVar : "my class local variable",

    printDynamic: function(link){
        this.localVar = link;
    }
});

We have JQuery full equivalent below


MyClass = Class.create( {
...
    displayFeeds: function(items){
        var ul = $('#itemsList');
        for (var i = 0; i < items.length; i++) {
            var li = $("<li><a href='#DetailsScreen'>"+items[i].title+"</a></li>");
            li.bind('click',{url:items[i].link}, $.proxy(this.printDynamic, this));
            li.appendTo( ul );
        }
    },
    localVar : "my class local variable",
    printDynamic: function(event){
        this.localVar = event.data.url;
    }
});