Determine if an app exists and launch that app on iOS
Asked Answered
A

6

77

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?

Adrenocorticotropic answered 21/4, 2011 at 15:28 Comment(3)
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.Crystallography
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.Adrenocorticotropic
Easy enough, e.g.: NSURL *urlApp = [NSURL URLWithString:@"fb://"]; BOOL canOpenFBApp = [[UIApplication sharedApplication] canOpenURL:urlApp]; printf("\n canOpenFBApp:%i \n",canOpenFBApp);Gladsome
S
68

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.

Smothers answered 21/4, 2011 at 15:54 Comment(4)
You could look at iHasApps for a list of apps on the users device.Ferritin
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).Shadowgraph
Links are dead.Canfield
Here's an article about how to do this with your own app.Emmer
C
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.

Chloral answered 25/10, 2011 at 8:42 Comment(9)
but still you will see the error message which come from safari if the app do not exist.Skippie
Does anyone know how to avoid that error message from safari if the app is not installed?Kuebbing
Yes thats right, how we can avoid that error message "Can not open page" within safari if app is not installed??Autoharp
Even though the error message is displayed, this still accomplishes the task of getting the user to the app store. A good solution!Zippora
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.Boyceboycey
@Boyceboycey 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.Tait
@Tait Does this work in iOS 9 and above?Septillion
@NirvanAnjirbag AFAIK it should still work.Tait
This does not works, the setTimeout is always executed even after the intent redirectionVotive
N
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://"]];
Nihility answered 20/11, 2014 at 7:16 Comment(2)
here are the docs: developer.apple.com/library/prerelease/ios/documentation/UIKit/…:Inventor
to find customurl of an app : amerhukic.com/finding-the-custom-url-scheme-of-an-ios-appFlashover
B
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.

Bruges answered 20/2, 2015 at 21:35 Comment(2)
Universal Links are coming :)Bruges
Is the my_app here the appname or the appID?Kironde
O
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");
Ourselves answered 21/5, 2015 at 0:44 Comment(0)
K
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.

Khano answered 15/2, 2014 at 18:35 Comment(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.Androw

© 2022 - 2024 — McMap. All rights reserved.