78

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?

3
  • 1
    I think that must be possible somehow - I say that because the Facebook SDK implementation will launch the Facebook app if installed otherwise it will fallback to Safari. You do need to know some info about the other app, because with Facebook you need to add some registration info to your own app. Commented Apr 21, 2011 at 15:33
  • Yes, I figure if you know the app identifier that you could check and start it somehow. But I can't find any reference to this. I was hoping someone has tried this. Commented Apr 21, 2011 at 15:49
  • 5
    Easy enough, e.g.: NSURL *urlApp = [NSURL URLWithString:@"fb://"]; BOOL canOpenFBApp = [[UIApplication sharedApplication] canOpenURL:urlApp]; printf("\n canOpenFBApp:%i \n",canOpenFBApp); Commented Oct 30, 2012 at 15:57

7 Answers 7

66

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.

Sign up to request clarification or add additional context in comments.

4 Comments

You could look at iHasApps for a list of apps on the users device.
Thanks Doug for providing these links. I had a similar question to this post. I mentioned you in my post (please edit it if you don't want to be mentioned there).
Links are dead.
45

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 (<a href="#" onclick="startMyApp()">Try to start MyApp</a>), 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.

9 Comments

but still you will see the error message which come from safari if the app do not exist.
Does anyone know how to avoid that error message from safari if the app is not installed?
This seems like a hack, and an unstable one too... After the redirect (document.location) JS should stop executing, so the function in setTimeout should never be executed. Not that I know of a better way (unless iOS Smart App Banners are sufficient for your needs). Would love to be proven wrong.
@johndodo That's exactly the point. If the redirect succeeds, JavaScript will stop executing, thus avoiding the timeout block (however, it really should be checking the current time against the initiating time because it will continue executing when the user goes back into Safari later). If the redirect fails, on the other hand, the user will see two messages: the first ugly one provided by Safari already mentioned, but then a second user-supplied and somewhat apologetic message to explain the first. It's not ideal, but is at least not as confusing as just seeing that first error.
This does not works, the setTimeout is always executed even after the intent redirection
|
23

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://"]];

2 Comments

14

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.

2 Comments

Universal Links are coming :)
Is the my_app here the appname or the appID?
2

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");

Comments

1

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.

1 Comment

This will still show the ugly "Safari cannot open the page because the address is invalid."-alert if the app is not installed, right? I really want to find a method to get pass that alert. The solutions suggesting automatic redirect after a short interval or displaying a confirm are not good enough for my project.
0

Don't forget to add the schema URL to your Info.plis LSApplicationQueriesSchemes key value; otherwise canOpenURL will always return your a false value.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.