diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0e3c8672df5ca74beac0db6f1ce6056df770a5a..be7679a63e50d36e2db7cdf4aab046396e4ca0b2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,7 +94,7 @@ opt(TETGEN_OLD "Enable older version of Tetgen" OFF)
 opt(VORO3D "Enable Voro3D (for hex meshing, experimental)" ${DEFAULT})
 opt(WRAP_JAVA "Enable generation of Java wrappers (experimental)" OFF)
 opt(WRAP_PYTHON "Enable generation of Python wrappers" OFF)
-opt(ZIPPER "Enable zip compression/decompression" OFF)
+opt(ZIPPER "Enable Zip file compression/decompression" OFF)
 
 set(GMSH_MAJOR_VERSION 2)
 set(GMSH_MINOR_VERSION 10)
diff --git a/Common/OS.cpp b/Common/OS.cpp
index d78fb9f5153c14ef2fced9026668c67ebeba193d..62e860c7b152364e81a0f097a866006da7d31c0c 100644
--- a/Common/OS.cpp
+++ b/Common/OS.cpp
@@ -19,6 +19,13 @@
 #include "StringUtils.h"
 #include "Context.h"
 
+#if defined(HAVE_ZIPPER)
+#include <iostream>
+#include <fstream>
+#include "zipper.h"
+#include "unzipper.h"
+#endif
+
 #if defined(__APPLE__)
 #include <sys/sysctl.h>
 #include <mach-o/dyld.h>
@@ -668,3 +675,39 @@ void RedirectIOToConsole()
   std::ios::sync_with_stdio();
 #endif
 }
+
+void UnzipFile(const std::string &fileName, const std::string &prependDir)
+{
+#if defined(HAVE_ZIPPER)
+  std::string dir = prependDir;
+  if(dir.size() && dir[dir.size()-1] != '/' && dir[dir.size()-1] != '\\')
+    dir.push_back('/');
+
+  ziputils::unzipper zipFile;
+  zipFile.open(fileName.c_str());
+  std::vector<std::string> dirnames = zipFile.getFolders();
+  for (std::vector<std::string>::const_iterator it = dirnames.begin();
+       it != dirnames.end(); it++){
+    std::string folder = dir + *it;
+    Msg::Info("Creating folder `%s'", folder.c_str());
+    CreatePath(folder);
+  }
+  std::vector<std::string> filenames = zipFile.getFilenames();
+  for (std::vector<std::string>::const_iterator it = filenames.begin();
+       it != filenames.end(); it++){
+    zipFile.openEntry(it->c_str());
+    std::string name = dir + *it;
+    Msg::Info("Extracting file `%s'", name.c_str());
+    std::ofstream ofs;
+    ofs.open(name.c_str());
+    if(ofs.is_open()){
+      zipFile >> ofs;
+      ofs.close();
+    }
+    else
+      Msg::Error("Could not create file `%s'", name.c_str());
+  }
+#else
+  Msg::Error("Gmsh must be compiled with Zipper support to extract zip files");
+#endif
+}
diff --git a/Common/OS.h b/Common/OS.h
index 17632f89ddeba60bacc3c0a76d2c55fee1b886b3..081dc222991f395c32df88a748b42cde6d0004f8 100644
--- a/Common/OS.h
+++ b/Common/OS.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <stdio.h>
 
+FILE *Fopen(const char* f, const char *mode);
 const char *GetEnvironmentVar(const char *var);
 void SetEnvironmentVar(const char *var, const char *val);
 double GetTimeInSeconds();
@@ -31,6 +32,6 @@ int SystemCallExe(const std::string &exe, const std::string &argsOrCommand,
                   bool blocking=false);
 std::string GetCurrentWorkdir();
 void RedirectIOToConsole();
-FILE *Fopen(const char* f, const char *mode);
+void UnzipFile(const std::string &fileName, const std::string &prependDir="");
 
 #endif
diff --git a/contrib/mobile/iOS/Onelab.xcodeproj/project.pbxproj b/contrib/mobile/iOS/Onelab.xcodeproj/project.pbxproj
index 5617224b2c0398730ef325fba3d280adb9710ce7..ba27239b771e4a06c3611d72375133a151482e6c 100644
--- a/contrib/mobile/iOS/Onelab.xcodeproj/project.pbxproj
+++ b/contrib/mobile/iOS/Onelab.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		2901F1211BB0086C004C328B /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2901F1201BB0086C004C328B /* libz.dylib */; };
 		2907CCEC193DE6560011341A /* icon_onelab.png in Resources */ = {isa = PBXBuildFile; fileRef = 2907CCEB193DE6560011341A /* icon_onelab.png */; };
 		2988FF1E18E59558001435B6 /* libf2cblas.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2988FF1C18E59558001435B6 /* libf2cblas.a */; };
 		2988FF1F18E59558001435B6 /* libf2clapack.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2988FF1D18E59558001435B6 /* libf2clapack.a */; };
