Determine if an app exists and launch that app on iOS - ios4

Is there a way to check iOS to see if another app has been installed and then launched? If memory serves me this was not possible in early versions but has this been changed?

Doable, but tricky.
Launching installed apps, like the FB or Twitter apps, is done using the Custom URL Scheme. These can be used both in other apps as well as on web sites.
Here's an article about how to do this with your own app.
Seeing if the URL is there, though, can be tricky. A good example of an app that detects installed apps is Boxcar. The thing here is that Boxcar has advanced knowledge of the custom URL's. I'm fairly (99%) certain that there is a canOpenURL:, so knowing the custom scheme of the app you want to target ahead of time makes this simple to implement.
Here's a partial list of some of the more popular URL's you can check against.
There is a way to find out the custom app URL : https://www.amerhukic.com/finding-the-custom-url-scheme-of-an-ios-app
But if you want to scan for apps and deduce their URL's, it can't be done on a non-JB device.
Here's a blog post talking about how the folks at Bump handled the problem.

There is a script like the following.
<script type="text/javascript">
function startMyApp()
{
document.location = 'yourAppScheme://';
setTimeout( function()
{
if( confirm( 'You do not seem to have Your App installed, do you want to go download it now?'))
{
document.location = 'http://itunes.apple.com/us/app/yourAppId';
}
}, 300);
}
</script>
Calling this script from the web (Try to start MyApp), you can determine if your app with scheme "yourAppScheme" is installed on the device or not.
The App will launch if it is installed on the device and "yourAppScheme" is registered in it.
If the app is not installed you can suggest the user to install this app from iTunes.

To check if an app is installed (e.g. Clear):
BOOL installed = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"clearapp://"]];
To open that app:
BOOL success = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"clearapp://"]];

Hides the error message if the app is not installed
At Branch we use a form of the code below--note that the iframe works on more browsers. Simply substitute in your app's URI and your App Store link.
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
window.onload = function() {
// Deep link to your app goes here
document.getElementById("l").src = "my_app://";
setTimeout(function() {
// Link to the App Store should go here -- only fires if deep link fails
window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8";
}, 500);
};
</script>
<iframe id="l" width="1" height="1" style="visibility:hidden"></iframe>
</body>
</html>
There's a second possibility that relies on cookies first and the javascript redirect only as a fallback. Here's the logic:
When a user without the app first taps on a link to your app, he or she is redirected straight to the App Store. This is accomplished by a link to your app actually being a dynamically-generated page on your servers with the redirect. You create a cookie and log a "digital fingerprint" of IP address, OS, OS version, etc. on your backend.
When the user installs the app and opens it, you collect and send another "digital fingerprint" to your backend. Now your backend knows the link is installed On any subsequent visits to links associated with your app, your servers make sure that the dynamically-generated redirect page leads to the app, not the App Store, based on the cookie sent up with the request.
This avoids the ugly redirect but involves a ton more work.

