Skip to content

Instantly share code, notes, and snippets.

@Exilz
Created November 2, 2015 15:20
Show Gist options
  • Save Exilz/3d50cf7614b982157faa to your computer and use it in GitHub Desktop.
Save Exilz/3d50cf7614b982157faa to your computer and use it in GitHub Desktop.
Meteor Cordova loader with cold start
/* This file is only loaded on Cordova-bundled apps and is used only in case
* autoupdate package is used.
* It checks if File plugin is installed and a newer version of the app code can
* be found on persistent storage. In that case those files are dynamically
* added to the page.
* Otherwise a normal app code is loaded (shipped with the app initially).
*/
// Store the potential used URL on cold-start
var invokeURL;
/**
* Execute handleOpenURL on Android which isn't triggered
* automatically contrary to iOS
*/
function androidBridge() {
cordova.exec(
handleOpenURL,
null,
"LaunchMyApp",
"checkIntent", []);
}
/**
* Executed once the URL is caught, set the route to open
* in invokeURL
* @param {string} url full URL opened with the scheme
*/
function handleOpenURL(url) {
setTimeout(function() {
// Remove the scheme
invokeURL = url.replace("aixapp://", "");
window.location = "http://meteor.local/" + invokeURL;
}, 0);
}
document.addEventListener("deviceready", function() {
// On android, execute the Cordova bridge when the device is ready
// A little delay is required
// Note : it's done natively on iOS
setTimeout(function() {
androidBridge();
}, 250);
}, false);
(function() {
var DEBUG_TAG = 'METEOR CORDOVA DEBUG (meteor_cordova_loader.js) ';
var log = function(msg) {
console.log(DEBUG_TAG + msg);
};
var uriToPath = function(uri) {
return decodeURI(uri).replace(/^file:\/\//g, '');
};
var readFile = function(url, cb) {
window.resolveLocalFileSystemURL(url, function(fileEntry) {
var success = function(file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
var result = evt.target.result;
cb(null, result);
};
reader.onerror = fail;
reader.readAsText(file);
};
var fail = function(evt) {
cb(new Error("Failed to load entry: " + url), null);
};
fileEntry.file(success, fail);
},
// error callback
function(err) {
cb(new Error("Failed to resolve entry: " + url), null);
});
};
var loadTries = 0;
var loadFromLocation = function(location) {
var cordovaRoot =
uriToPath(window.location.href).replace(/\/index.html$/, '/');
var httpd = cordova && cordova.plugins && cordova.plugins.CordovaUpdate;
var retry = function() {
loadTries++;
if (loadTries > 10) {
// XXX: If this means the app fails, we should probably do exponential backoff
// or at least show a message
log('Failed to start the server (too many retries)');
} else {
log('Starting the server (retry #' + loadTries + ')');
loadFromLocation(location);
}
};
setTimeout(function() {
httpd.startServer({
'www_root': location,
'cordovajs_root': cordovaRoot
}, function(url) {
// go to the new proxy url
if (typeof invokeURL !== 'undefined') {
// The app has been opened from a scheme, start
// the server with the correct route
window.location = "http://meteor.local/" + invokeURL;
} else {
// The app was opened without a scheme, start
// the server with the default route
log("Loading from url: " + url);
window.location = url;
}
}, function(error) {
// failed to start a server, is port already in use?
log("Failed to start the server: " + error);
retry();
});
}, 0);
};
// Fallback to the bundled assets from the disk. If an error is passed as an
// argument, then there was a problem reading from the manifest files. If
// no error is passed, then we simply do not have any new versions.
var fallback = function(err) {
if (err) {
log("Couldn't load from the manifest, falling back to the bundled assets.");
} else {
log('No new versions saved to disk.');
}
var location = cordova.file.applicationDirectory + 'www/application/';
location = uriToPath(location);
loadFromLocation(location);
};
var loadVersion = function(version, localPathPrefix) {
var versionPrefix = localPathPrefix + version + '/';
var location = uriToPath(versionPrefix);
loadFromLocation(location);
};
var loadApp = function(localPathPrefix) {
readFile(localPathPrefix + 'version', function(err, version) {
if (err) {
log("Error reading version file " + err);
fallback(err);
return;
}
loadVersion(version, localPathPrefix);
});
};
document.addEventListener("deviceready", function() {
var startLoading = function() {
if (!cordova.file) {
// If the plugin didn't actually load, try again later.
// See a larger comment with details in
// packages/meteor/startup_client.js
setTimeout(startLoading, 20);
return;
}
var localPathPrefix = cordova.file.dataDirectory + 'meteor/';
loadApp(localPathPrefix);
};
startLoading();
}, false);
})();
@ccorcos
Copy link

ccorcos commented Sep 14, 2017

@Exilz can you explain how this script works?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment