76

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?

RedBlueThing
  • 42,006
  • 17
  • 96
  • 122
Rob
  • 4,149
  • 5
  • 34
  • 48
  • 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. – Tomas McGuinness Apr 21 '11 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. – Rob Apr 21 '11 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); – dijipiji Oct 30 '12 at 15:57

6 Answers6

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.

computingfreak
  • 4,939
  • 1
  • 34
  • 51
Doug Stephen
  • 7,181
  • 1
  • 38
  • 46
  • You could look at iHasApps for a list of apps on the users device. – 1789040 Dec 05 '12 at 02:26
  • Thanks Doug for providing these links. I had a similar question to this post. I mentioned you in my [post](http://stackoverflow.com/questions/16857162/detect-if-application-is-installed-on-users-macosx-from-browser/16896388#16896388) (please edit it if you don't want to be mentioned there). – Silex Jun 03 '13 at 12:48
  • 8
    Links are dead. – Greg Hilston May 24 '17 at 20:49
  • [Here's an article about how to do this with your own app.](http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html) – Alexey Golikov Sep 21 '17 at 07:55
44

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.

Pang
  • 9,564
  • 146
  • 81
  • 122
Ievgen
  • 1,596
  • 16
  • 13
  • 23
    but still you will see the error message which come from safari if the app do not exist. – shebelaw Feb 28 '12 at 22:05
  • 10
    Does anyone know how to avoid that error message from safari if the app is not installed? – davidk Sep 07 '12 at 20:38
  • 1
    Yes thats right, how we can avoid that error message "Can not open page" within safari if app is not installed?? – Hardik Thakkar Nov 30 '12 at 12:01
  • 1
    Even though the error message is displayed, this still accomplishes the task of getting the user to the app store. A good solution! – karlbecker_com Feb 23 '13 at 19:47
  • 3
    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](http://smartappbanners.com/) are sufficient for your needs). Would love to be proven wrong. – johndodo May 19 '13 at 19:59
  • 3
    @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. – devios1 Oct 20 '13 at 19:53
  • @devios1 Does this work in iOS 9 and above? – mjsxbo Dec 29 '20 at 09:55
  • @NirvanAnjirbag AFAIK it should still work. – devios1 Jan 05 '21 at 21:22
  • 2
    This does not works, the setTimeout is always executed even after the intent redirection – Sagar Khan Mar 18 '21 at 10:48
22

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://"]];
Gavin Hope
  • 2,173
  • 24
  • 38
  • here are the docs: https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIApplication_Class/#//apple_ref/occ/instm/UIApplication/canOpenURL: – John Bachir Mar 14 '16 at 22:11
  • to find customurl of an app : https://www.amerhukic.com/finding-the-custom-url-scheme-of-an-ios-app – computingfreak May 07 '20 at 10:49
13

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.

st.derrick
  • 4,769
  • 2
  • 24
  • 25
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");
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
    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. – Gustav Mar 07 '14 at 10:25