URL schemes on iOS and intent filters on Android provide an open integration point for you to expose functionality in your apps to others. This is particularly helpful if you are building a suite of enterprise apps such as a separate mileage and expense app and want to allow for integration points between them.
This recipe demonstrates how to create a cross-platform URL scheme within your Titanium Enterprise app. We will illustrate how to use this open integration point to access functionality within your Titanium app.
This recipe uses the demoUI
and Ti.SchemeTools
CommonJS libraries to help manage and demonstrate how to create cross-platform URL schemes. This module and other code assets can be downloaded from the source provided by the book. To install these modules, simply copy them to the Resources
folder of your Titanium project as demonstrated in the following screenshot:
After adding the demoUI
and Ti.SchemeTools
modules, you will need to create your application namespaces and use require
to import the module into your app.js
as the following code snippet demonstrates:
//Create our application namespace var my = { isAndroid : Ti.Platform.osname === 'android', scheme : require('Ti.SchemeTools'), ui : require('demoUI') };
To add the ability for other apps to launch this recipe, you must make a few updates to the tiapp.xml
file. The following steps discuss how to create the bencoding-linkrecipe
custom URL scheme:
tiapp.xml
file and make the following changes to the ios
node:<ios> <plist> <dict>
CFBundleURLTypes
node. This is an array of dictionaries describing the URL schemes supported by the bundle. Under this node, you will list all of the URL and scheme names your app will respond to.<key>CFBundleURLTypes</key> <array> <dict>
CFBundleURLName
key. This key contains the abstract name for this URL type. This is the main way to refer to a particular app. To ensure uniqueness, it is recommended that you use a Java-package style identifier.<key>CFBundleURLName </key> <string>bencoding-linkrecipe</string>
CFBundleURLSchemes
keys. These keys contain an array of strings, each of which identifies a URL scheme handled by this type. The following snippet shows URLs for the login, about, and root activities of the app:<key>CFBundleURLSchemes</key> <array> <string>bencoding-linkrecipe</string> <string>bencoding-linkrecipe://about</string> <string>bencoding-linkrecipe://login</string> </array> </dict> </array> </dict> </plist> </ios>
To create a custom URL scheme on Android, you will need to edit the tiapp.xml
file to add an intent filter to listen for the specific android:scheme
and android:host
to be initialized.
tiapp.xml
file and edit the android configuration node.<android xmlns:android="http://schemas.android.com/apk/res/android">
manifest
node.<manifest>
application
node. This node will later be used to generate your project's AndroidManifest.xml
file, so make sure the attributes correctly match your project.<application android:debuggable="false" android:icon= "@drawable/appicon" android:label= "XUrlScheme" android:name="XurlschemeApplication">
<activity android:configChanges="keyboardHidden|orientation" android:label="XUrlScheme" android:name=".XurlschemeActivity" android:theme="@style/Theme.Titanium">
<intent-filter> <action android:name= "android.intent.action.MAIN"/> <category android:name= "android.intent.category.LAUNCHER"/> </intent-filter>
<intent-filter>
android:scheme
and android:host
information. These values act as the protocol used when Ti.Platform.openURL
is used to launch the URL scheme. The following highlighted code allows you to launch the app using a URL such as bencoding-linkrecipe://com.bencoding
.<data android:scheme="bencoding-linkrecipe" android:host="com.bencoding"/>
<category android:name= "android.intent.category.DEFAULT" /> <category android:name= "android.intent.category.BROWSABLE" /> <action android:name= "android.intent.action.VIEW" /> </intent-filter> </activity> </application> </manifest> </android>
This recipe has a simple UI designed to demonstrate how different URL scheme features can be implemented.
Ti.UI.Window
is created; this window is the root Ti.UI.Window
of the app.var win = Ti.UI.createWindow({ backgroundColor: '#fff', title: 'Url Receiver', barColor:'#000',layout:'vertical',fullscreen:false });
Ti.UI.Button
is added to allow the URL Receiver app to launch the App Launcher app created in the Launching one app from another recipe discussed earlier in this chapter.if(!my.isAndroid){ var launcherButton = Ti.UI.createButton({ title:'Press to open AppLauncher Sample', top:30, left:10, right:10, height:45 }); win.add(launcherButton);
launcherButton
is tapped, the app will try to open the App Launcher if the app is available on the device. The highlighted code demonstrates how to use the Ti.Platform.openURL
method to launch the app.launcherButton.addEventListener('click',function(e){ if(Ti.Platform.canOpenURL( "bencoding-linkLauncher://") ){ Ti.Platform.openURL( "bencoding-linkLauncher://"); }else{ alert("Please install the AppLauncher Recipe"); } }); }
This recipe uses the assist object
to help launch a different URL.
var assist = {
openWindow
method opens a specific window based on the URL and parameter values provided.openWindow : function(url,params){ if(url == 'about'){ my.ui.openAboutWindow(); } if (url =='login'){ my.ui.openLoginWindow(params); } },
openPageFromUrl
method is called when an app is opened or resumed to determine if the app has been opened from a third-party app and if so, what routing information has been provided.openPageFromUrl : function(){
hasLaunchUrl
method.if(!my.scheme.hasLaunchUrl()){
my.scheme.session.reset(); return; }
hasChanged
method as highlighted in the following code snippet: if(!my.scheme.session.hasChanged()){
return;
}
getLaunchUrl
method as the following code snippet shows. This URL is then loaded into a session
variable for later use.my.scheme.session.launchUrl = my.scheme.getLaunchUrl();
getCurrentPage
function. This will be used in determining which page to load using the openWindow
method.var requestedPage = my.scheme.getCurrentPage();
my.scheme.session.launchParams = null; if(my.scheme.hasParams()){ my.scheme.session.launchParams = my.scheme.getParams(); }
openWindow
method is called using the requestedPage
and launchParams
created in the preceding steps. The openWindow
method will then open the requested window in the app.assist.openWindow(requestedPage, my.scheme.session.launchParams); } };
In order to have the recipe launch the requested window, listeners must be added to the resumed and open events. The following steps detail how to add the proper event listeners to your app:
app.js
when implementing in your own app.if(!my.isAndroid){ Ti.App.addEventListener( 'resumed', function(e) {
assist.openPageFromUrl
method will be called each time the app is resumed. If no URL information is provided, the main window will be displayed.assist.openPageFromUrl(); }); }
win.addEventListener('open',function(e){
assist.openPageFromUrl
method is called to determine if the app has been opened by a third-party app.assist.openPageFromUrl();
resume
event on the main window. This allows the recipe to detect if a third-party app tries to open the recipe while the app is running in the background.if(my.isAndroid){ win.activity.addEventListener('resume', function(){ assist.openPageFromUrl(); }); } }); win.open();
Cross-platform custom URL schemes are a great low-cost way to provide integration points with third parties. The following section details the end-to-end process for using the Launching one app from another recipe to access different app routes without this recipe's sample app.
This section provides a step-by-step description on how you can launch the About window in the URL Receiver recipe when launched from the App Launcher recipe.
Ti.Platform.openURL('bencoding-linkrecipe://about'),
Ti.Platform.openURL('bencoding-linkrecipe://com.bencoding/about'),
getCurrentPage
method is called, the requestedPage
value will be set to a string with the value of about
.var requestedPage = my.scheme.getCurrentPage();
my.scheme.hasParams
method is called to determine if any parameters have been passed as part of the provided URL. In this case, no additional parameters have been provided, so the session
parameter object remains null
.openWindow
method is then called and the following About window is then opened:This section provides a step-by-step description of launching the Login window in the URL Receiver recipe when launched from the App Launcher recipe. As part of the launch process, the user and token parameters are provided by the App Launcher recipe then used to complete the form within the URL Receiver recipe app.
Ti.Platform.openURL('bencoding-linkrecipe://login?user=chris&token=12345'),
Ti.Platform.openURL( 'bencoding-linkrecipe://com.bencoding/'+ login?user=chris&token=12345'),
getCurrentPage
method is called, the requestedPage
value will be set to a string with the value of login
.var requestedPage = my.scheme.getCurrentPage();
my.scheme.hasParams
method is called to determine if any parameters have been passed as part of the provide URL.{ user:"chris", token:12345 }
openWindow
method is then called providing the requestedPage
and parameter
objects. This will then open the Login page with the parameter used to complete the form as shown in the following screenshot:3.137.217.95