Summary I have an app with a correctly functioning URL scheme that I'd like to launch from a web app stored on the home screen, and the normal JavaScript redirect methods don't seem to work.
Details I'm trying to create an iOS web app, to be opened in full-screen mode from a link saved on the Home Screen. The web app needs to open a specific native app. I have already registered the url scheme for the native app, and verified that it works correctly - I can open the native app by typing the scheme directly into my Safari address bar, for instance. I can also open it from other applications using the +openURL: method of UIApplication. I would like to also open it with certain arguments from a native web app that can be added to the home screen.
What I'm trying to do is use JavaScript like so inside the native app:
window.location = "myapp://myparam";
When using this code inside the web app I get an alert saying:
"Cannot Open myWebAppName - myWebAppName could not be opened. The
error was "This URL can't be shown".".
This same javascript when executed within Safari works correctly. I get the same result using window.location.replace("myapp://myparam").
The html for the web app is:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>untitled</title>
<meta name="generator" content="TextMate http://macromates.com/">
<meta name="author" content="Carl Veazey">
<!-- Date: 2012-04-19 -->
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta names="apple-mobile-web-app-status-bar-style" content="black-translucent" />
</head>
<body>
<script type="text/javascript" charset="utf-8">
if (window.navigator.userAgent.indexOf('iPhone') != -1) {
if (window.navigator.standalone == true) {
window.location = "myapp://myparam";
} else {
document.write("please save this to your home screen");
};} else {
alert("Not iPhone!");
document.location.href = 'please-open-from-an-iphone.html';
};
</script>
</body>
</html>
What am I doing wrong here? I'm pretty inexperienced with javascript and mobile web so I suspect I'm just missing something obvious.
Your code works if its in mobile safari but NOT if its from a bookmark on the iOS desktop. Never tried it that way before, but thats the issue. If i just set your JS to
<script type="text/javascript" charset="utf-8">
window.location = "myapp://myparam";
</script>
It works in browser, but when bookmarked it fails. It might have to do something with how the url is loaded when its bookmarked since there is no chrome? My guess is that apple doesn't want booked mark pages to access local apps. Also, I've noticed that if I bookmark a locally hosted page, that works in mobile safari, I can't get it to load via bookmark. Its really odd....
Best recommendation I have for you is to make it
<meta name="apple-mobile-web-app-capable" />
instead of
<meta name="apple-mobile-web-app-capable" content="yes" />
This way it will be on the home screen, but will unfortunately load with the chrome. Thats the only solution I can think of.
If you need to open an iOS application if it is installed and also want to preserve your page's functionality, the location.href = 'myapp://?params=...'; won't help since if myapp:// is not registered, the redirect leads user to unreachable destination.
The safest bet seems to be in using an iframe. The following code will open an iOS app if it is installed and will not cause a failure if it is not (though it may alert a user that the page could not be reached if the app is not installed):
var frame = document.createElement('iframe');
frame.src = 'myapp://?params=...';
frame.style.display = 'none';
document.body.appendChild(frame);
// the following is optional, just to avoid an unnecessary iframe on the page
setTimeout(function() { document.body.removeChild(frame); }, 4);
Try like this:
The index page
<html><head></head><body>
<?php
$app_url = urlencode('YourApp://profile/blabla');
$full_url = urlencode('http://yoursite.com/profile/bla');
?>
<iframe src="receiver.php?mylink1=<?php echo $app_url;?>" width="1px" height="1px" scrolling="no" frameborder="0"></iframe>
<iframe src="receiver.php?mylink2=<?php echo $full_url;?>" width="1px" height="1px" scrolling="no" frameborder="0"></iframe>
</body>
</html>
the receiver.php page:
<?php if ($first == $_GET['mylink1'])) { ?>
<script type="text/javascript">
self.window.location = "<?php echo $first;?>";
</script>
<?php } if ($second == $_GET['mylink2'])) { ?>
<script type="text/javascript">
window.parent.location.href = "<?php echo $second ;?>";
//window.top.location.href=theLocation;
//window.top.location.replace(theLocation);
</script>
<?php } ?>
To provide an update, iOS14 Beta7 doesn't appear to be opening any local apps via their registered x-callback URLs. š
<?php
// Detect device type
$iPod = stripos($_SERVER['HTTP_USER_AGENT'],"iPod");
$iPhone = stripos($_SERVER['HTTP_USER_AGENT'],"iPhone");
// Redirect if iPod/iPhone
if( $iPod || $iPhone ){
header('Location:http://example.com');
}
?>
The above will redirect the browser to the inputted URL (http://example.com/) if the device is an iPod or iPhone. Add the script to the top of your web app, make sure you save it as a .php file rather than .html.
Source:
http://www.schiffner.com/programming-php-classes/php-mobile-device-detection/
Related
I have a very simple HTML page that connects the page to my Twilio backend:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/#twilio/voice-sdk#2.0.1/dist/twilio.min.js"></script>
<script>
connection = null;
call = async () => {
const response = await fetch(
"https://my.token.endpoint/token"
);
const data = await response.json();
const device = new Twilio.Device(data.token);
connection = await device.connect();
connection.on(
"error",
(err) =>
(document.getElementById("error-display").innerHTML = err.message)
);
};
stop = () => {
connection?.disconnect();
connection = null;
};
</script>
</head>
<body>
<button onclick="call()">call</button>
<button onclick="stop()">stop</button>
<p id="error-display"></p>
</body>
</html>
When I open the HTML page from my Windows 10 machine using Chrome 102.0.5005.115, clicking the call button successfully connects to my Twilio backend.
However when I open the HTML page from my Android 12 mobile device using Chrome 102.0.5005.125, clicking the call button triggered the following error:
AcquisitionFailedError (31402): The browser and end-user allowed permissions, however getting the media failed. Usually this is due to bad constraints, but can sometimes fail due to browser, OS or hardware issues.
I was getting this issue beforehand when trying to register the device before setting the current devices. However, since you're only seeing this on mobile, my guess is it's a permissions issue preventing the audio devices to be set. On your phone, can you try removing all permissions for your browser? Then in the code, print out the devices available input and output devices by console logging these:
device.audio.availableInputDevices
device.audio.availableOutputDevices
After refreshing the page, your phone should prompt you to allow audio permissions. If not, may need to take a gander through your settings.
I'm trying to calculate the load time and page size of different URLs/Pages similar to the developer tools performance tab but in javascript. But the current code only calculates its current page instead of a different URL. Is there any way for me to do this because with my research I have no luck.
<html>
<head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<script type="text/javascript">
var start = new Date().getTime();
function onLoad() {
var now = new Date().getTime();
var latency = now - start;
alert("page loading time: " + latency+"\n"+"Start time:"+start+"\n"+"End time:"+now);
alert("Load_size:"+document.getElementsByTagName("html")[0].outerHTML.length + "KB");
}
</script>
</head>
<body onload="onLoad()">
<!- Main page body goes from here. -->
</body>
</html>
It will not be possible to read the runtime parameters of a page outside the page your javascript is running on.
Part of the security model is to avoid being able to inspect the runtime of other pages. This is called the "sandbox". You'll need to build a plugin that breaks the sandbox to inspect the domLoad / domReady and other performance events.
Good news though, you probably have one built in! The console for modern browsers shows all those events in the timeline tab.
If you're trying to make a service that attempts to evaluate the runtime of other pages, you'll need to load those in a virtual web browser on the server and interpret the results using selenium or something similar.
You can try this to calculate the load time of a page:
<script type="text/javascript">
$(document).ready(function() {
console.log("Time until DOMready: ", Date.now()-timerStart);
});
$(window).load(function() {
console.log("Time until everything loaded: ", Date.now()-timerStart);
});
</script>
edit: this will only work on pages where this JS code will run, so if you cant insert code onto the page you wont be able to run it.
I'm having following problem. I have following code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Click Me test site</title>
</head>
<body>
Click Me
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script>
$(document).ready(function() {
var handler = function codeclick(event) {
var link_new = $('a').attr('co-target');
if (link_new) {
window.open(link_new, '_blank');
}
}
$('a').bind('click.codeclick', handler);
});
</script>
</body>
</html>
You can see it in action here
The expected behaviour on desktop is that the page in co-target attribute is opened in new tab/window and the one in href attribute is opened in current tab.
On internal mobile facebook browser it should open just the co-target attribute page (intended). But on Google mobile iOS app it opens the page in href attribute (unintended).
Does anyone encountered similar problem before and maybe have some clues what should I do to make it right? There is no need that the page in co-target has to open. I just want it that on both facebook and google app it open one of it, not different one in each.
I create a Badge on Google plus developers : https://developers.google.com/+/web/badge/
but when I copy and past the code into my HTML file the badge not showing. Here is my code :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Google + Badge</title>
</head>
<body>
<!-- Place this tag where you want the widget to render. -->
<div class="g-page" data-href="https://plus.google.com/109600806421917664383" data-rel="publisher"></div>
<!-- Place this tag after the last widget tag. -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/platform.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</body>
</html>
What I'm doing wrong !? Thanks
adeneo's JSFiddle wasn't working for me either (Chrome 35, OSX). First I had to whitelist it in the Disconnect extension. Then I was getting the console error
Uncaught ReferenceError iframes is not defined
which, according to http://www.jesse-smith.net/fixed-google-plus-1-button-working/ and Google PlusOne Button has errors on Chrome, is caused by having 3rd-party cookies blocked.
If you're using Chrome as well (and the problem is caused for you by blocking 3rd-party cookies as well), there should be a cookie icon on the right-hand side of your URL bar. Click it, click "Show cookies and other site data...", change to the "Blocked" tab and allow all the 3rd-party cookies from *.google.com domains.
You can also go Settings > Show advanced settings > Privacy, click the āContent Settingsā button and enable 3rd-party cookies everywhere.
Unfortunately I wasn't able to find a way to get your G+ button to work in browsers with 3rd-party cookies disabled.
I have written a Firefox extension that requires the background document's URL. Normally, JavaScript's document.URL could achieve this - but this is different.
Please see my example below:
As can be seen, there are 4 tabs open:
BBC Homepage
Add-ons Manager
Amazon.com
Stack Overflow
And, the page currently being viewed is StackOverflow.com (.. indeed).
My question is: how can I retrieve the URL of the user's active window? (i.e. http://www.stackoverflow.com).
Below is the panel.html code.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href=panel.css rel="stylesheet" type="text/css">
</head>
<body>
<header><h3>Where aM I</h3></header>
This Mozilla extension will display the current <i>background</i> URL
<main>
<fieldset>
<legend>Click the Button</legend>
<button onclick="PageViewing()">Fetch</button>
</fieldset>
</main>
<script>
function PageViewing() {
alert(document.URL);
}
</script>
</body></html>
EDIT
If placed in the main.js file, this code snippet works:
var tabs = require("sdk/tabs");
console.log("URL of active tab is " + tabs.activeTab.url); //yields SO.com
So in the context of my example, how could I retrieve it from P-Name/lib, for use in the P-Name/data directory - as a variable?
You have to establish a communication protocol between module and content script. This is done with port.
In your main.js
panel.port.on('askactivetaburl', function(){
panel.port.emit('sentactivetaburl', tabs.activeTab.url);
})
and in your panel script
self.port.on('sentactivetaburl', function(activetaburl){
// work with activetaburl
});
self.port.emit('askactivetaburl');