Matryoshka is a package for Cordova/PhoneGap 3.0 and above that lets you do live, on-device updating of the app's code.
Notice: This should be considered experimental code at the moment — it may not be ready for prime time. I've been testing it on iOS and Android. Other platforms are totally untested. Testers are welcome, but please back up your code before starting and report any issues you might encounter. If you want to add a new platform, see below.
This is working more or less the way I want it, so there shouldn't be any breaking changes, but obviously that can't be guaranteed at this stage.
Matryoshka is for Cordova/Phonegap 3.0 and above. It would probably be possible to make it work with earlier versions.
##What does it do?
For a quick overview, see the Demo Video
Clone the repo and run:
npm install -g
from the repo root folder.
If you want to remove it later, use:
npm uninstall -g matryoshka
A future (stable) release will be published to the npm registry, but for now you'll have to get it directly from github.
Note that you only need to do this once (unless you need to add more plugins or the like).
<access origin="*" />
##Using Matryoshka with Your Own Projects
matryoshka [platform] where platform is ios, android, etc.
You may also specify an optional port number after the platform. If not supplied, the server will run on port 8089.
Your system's firewall may ask for permission to receive incoming connections. If so, grant it.
When the Matryoshka server starts, it should tell you which port number and IP address(es) it is using. Make a note of the external IP address (i.e., the one that is not 127.0.0.1).
After it starts up, the server will begin monitoring the top-level www folder for changes and should automatically propagate those changes into the platform-specific www folder (e.g., platforms/ios/www).
Next, run the Matryoshka app on your device and enter the IP address and port number for the Matryoshka server. Tap Go and your own app's web code should load, replacing the Matryoskha app's web code.
Once the server and app are both running, any changes under the top-level www folder in your project (editing, adding, or deleting files) should be reflected in the running Matryoshka app within a few seconds.
Cool beans, huh?
When you're finished, just terminate the Matryoshka server (Control-C on most platforms).
##Known and Potential Limitations, Issues, and Workarounds
If your Matryoshka server is running on a machine on the public internet, anyone will be able to see your code. It is recommended that you run the server on a machine behind a NAT (or otherwise firewalled against incoming connections from the public net). However, you also need to make sure that your devices can connect to the server (see the discussion in troubleshooting below). Note that the built-in web server in Cordova also works this way. These servers are for testing and development, and are not hardened/secured for general use on the public internet.
Before building and submitting a production app to the iOS App Store, remove both the matryoshka-client.js and the script elements for it in your HTML files. I guarantee that Apple's reviewers won't be amused by finding dynamic code loading in a production app. :-)
In theory, most plugins should work as long as the plugin is added to both the Matryoshka app and the app under test. In practice there are some exceptions which will be noted here as they're discovered. At this early stage, "seems to work" in this list should be interpreted as "tried with one of the simple examples in the docs" rather than "rigorously tested". :-)
Anything that uses a file:// URL to load stuff from the device is likely to cause trouble. When your app is running in Matryoshka, it's being loaded as a remote site over http. Browser security restrictions prevent direct access to local files from remote web sites. Normally this is a very good thing (you don't want random web pages reading files from your hard drive) but it's troublesome for an app of this type. There may be a way around this (configuring security on the web view, e.g.) — investigating.
Accelerometer: seems to work on iOS. Not working on one of my Android devices (but does work on the other). Investigating.
Camera: partial support on both iOS and Android. Taking pictures works, as does returning the image with Camera.DestinationType.DATA_URL. Camera.DestinationType.FILE_URI partially works, in the sense that you can take a picture, but suffers from the "loading file:// from http://' issue discussed above.
Capture: untested. Likely also suffers from the "loading file:// from http://' issue.
Compass: seems to work on both Android (if the device has a compass) and iOS (previous weird behavior on iOS went away after recalibrating compass).
Connection: seems to work on both Android and iOS.
Contacts: seems to work on both Android and iOS.
Device: seems to work on both Android and iOS.
Events: deviceready seems to work on both Android and iOS. Others untested.
File: seems to work on both Android and iOS (tested using my gapfile gapfile plugin).
Geolocation: seems to work on both Android (if the Android device has GPS, some don't) and iOS.
InAppBrowser: seems to work on both Android and iOS.
Notification: seems to work on both Android and iOS (both dialog and vibration).
Storage: seems to work on both Android and iOS. However, do note that the local storage for your app running stand-alone and the local storage for your app running in Matryoshka are going to be different.
If it doesn't work, check these possible causes:
Are the Matryoshka app and server able to see each other? One way to check is to go into the regular browser on the mobile device and try to load http://(server ip address):(server port)/index.html. If it comes up in the browser, you're good. If not, make sure that your device is on the same network as the Matryoshka server (e.g., on the same wireless LAN). It definitely won't work if your device is on the cellular data network and your server is behind a NAT or firewall.
window.location='http://(server IP address):(server port)/index.html'
If things really get messed up, you may need to terminate and restart the Matryoskha app. On iOS 7, this is done by double-tapping on the Home button, then swiping upward on the app's mini-screenshot (not the icon). On Android, you can do this by Force Stopping from the Applications menu (YMMV on where this is located — it's under Settings on both of my Android devices).
##Adding a New Platform
If you want to try it with a platform that isn't currently supported, load up lib/matryoshka.js and add entries for the proper folders for your platform in buildfolders and assetfolders. The entry in buildfolders is likely to be 'platforms/[platformname]', but the entry for assetfolders may vary. This is the folder where the generated www folder for your platform should be placed. For example, on iOS, the app's www folder is located at /platforms/ios, while for Android it's /platforms/android/assets. I have no idea for the others; firefoxos seems to follow the same pattern as iOS, but I have no way of actually testing it. Pull requests welcome on this.
Once you've added the correct folders, reinstall the matryoshka node module with
npm install -g and restart any matryoshka servers you might have running.
Matryoshkya was written by Tony Hursh. Of course, major credit must go to the fine folks behind node (and all the node modules) and Cordova/PhoneGap itself.
I can be reached at tony.hursh -- AT -- gmail.com. However, please don't email bug reports or feature requests. Use the issue tracker instead. I get a lot of email. If I can't deal with your issue at the exact moment I get the mail, there's a good chance it will sink into the uncharted depths of my inbox, never to be seen again. :-)
If you want want to hire me to do something, have a look at my profile on the PhoneGap developer portal. I'm currently available for remote contract work.