browser-deeplink
browser-deeplink copied to clipboard
Does it work in iOS 8?
Hey Hampus,
I have been having mixed results on Android (it doesn't work initially, but only when you click back - I use chrome 40).
This article http://www.tuaw.com/2014/06/18/ios-8-safari-can-block-ads-from-automatically-redirecting-to-the/ explains that it would pretty much impossible on latest iOS, or am I mistaken?
Just realized that this would only break fallback behavior: opening the app store. Perhaps that's not such a good choice as default behavior in that case
Right. On another note, I was thinking that the plugin API could be re-structured a little. Perhaps it would be useful to be able to check whether the user has the app installed or not. Which takes a callback which returns whether it was successful or not. Would love your input on this.
On the client side you could call:
deeplink.canOpen("myapp://xyz", myCustomCallback);
or just
deeplink.open("myapp://xyz");
Haven't tested this code, but I imagine it could look something like this:
// Parse android URL
var parseUri = function(uri) {
if (isAndroid() && !navigator.userAgent.match(/Firefox/)) {
var matches = uri.match(/([^:]+):\/\/(.+)$/i);
uri = "intent://" + matches[2] + "#Intent;scheme=" + matches[1];
uri += ";package=" + settings.android.appId + ";end";
}
return uri;
}
// Check if device can open a certian link
var canOpen = function(uri, callback) {
if (!isMobile()) {
callback(new Error("Not on mobile"), false);
}
var ts = Date.now();
var timeout = setTimeout(function() {
var wait = settings.delay + settings.delta;
if ((Date.now() - ts) < wait) {
callback(new Error("Could not open app"), false);
}
}, settings.delay);
var iframe = document.createElement("iframe");
iframe.onload = function() {
clearTimeout(timeout);
iframe.parentNode.removeChild(iframe);
callback(null, true);
};
iframe.src = parseUri(uri);
iframe.setAttribute("style", "display:none;");
document.body.appendChild(iframe);
}
// Open app or fallback
var open = function(uri) {
canOpen(uri, function(err, success) {
if (!err || settings.fallback === "openAppStore") {
window.location.href = parseUri(uri);
} else if (typeof settings.fallback === "function") {
settings.fallback(err, success);
}
});
}
No idea if this would work with the Android intent thing though
Hey, that's a great add-on, I like it!
I would say that the callback of canOpen
doesn't have to be called with both an error and success because they're mutually exclusive: I'd stick with only the error param. Then in open
you can just check that argument for truthy.
Another thing I just thought about, what if the iframe has a delay with opening (because of some external unexpected reason) and it loads after the timeout function ran, the callback gets called twice right? Maybe we should add to the setTimeout
function, before var wait = ...
, timeout = null;
to tell us that the timeout has happened. Then in the iframe.onload
function we add before clearTimeout(timeout)
, if (!timeout) return;
Now, the callback will never be called twice. [ it's a bit unhandy that comments don't have line numbers :) ]
In general, I wouldn't know if it works on Android, because on Chrome 40 it doesn't work like it's intended (almost wrote intent
ed there). Do you know of a different method than the iframe
method?
I'm deploying your plugin tomorrow on our site to redirect users to our app! :)