@@ -51,6 +52,7 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		2901F1201BB0086C004C328B /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
 		2907CCEB193DE6560011341A /* icon_onelab.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_onelab.png; sourceTree = "<group>"; };
 		2988FF1C18E59558001435B6 /* libf2cblas.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libf2cblas.a; path = ../../frameworks_ios/libf2cblas.a; sourceTree = "<group>"; };
 		2988FF1D18E59558001435B6 /* libf2clapack.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libf2clapack.a; path = ../../frameworks_ios/libf2clapack.a; sourceTree = "<group>"; };
@@ -122,6 +124,7 @@
 			files = (
 				2988FF1E18E59558001435B6 /* libf2cblas.a in Frameworks */,
 				2988FF1F18E59558001435B6 /* libf2clapack.a in Frameworks */,
+				2901F1211BB0086C004C328B /* libz.dylib in Frameworks */,
 				9C2C3A20187FDF9900E87F78 /* libstdc++.dylib in Frameworks */,
 				9C2C3A1E187FDF9200E87F78 /* libc++.dylib in Frameworks */,
 				9C96089D1712C7F600E1D4A0 /* QuartzCore.framework in Frameworks */,
@@ -170,6 +173,7 @@
 		9C9608391712C16300E1D4A0 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				2901F1201BB0086C004C328B /* libz.dylib */,
 				9C1B9911194F4E0400507EFD /* slepc.framework */,
 				2988FF1C18E59558001435B6 /* libf2cblas.a */,
 				2988FF1D18E59558001435B6 /* libf2clapack.a */,
diff --git a/contrib/mobile/iOS/Onelab/AppDelegate.mm b/contrib/mobile/iOS/Onelab/AppDelegate.mm
index 64579b9e7ebce4cbc3eb2ad829e2dc3bc1bacc18..f155763c203b73b77d9a1a2a738e9d3be31e9c9f 100644
--- a/contrib/mobile/iOS/Onelab/AppDelegate.mm
+++ b/contrib/mobile/iOS/Onelab/AppDelegate.mm
@@ -28,6 +28,17 @@
   else{
     NSLog(@"Leaving models as-is (version %@)", prefsv);
   }
+
+  // Check if there is a model to open
+  NSURL* url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
+  [Utils openModelURL:url];
+
+  return YES;
+}
+
+- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
+{
+  [Utils openModelURL:url];
   return YES;
 }
 
diff --git a/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_ipad.png b/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_ipad.png
index a375bd3d75634a444e0847add7345be901bf7a4e..a3d380259339378786654f875763943625e14c54 100644
Binary files a/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_ipad.png and b/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_ipad.png differ
diff --git a/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_ipad_retina.png b/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_ipad_retina.png
index ce69f13ee2cc67fa2e3bfcaa7adf7acebb9e066e..9d32334991017d7ef43cb57141a76ee95d529fb4 100644
Binary files a/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_ipad_retina.png and b/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_ipad_retina.png differ
diff --git a/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_iphone_retina.png b/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_iphone_retina.png
index 4ad538bdd6d17c10ee4fa1e2cf0003161b255228..f924b3cec5c647292b37c546989a775979978143 100644
Binary files a/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_iphone_retina.png and b/contrib/mobile/iOS/Onelab/Images.xcassets/AppIcon.appiconset/icon_app_iphone_retina.png differ
diff --git a/contrib/mobile/iOS/Onelab/Onelab-Info.plist b/contrib/mobile/iOS/Onelab/Onelab-Info.plist
index e3b855347ce97ef915d99ce9e03ef3b0f585850b..56781a8f5d30bb264254dfdb7fe3a0d8d393f817 100644
--- a/contrib/mobile/iOS/Onelab/Onelab-Info.plist
+++ b/contrib/mobile/iOS/Onelab/Onelab-Info.plist
@@ -68,5 +68,27 @@
       <string>UIInterfaceOrientationLandscapeLeft</string>
       <string>UIInterfaceOrientationLandscapeRight</string>
     </array>
