These days, I am trying to develop an iOS app which allows other apps to launch it. In iOS, we can customize URL schemes in our app. It will tell iPhone to launch this app when it finds other apps trying to open an URL which fit the URL schemes. This will be my another SWIFT tutorial which also helps me be familiar with SWIFT language.
Customize URL Schemes in iOS App
To allow other App to launch our app, we need to customize URL schemes in our App. After we install the app in iPhone, it will register itself to handle the URL’s scheme. Here is the steps to customize URL schemes in iOS app.
We can also add the customized URL scheme in the Info.plist. The result will be same. Here is my Info.plist:
Launch iOS App from Browser
After above steps, we succeed to customize our own URL scheme. In the iPhone Safari, we can type “JMSCustomizeURL://” to open our app.
As same concept, we can launch an iOS app when we open a web page. Actually, one requirement of my current project is open my iOS app whenever user clicks a button in the website. To implement this feature, we can add following code in our web page:
$(document).ready(function() { var user_agent_header = navigator.userAgent; if(user_agent_header.indexOf('iPhone')!=-1 || user_agent_header.indexOf('iPod')!=-1 || user_agent_header.indexOf('iPad')!=-1) { setTimeout(function() { window.location="JMSCustomizeURL://data";}, 25); } });
How to Pass Data to App When Launching From Outside
When we are using customized URL to launch the app, we can pass data along with the URL. For example:
JMSCustomizeURL://data?a=1&b=2
If we are working in old version before iOS 9, we can try to implement following AppDelegate functions:
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool { print("Called By: \(sourceApplication)"); print("Full URL \(url.absoluteString)"); print("Scheme: \(url.scheme)"); print("Query String: \(url.query)"); return true; }
or
func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool { print("Full URL \(url.absoluteString)"); print("Scheme: \(url.scheme)"); print("Query String: \(url.query)"); return true; }
The function openURL is recommended. Actually, when we implement the openURL, the handleOpenURL function will be omitted automatically. In iOS 9, the following function is recommended to call:
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool { print("Called By: \(options["UIApplicationOpenURLOptionsSourceApplicationKey"])"); print("Scheme: \(url.scheme)"); print("Query String: \(url.query)"); //learning tips: get all key-value pairs in options for (key, value) in options { print(key, value); } return true; }
Once we get the query string in the url, we can use following code to get the key-value pair of the query string in SWIFT.
if(url.query != nil) { let queryKeyValue = url.query!.componentsSeparatedByString("&"); for keyValue in queryKeyValue { let kv = keyValue.componentsSeparatedByString("="); if(kv.count > 1) { print("\(kv[0]): \(kv[1])"); } } }
How to Open Another App by openURL
Besides launching an APP by URL in the browser, we can also launch the App from another App. For example, we can launch Facebook app to share photos from our camera app. As long as we know the URL scheme, we are able to launch the app in our apps. Here, I will create a new APP. The App will be implemented by SWIFT again! I will put a button on the stage. When we click the button, we will call openURL to launch the app I created just now.
The source code is very simple. First, I will call canOpenURL to check if there is a App to handle given URL scheme. If there is, I will call openURL to launch the APP. Here is the example source code;
@IBAction func OpenMyTestApp(sender: AnyObject) { let myAppURL:NSURL = NSURL(string: "JMSCustomizeURL://data?a=1&b=2")!; let application:UIApplication = UIApplication.sharedApplication(); if(application.canOpenURL(myAppURL)) { application.openURL(myAppURL); } }
After saving and running the app, I get following error message:
2016-01-20 19:42:13.519 OpenAppByURL[38294:399556] -canOpenURL: failed for URL: “JMSCustomizeURL://” – error: “This app is not allowed to query for scheme JMSCustomizeURL”
OK! This is a new restriction in iOS 9. In iOS 9.0, we must declare the URL schemes we want to call canOpenURL. We can add these URL schemes in LSApplicationQueriesSchemes in the Info.plist. For each URL scheme you want your app to use with this method, add it as a string in this array.
Then, how about the apps built against an earlier version of iOS but is running in iOS 9.0? iOS allows us to call this method canOpenURL on 50 distinct URL schemes. After hitting this limit, subsequent calls to this method return false. Here is my Info.plist example:
Get Full Source Code Under $1.99
In this tutorial, I have created two Swift iOS Apps. You can download a zip file which contains both iOS App projects after donating a small fee $1.99. It is a small money to support me continuing writing tutorials. You have the full permission to use the source code.
I wanted to know if we can call out to any Apps within Apps. For example we are using an iOS Learning Management System, and we want to be able to open an ebooks reader app from the LMS app. Is this at all possible?
Yes, but you need to know the URL scheme to call the ebooks reader.
Hi,
I paid by paypal but I will need help docs the project.
The doc is the article itself.
How we can test this? Do we need to submit app to app store first.
Don’t need. To develop ios app, you must have iOS dev account. Just run the source code in xcode with your real ios device, you can test it.
Hi James, nice to meet you. I have a doubt: I created an app and in the appdelegate I programmed the func private func application(application: UIApplication, openURL with the line application.openURL(myAppURL as URL); – When this line is executed the app quit and returns to open again in a eternal loop. Do I need to comment this line ?
Please don’t do that. application.openURL could launch another app from your app. In appdelegate, you’d better just do some app initialization job. For other task, implement in your first ViewController.