App to App Switching in iOS (Part I)

Hyperlinks in websites has been there since the dawn of time, and have well served the human kind to redirect the audience to helpful targets, easing away cross referencing and seamless navigation. So, when the civilisation moved on, from websites to mobile apps, hyperlinks evolved to app-links to keep pace with the ever increasing demand of inter-app travel for users. Even more so, because mobile applications, having always been seen something of a scaled down version of desktop apps to account for the low memory in smartphone, differs from their desktop ancestors mainly in the fact that they do not serve the user with diverse functionalities by its very nature. One app can be very good at doing something, but it must depend on its siblings to do something else. This clear demarkation gives the user more choice and flexibility to get the best of everything and keep the competition tense, productive and healthy. What was once “One App to Rule ‘em all” is now a constellation of apps who perform their part of the job (with absolute bureaucracy), with absolute brilliance, better than anyone in the market.

Application switching guidelines

As we are talking about a two way communication between the apps, we need to consider both of the scenarios —

  • The current app is invoking another app and
  • The current app is being invoked by another app

Before moving into the discussion on how to achieve them, there are certain precautions and guidelines that one should be aware of.

Invoke another app from current app

While launching another app, the invoking app does not need to be very wary about its own security, unless there are some data that are being exchanged between the apps. It is always good to remember the below points when invoking an application —

  1. The launched app might not be the one you intended to launch and you can never really ensure that. An app can fake itself to be one of yours to fool the user into giving away the credentials. So, if you are transferring any data be sure to encrypt them so that only the intended application may have the sufficient means to decrypt that.
  2. It is a good user experience to allow the user to launch Apple app store to download the app, if it is not installed. So,  its better to check if the app is installed in the device and accordingly launch app store or the app itself
  3. Unless you have very obvious reason for not doing so, its always advisable to inform the user that by invoking the other app he/she is actually going to leave the current app (in the background)
  4. Finally, your app is going background and has the potential risk of getting terminated in case memory become scarce. So, prepare by serialising and saving data to persistent store, so that the user does not lose anything

Invoke current app from another app

Invoking the current app from another app is the riskier part of the whole functionality. Any application can know about the URL scheme used by the current application and launch it by invoking the scheme. So, automatically potential risk of divulging data to unintended recipient gets increased. Following are a few cautionary words to be remembered in this aspect —

  1. A malicious app can pass many parameters along with the URL scheme which, if not handled properly and being relied upon, can cause havoc in the security of the system and  of the user
  2. If you are accepting commands from trusted applications, be wary because hackers will try every possible combinations of keywords to guess the commands that you accept blindly from your trusted apps
  3. Do not accept any commands with arbitrary path names as they can easily be substituted with other path names by people with malicious intentions

Application Switching Techniques

The following paragraphs will delve into simple application switching techniques most commonly used at the time of this writing.  As discussed before, an application switching functionality has 2 aspects, launching another app from current app and launching current app from another app. We will discuss about them separately in the following paragraphs:

Invoke another app from current app

To invoke another app from current app, the custom URL scheme of the other app is required. Custom URL scheme of the app is generally defined in the info.plist file of an application and is generally a short word. The app can be launched using the custom scheme as a protocol. For example, to launch an app with custom URL scheme as “myscheme”, the app must be launched with an URL like — myscheme://.  However, easy as it is to invoke an app from the current app, it also makes sense to take steps to direct the user to the app in the easiest way. Directing an user to the app store when the app is installed in the device, or trying and failing to launch an app just because it is not installed in the device — both have  adverse effect on the user experience. So, the following steps would be providing a good user experience —

  1. On the tap of the application link, ask the user whether he/she is fine to be moving away from the current app
  2. If no, no action to be taken
  3. If yes, internally the application will check if the app is installed in the device by using UIApplication class’s canOpenURL method which returns YES when the targeted app is present in the device and is responsive to the openURL message
  4. If the canOpenURL returns YES, invoke the target application using openURL and passing the target applications custom URL scheme as a NSURL object to it
  5. If the canOpenURL returns NO, that means the application is not installed in the device and the app store needs to be opened. The app can then pass the message openURL to the UIApplication’s shared instance with the target application’s app store URL as a parameter

Following is the code for the above mentioned logic —

  1. Code for showing alert about leaving the app
    [[[UIAlertView alloc] initWithTitle:@"Info" message:@"This will take you out of the current application and will try to launch the target app. Do you want to proceed?" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show];
  2. Code for launching the app store or the app conditionally based on the existence of the app in the device:
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
     NSURL *customURL = [NSURL URLWithString:@"myappurl://"];
     NSURL *appStoreURL = [NSURL URLWithString:@"itms://"];
     if ([[UIApplication sharedApplication] canOpenURL:customURL])
     [[UIApplication sharedApplication] openURL:customURL];
     [[UIApplication sharedApplication] openURL:appStoreURL];

Invoke current app from another app

When an application is invoked from another application, the invoked application may or may not be running in the background. Since in iOS only one instance of an application can run at a time, the iOS can intelligently understand whether to launch the app, or to show app already running in the background. Following is a flow chart depicting the case when the application is launched (from not-running state) —

Flow chart for launching app

Following is another flow chart which depicts the scenario when an app already running in the background gets invoked because of some other app called its custom URL scheme.

Launching app from background

Inside the launched app, all the handling of the URL invoked with should be dealt with in the following method —

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *) sourceApplication annotation:(id)annotation

If you are intending to do nothing with any parameters passed into your app, just returning NO will be safe and secure. However, if the received parameters are to be used, it should be filtered out for unwanted commands first.

Next Steps

The next step in this journey would be to display a bar at the top of your application which will allow you to glide back to the application which launched the current foreground application. Whether its a good practice or a outright bad one is an argument for another time, but for the time being we will concentrate on how to achieve this. We are going to discuss this in the next part of this discussion which I am going to post soon.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s