+    <key>CFBundleDocumentTypes</key>
+    <array>
+      <dict>
+        <key>CFBundleTypeName</key>
+        <string>Zip archive</string>
+        <key>CFBundleTypeRole</key>
+        <string>Editor</string>
+        <key>LSItemContentTypes</key>
+        <array>
+          <string>com.pkware.zip-archive</string>
+        </array>
+        <key>UTTypeTagSpecification</key>
+        <dict>
+          <key>public.filename-extension</key>
+          <string>zip</string>
+          <key>public.mime-type</key>
+          <string>application/zip</string>
+        </dict>
+        <key>LSHandlerRank</key>
+        <string>Owner</string>
+      </dict>
+    </array>
   </dict>
 </plist>
diff --git a/contrib/mobile/iOS/Onelab/Utils.h b/contrib/mobile/iOS/Onelab/Utils.h
index 448225c7a40f27ad8c0dd1eb83b10c0514ddc88d..8c1db0a7b7314017e06b5e7e4917a9a7e7d7aa49 100644
--- a/contrib/mobile/iOS/Onelab/Utils.h
+++ b/contrib/mobile/iOS/Onelab/Utils.h
@@ -4,8 +4,7 @@
 
 + (NSString *) getApplicationDocumentsDirectory;
 + (void) copyRes;
-
++ (void) openModelURL:(NSURL*)url;
 + (id) traverseResponderChainForUIViewController:(UIView *)v;
 
-
 @end
diff --git a/contrib/mobile/iOS/Onelab/Utils.mm b/contrib/mobile/iOS/Onelab/Utils.mm
index f76a002ff5ca7575fae207dcf0008752a353d8df..e1525274c615d16c0cd083fa64643577a24494b6 100644
--- a/contrib/mobile/iOS/Onelab/Utils.mm
+++ b/contrib/mobile/iOS/Onelab/Utils.mm
@@ -1,5 +1,7 @@
 #import "Utils.h"
 
+#include <gmsh/OS.h>
+
 @implementation Utils
 
 + (NSString *) getApplicationDocumentsDirectory
@@ -28,6 +30,24 @@
   }
 }
 
++ (void) openModelURL:(NSURL*)url
+{
+  if(!url) return;
+  NSString *filepath = [url path];
+  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+  NSString *docPath = [paths objectAtIndex:0]; //Get the docs directory
+  NSString *extension = [filepath pathExtension];
+  if([extension isEqualToString:@"zip"] || [extension isEqualToString:@"ZIP"]){
+    NSLog(@"Unzipping %@", filepath);
+    UnzipFile([filepath UTF8String], [docPath UTF8String]);
+    NSLog(@"Removing %@", filepath);
+    [[NSFileManager defaultManager] removeItemAtPath:filepath error:nil];
+  }
+  else{
+    NSLog(@"Unknown model file extension: only .zip files are currently accepted");
+  }
+}
+
 + (UIViewController *) traverseResponderChainForUIViewController:(UIView *)v
 {
   id nextResponder = [v nextResponder];
diff --git a/contrib/zipper/unzipper.cpp b/contrib/zipper/unzipper.cpp
index f66db1a1a3c498a5b7d3dab85c7efcf2efe7e8dc..e39367c155534cbd39b41a9ef21677c45a9737e2 100644
--- a/contrib/zipper/unzipper.cpp
+++ b/contrib/zipper/unzipper.cpp
@@ -162,7 +162,7 @@ namespace ziputils
       }
   }
 
-  // Dump the currently open entry to the uotput stream
+  // Dump the currently open entry to the output stream
   unzipper& unzipper::operator>>( std::ostream& os )
   {
     if ( isOpenEntry() )
diff --git a/utils/icons/gmsh.xcf b/utils/icons/gmsh.xcf
index db573a58e8a4ef177907699fab08cc0c2430f814..532271281a0daa46813ede1ccebced73dda611a7 100644
Binary files a/utils/icons/gmsh.xcf and b/utils/icons/gmsh.xcf differ
diff --git a/utils/icons/gmsh_mobile_1024x1024.png b/utils/icons/gmsh_mobile_1024x1024.png
index 5959848fa2bc802ba0c26b9521e54d08ae8afca6..73ecd184873c9406528367771c9743650e03a09c 100644
Binary files a/utils/icons/gmsh_mobile_1024x1024.png and b/utils/icons/gmsh_mobile_1024x1024.png differ