To my understanding, because of privacy issues, you can't see if an app is installed on the device. The way around this is to try and launch the app and if it doesn't launch to have the user hit the fall back url. To prevent the mobile safari error from occurring I found that placing it in an iframe helps resolve the issue.
Here's a snippet of code that I used.
<form name="mobileForm" action="mobile_landing.php" method="post">
<input type="hidden" name="url" value="<?=$web_client_url?>">
<input type="hidden" name="mobile_app" value="<?=$mobile_app?>">
<input type="hidden" name="device_os" value="<?=$device_os?>">
</form>
<script type="text/javascript">
var device_os = '<? echo $device_os; ?>';
if (device_os == 'ios'){
var now = new Date().valueOf();
setTimeout(function () {
if (new Date().valueOf() - now > 100)
return;
document.forms[0].submit(); }, 5);
var redirect = function (location) {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', location);
iframe.setAttribute('width', '1px');
iframe.setAttribute('height', '1px');
iframe.setAttribute('position', 'absolute');
iframe.setAttribute('top', '0');
iframe.setAttribute('left', '0');
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
};
setTimeout(function(){
window.close()
}, 150 );
redirect("AppScheme");

I struggled with this recently, and here is the solution I came up with. Notice that there is still no surefire way to detect whether the app launched or not.
I serve a page from my server which redirects to an iPhone-specific variant upon detecting the User-Agent. Links to that page can only be shared via email / SMS or Facebook.
The page renders a minimal version of the referenced document, but then automatically tries to open the app as soon as it loads, using a hidden <iframe> (AJAX always fails in this situation -- you can't use jQuery or XMLHttpRequest for this).
If the URL scheme is registered, the app will open and the user will be able to do everything they need. Either way, the page displays a message like this at the bottom: "Did the app launch? If not, you probably haven't installed it yet .... " with a link to the store.

Related

Electron Webview get response

I am very new to electron so I may be going about this all wrong.
We have a few web apps internally that are all working and I wanted to practice by building one of them into electron.
What I need to do is load our SSO login page within the app and then listen for a cookie/session to be created after authentication has been successful.
I am using a webview like so:
<div style="width:100%; height:100%">
<span class="loading loader" id="loading" name="loading"></span>
<webview class="ssologin" src="https://example.com/resources/ldap.php" autosize="on" style="min-width:755px; min-height:640px"></webview>
</div>
This loads the login page for ldap/sso. After I login, it would normally take you to the web application you were going to before you were re-routed to SSO do to not having a valid session.
I am trying to figure out how I can listen for a cookie/session so that I know that they have authenticated and we get a response back.
Essentially, I need this valid session in order to make future API calls in the app to endpoints so I want to try and use this existing authentication implementation without having to include other modules and mess with all that.
Any suggestions?
Just in case you didn't know: Electron does not currently recommend to use <webview>:
We currently recommend to not use the webview tag and to consider alternatives, like iframe, Electron's BrowserView, or an architecture that avoids embedded content altogether.
Cf https://electronjs.org/docs/api/webview-tag#warning
You probably need to set a partition on your <webview>:
<webview src="https://github.com" partition="persist:github"></webview>
<webview src="https://electronjs.org" partition="electron"></webview>
Sets the session used by the page. If partition starts with persist:, the page will use a persistent session available to all pages in the app with the same partition. if there is no persist: prefix, the page will use an in-memory session. By assigning the same partition, multiple pages can share the same session. If the partition is unset then default session of the app will be used.
Cf https://electronjs.org/docs/api/webview-tag#partition
With that you can (from the main process) access the cookie of the session:
const {session} = require('electron');
const sess = session.fromPartition('persist:foobar');
const cookies = sess.cookies;
Then you can listen for changed events on that cookie object:
Emitted when a cookie is changed because it was added, edited, removed, or expired.
cookies.on('change', () => {
// do something when your SSO cookie is set
});
Cf https://electronjs.org/docs/api/cookies#event-changed

want to write node.js http client for web site testing

I am new to node.js
I want to try to write node.js client for my web site testing
(stuff like login, filling forms, etc...)
Which module should i use for that?
Since I want to test user login following other user functionality
it should be able to keep session like browser
Also any site where it has example of using that module?
Thanks
As Amenadiel has said in the comments, you might want to use something like Phantom.js for testing websites.
But if you're new to node.js maybe try with something light, like Zombie.js.
An example from their home page:
var Browser = require("zombie");
var assert = require("assert");
// Load the page from localhost
browser = new Browser()
browser.visit("http://localhost:3000/", function () {
// Fill email, password and submit form
browser.
fill("email", "zombie#underworld.dead").
fill("password", "eat-the-living").
pressButton("Sign Me Up!", function() {
// Form submitted, new page loaded.
assert.ok(browser.success);
assert.equal(browser.text("title"), "Welcome To Brains Depot");
})
});
Later on, when you get the hang of it, maybe switch to Phantom (which has webkit beneath, so it's not emulating the Dom).

Mimicking the features of node-webkit using a client and a server

I'm trying to find out whether it's possible to invoke node.js functions from a web page. Is there any way to make node.js functions accessible from Google Chrome (so that they are run on the node.js server), as shown here?
(I'm aware that it's possible to do this using node-webkit (a non-standard Chromium implementation) without modifying the code, but I'd prefer to do this using an unmodified browser, which will require the code shown below to be modified in some way.)
<html>
<body>
<script type = "text/javascript">
var exec = require('child_process').exec; //node.js function
</script>
<p onclick = "exec('firefox')">
Click here to launch the Firefox web browser.
</p>
</body>
</html>
No, this is not possible, for clear security reasons.
You only have available to you what the browser gives you. node-webkit is the closest thing available, and does not meet your requirements.
NW has own method like node exec :
var gui = require('nw.gui');
gui.Shell.openItem('firefox', ,function(error, stdout, stderr) { });

How Do I Broadcast Json To Users via Node JS server?

Goal: After user saves data to my mysql DB, a JSON teaser of the newly saved content is broadcasted to all users.
What are some quick and dirty solutions to achieve this? I am working with php/mysql. Got a taste of Socket.io, and a node.js server listening on the side....
Any good links would be greatly appreciated.
Background--------
After many years of working with php, I have decided to jump onto the NodeJS Bandwagon- and have no clue to do anything other than the vanilla "Hello World".... This is my starting point. Thanks again!!
If you would like to broadcast to all users including yourself, then you should use:
io.sockets.emit('global', {data: 'this will be received by everyone'});
If you would like to broadcast to all users without yourself being notified, then you should use:
socket.broadcast.emit('Hello everyone!');
Hope this helps!
Can you define what you mean by "broadcast" in this context?
Do you want to display an alert on a web page?
If so, do you wish to alert only those users who are currently viewing pages on your site or those who come to your site during a period of time? If the later, do you care if the alert appears to a single user more than once?
Socket.IO is one way to transmit/receive messages to/from a remote browser, but without a client-side handler that has some way of displaying your message to the user, it's kind of moot.
I've found now.js to be a far better abstraction of browser<-->server communications as shown in this possible solution that will display an alert on pages currently viewed by your users:
Step 1: Install now.js (remove the -g if you don't want now installed globally):
npm install -g now
Step 2: Create a HTTP server and cause it to listen on a port 80
var PORT=80,
http=require('http'),
nowjs=require('now'),
app=http.createServer(requestHandler).listen(PORT), // create your server
everyone=nowjs.initialize(app); // initialize now on your listening server
function alertUsers(msg){ // sends msg to showAlert() callback on clients
everyone.now.showAlert(msg);
}
function requestHandler(req,res) {
...
...
/*
* Ok, something has happened you want to inform your currently
* connected users of...
*
* if the thing can happen as a result of a request, do it here
*/
var msg="Whoohoo! Something's happened!";
alertUsers(msg);
...
...
}
// or if it happens somewhere else, just call alertUsers() there.
Step 3: And then in the browser-side HTML:
<html>
<head>
<style type="text/css">
.alert { background-color:red; color:white; font:24pt bold sans-serif; }
.hidden { display:hidden; visibility:none; }
</style>
</head>
<body>
<div id="alert" class="alert hidden">
<div class="main-content">
<!-- main page content -->
</div>
<script type="text/javascript" src="...load jQuery here..."></script>
<script src="/nowjs/now.js"></script> <!-- *SEE NOTE BELOW -->
<script type="text/javascript>
$(document).ready(function(){
// after the document has finished loading
now.showAlert=function(msg){ // define your callback function
$('#alert').removeClass('hidden').text(msg);
};
});
</script>
</body>
</html>
* Note that the <script src="/nowjs/now.js"></script> request is magic in that the referenced file doesn't really exist server-side at that location. By running nowjs.initialize() on your http server instance, you're setting things up so that nowjs will intercept the request for /nowjs/now.js and serve it back to the client without invoking your requestHandler().
Also, this solution does not display your alert to anyone who connects after the alert is sent from the server. If you want to do that, you'll need to do something different.

how to check if my javascript browser extension works

I am trying to create a simple javascript based extension for Google Chrome that takes data from one specific iframe and sends it as part of a POST request to a webpage.
The web page that sends the data submitted by POST request, to my email address.
I tried running the extension, it looks to be running fine, but I am not getting any email.
The servlet which receives form data is very simple, I dont think there is any error in it.
What I want is some way to check if the javascript based extension works or not.
The javascript code is given below-
var mypostrequest=new ajaxRequest()
mypostrequest.onreadystatechange=function(){
if (mypostrequest.readyState==4){
if (mypostrequest.status==200 || window.location.href.indexOf("http")==-1){
document.getElementById("result").innerHTML=mypostrequest.responseText
}
else{
alert("An error has occured making the request")
}
}
}
var namevalue=encodeURIComponent("Arvind")
var descvalue=encodeURIComponent(window.frames['test_iframe'].document.body.innerHTML)
var emailvalue=encodeURIComponent("arvindikchari#yahoo.com")
var parameters="name="+namevalue+"&description="+descvalue &email="+emailvalue
mypostrequest.open("POST", "http://taurusarticlesubmitter.appspot.com/sampleform", true)
mypostrequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
mypostrequest.send(parameters)
UPDATE
I made changes so that the content in js file is invoked by background page, but even now the extension is not working.
I put the following code in background.html:
<script>
// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript( null, {file: "content.js"});
});
chrome.browserAction.setBadgeBackgroundColor({color:[0, 200, 0, 100]});
</script>
Looking at your code looks like you are trying to send cross domain ajax request from a content script. This is not allowed, you can do that only from background pages and after corresponding domains are declared in the manifest. More info here.
To check if your extension works, you can open dev tools and check if there any errors in the console. Open "Network" tab and see if request was sent to your URL. Place console.log in various places in your code for debugging, or use full featured built in javascript debugger for step-by-step debugging.

Resources