---
title: "Titanium"
slug: "titanium"
updated: 2026-06-09T22:40:39Z
published: 2026-06-09T22:40:39Z
canonical: "docs.xtremepush.com/titanium"
stale: true
---

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xtremepush.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Titanium

Use the Xtremepush SDK to integrate your Titanium apps with the platform

With the Xtremepush module for [Titanium](https://www.appcelerator.com/Titanium/), you can add Xtremepush to both iOS and Android apps quickly.

Make sure your mobile apps are added to Xtremepush, following the guides for [Android](/documentation/docs/android-integration) and [iOS](/documentation/docs/ios-integration).

## Add the Xtremepush Titanium files

Download the Titanium module from the [Titanium SDK releases](/documentation/docs/titanium-sdk-releases) page.

Copy the modules folder from the download into the directory shown below for your respective system, and allow it to merge.

**macOS**

```macOS
~/Library/Application Support/Titanium
```

**Windows**

```Windows
C:\ProgramData\Titanium
```

**Linux**

```Linux
~/.titanium
```

### Modify the `tiapp.xml`

Import the Xtremepush module into your project by opening your project's `tiapp.xml` in TitaniumStudio. You can add the module via the TiApp editor UI by clicking the green add button next to the list of modules,

![950](https://cdn.document360.io/b056e88b-f6c1-4bd2-b5b8-08e9336a17c9/Images/Documentation/b1398c9-Screen_Shot_2014-12-30_at_14.03.06(1).png)

and selecting Xtremepush from the drop down list

![600](https://cdn.document360.io/b056e88b-f6c1-4bd2-b5b8-08e9336a17c9/Images/Documentation/e816efd-Screen_Shot_2014-12-30_at_14.11.17(1).png)

you will see Xtremepush in the list of modules if you have successfully added it.

![431](https://cdn.document360.io/b056e88b-f6c1-4bd2-b5b8-08e9336a17c9/Images/Documentation/adfd2a3-Screen_Shot_2014-12-30_at_14.11.36(1).png)

You can also add the module by editing `tiapp.xml` via the raw XML editor.

Note: For android apps, due to Xtremepush's dependency on play-services, you will also need to add the *ti.playservices* module, in the same way you added the Xtremepush module outlined above.

### iOS

```xml
<modules>
...
<module platform="android">com.xtremepush.xtremepush</module>
<module platform="iphone">com.xtremepush.xtremepush</module>
</modules>
```

You must follow the steps under **Add description for CoreBluetooth** in the [Integrate the iOS SDK](/documentation/docs/ios-sdk-integration) guide, to add the required *CoreBluetooth* description.

If you are also enabling push notifications, you will need to set up your Apple push certificates and add the notifications handling methods described in the [iOS push notifications](/documentation/docs/ios-push-notifications) guide.

If you are adding adding location services, you will need to add the usage descriptions by following the [iOS location permissions](/documentation/docs/ios-sdk-location) guide. If you are using beacons you will also need to add the bluetooth usage message described in the beacons section in the same guide.

Additionally you will need to add the bluetooth flag to your `register.json` in the iOS node:

```json
ios: {
    locationsEnabled: true,
    beaconsEnabled: true,
},
```

### Android

Follow the steps in the guide for [Android push notifications](/documentation/docs/android-push-notifications) to get the configuration values and `google-services.json` file.

In native android, or another framework that uses the gradle build tool you can add a plugin which automatically migrates values from the google-services.json file to the app resources. Titanium requires the configuration values to be manually set from the configuration file.

In your project, edit the file `platform/android/res/values/values.xml`, creating it if it does not already exist:

```xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <! -- Present in all applications -->
    <string name="google_app_id" translatable="false">1:312123...:android:...</string>

    <! -- Present in applications with the appropriate services configured 
    <string name="gcm_defaultSenderId" translatable="false">312123...</string>
    <string name="default_web_client_id" translatable="false">312123...-860....apps.googleusercontent.com</string>
    <string name="google_api_key" translatable="false">AIza..</string>
    <string name="project_id" translatable="false">my_project...</string>
    ...

</resources>
```

The values for the keys in the XML can be found in the `google-services.json` file in these locations:

| XML key | Location in `google-services.json` |
| --- | --- |
| google_app_id | {YOUR_CLIENT}/client_info/mobilesdk_app_id |
| gcm_defaultSenderId | project_info/project_number |
| default_web_client_id | {YOUR_CLIENT}/oauth_client/client_id (client_type == 3) |
| ga_trackingId | {YOUR_CLIENT}/services/analytics-service/analytics_property/tracking_id |
| firebase_database_url | project_info/firebase_url |
| google_api_key | {YOUR_CLIENT}/api_key/current_key |
| google_crash_reporting_api_key | {YOUR_CLIENT}/api_key/current_key |
| project_id | project_info/project_id |

Now you add the Xtremepush module and `ti.playservices` to your app:

![491](https://cdn.document360.io/b056e88b-f6c1-4bd2-b5b8-08e9336a17c9/Images/Documentation/541f94d-Screenshot_2019-02-11_at_11.54.57(1).png)

Edit the `tiapp.xml` file to add the following to the android section:

```xml
<android xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
        <manifest>
            <uses-sdk android:targetSdkVersion="26"/>
            <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
            <!-- REQUIRED for XtremePush -->
            <uses-permission android:name="android.permission.INTERNET"/>
            <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
            <!-- Keeps the processor from sleeping when a message is received. -->
            <uses-permission android:name="android.permission.WAKE_LOCK"/>
            <!-- REQUIRED PERMISSIONS for GCM (Push Notifications) -->
            <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
            <!-- GCM requires a Google account. -->
            <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
            <!-- This app has permission to register with GCM and receive message -->
            <permission android:name=".permission.C2D_MESSAGE" android:protectionLevel="signature"/>
            <uses-permission android:name=".permission.C2D_MESSAGE"/>
            <!-- The two elements above ensure that only this application can receive the messages and registration result -->
            <!-- OPTIONAL XtremePush settings-->
            <!-- REQUIRED FOR GEO-LOCATION-->
            <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
            <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
            <!-- REQUIRED FOR IBEACON -->
            <uses-permission android:name="android.permission.BLUETOOTH"/>
            <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
            <!-- REQUIRED IF you support iBeacon and your app must support devices that don't support BLE -->
            <uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
            <application>
                <activity android:configChanges="orientation|screenSize"
                    android:label="@string/title_activity_inbox"
                    android:name="ie.imobile.extremepush.ui.InboxActivity" android:theme="@style/Theme.Transparent"/>
                <activity android:exported="false"
                    android:name="ie.imobile.extremepush.ui.OnclickPushActivity" android:taskAffinity=""/>
                <service android:name="ie.imobile.extremepush.NotificationOnClickHandlerService"/>
                <activity android:exported="false" android:name="ie.imobile.extremepush.ui.WebViewActivity"/>
                <activity android:exported="false"
                    android:label="Locations are not available"
                    android:name="ie.imobile.extremepush.ui.LocationDialogActivity" android:theme="@android:style/Theme.Dialog"/>
                <!-- REQUIRED FOR GEO LOCATION SERVICES -->
                <service android:name="ie.imobile.extremepush.location.GeoLocationService"/>
                <!-- REQUIRED FOR IBEACON -->
                <service android:enabled="true" android:exported="false" android:isolatedProcess="false" android:label="beacon" android:name="org.altbeacon.beacon.service.BeaconService"/>
              <service android:enabled="true" android:exported="false" android:name="org.altbeacon.beacon.BeaconIntentProcessor"/>
                <service android:name="ie.imobile.extremepush.beacons.BeaconLocationService"/>
                <!-- REQUIRED FOR GCM, LOCATION AND BEACON -->
                <receiver android:name="ie.imobile.extremepush.receivers.CoreBroadcastReceiver">
                    <intent-filter>
                        <action android:name="ie.imobile.extremepush.BEACON_SERVICE_STARTED"/>
                        <category android:name="."/>
                    </intent-filter>
                    <intent-filter>
                        <action android:name="android.intent.action.BOOT_COMPLETED"/>
                        <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
                        <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
                    </intent-filter>
                </receiver>
                <service
                    android:name="ie.imobile.extremepush.beacons.XPBeaconJobService" android:permission="android.permission.BIND_JOB_SERVICE"/>
                <service
                    android:name="ie.imobile.extremepush.util.ImageHandlerJobService" android:permission="android.permission.BIND_JOB_SERVICE"/>
                <receiver android:exported="true" android:name="ie.imobile.extremepush.beacons.BeaconLocationReceiver"/>
                <receiver android:exported="true" android:name="ie.imobile.extremepush.location.GeoLocationBroadcastReceiver"/>
                <receiver android:exported="true" android:name="ie.imobile.extremepush.location.ProxymityAlertReceiver"/>
                <receiver android:name="ie.imobile.extremepush.receivers.XP_App_Update_Receiver">
                    <intent-filter>
                        <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
                        <category android:name="."/>
                    </intent-filter>
                </receiver>
                <service android:name="ie.imobile.extremepush.google.XPFirebaseMessagingService">
                    <intent-filter>
                        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
                    </intent-filter>
                </service>
                <service android:name="com.google.firebase.components.ComponentDiscoveryService">
                  <meta-data android:name="com.google.firebase.components:com.google.firebase.iid.Registrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                </service>
            </application>
        </manifest>
    </android>
```

## Enable in Alloy application

If you are using Alloy, then you would add the following to your `alloy.js` file:

```javascript
// Initialise XtremePush
Ti.Network.registerApp;
Alloy.Globals.xtremepush = require("com.xtremepush.xtremepush");
Alloy.Globals.xtremepush.registerApp(
   {
      appKey: "YOUR_APP_KEY",
      debugLogsEnabled: true,
      impressionsBatchingEnabled: true,
      impressionsStoreLimit: 999,
      inappMessagingEnabled: true,
      inboxBadgeCallback: inboxBadgeCallbackFunction,
      inboxEnabled: true,
      messageResponseCallback: messageResponseCallbackFunction,
      deeplinkCallback: onDeeplinkReceived,
      tagsBatchingEnabled: true,
      tagsStoreLimit: 888,
      startSessionEnabled: true,
      sessionsStoreLimit: 777,
      attributionsEnabled: true,
      foregroundNotificationsEnabled: true,    
      ios: {
         //if using location
         locationsEnabled: true,
         //if sandbox
         sandboxModeEnabled: true
      },
      android: {
         gcmProjectNumber: "YOUR_GCM_PROJECT_NUMBER",
         //if using geo
         geoEnabled: false,
         //if using beacon
         beaconsEnabled: true
      }
   });
```

You can see in the registration above there are three callback functions (`messageResponseCallback`, `InboxBadgeCallback`, `deeplinkCallback`). Examples of how to use these is shown later.

In your controller JavaScript file `index.js` you need to register the app with the Xtremepush servers:

```javascript
Ti.Network.registerForPushNotifications;
```

Because of Titanium's handling of Windows and TabGroups as activities in Android, there are a number of additional options which can be set in your `index.js` file. In this example, `$.index` is the app's main *TabGroup* and `$.b1-14` are example buttons which show some of the options available in the module.

```javascript
Ti.Network.registerForPushNotifications;

var handlePush = function(exampleDataForProcessing) {
	// Handle received push data
	alert(exampleDataForProcessing);
};

var handlePushList = function(data) {
	// Handle received push data
	var pushArray = data.notifications;
	for (var i=0; i < pushArray.length; i++)
	{
		Ti.API.debug(pushArray[i]);
		handlePush(pushArray[i].alert);
	}
};

$.button0.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the trigger event button");
    Alloy.Globals.xtremepush.hitEvent("InAppCampaign");
});

$.button1.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the hit tag button");
    Alloy.Globals.xtremepush.hitEvent("tagTest");
});

$.button2.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the hit impression button");
    Alloy.Globals.xtremepush.hitImpression("ExampleImpression");
});

$.button3.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the release all button");
    Alloy.Globals.xtremepush.sendTags();
    Alloy.Globals.xtremepush.sendImpressions();
});

batching = false;
$.button4.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the toggle batching button");
	batching = !batching;
	Ti.API.debug(batching);
    Alloy.Globals.xtremepush.setTagsBatchingEnabled(batching);
    Alloy.Globals.xtremepush.setImpressionsBatchingEnabled(batching);
});

$.button5.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the getPushList button");
    Alloy.Globals.xtremepush.getPushNotifications({
    	success: handlePushList,
    	offset: 0,
    	limit: 1,
    	read: 0
    });
});

$.button6.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the markRead button");
	Alloy.Globals.xtremepush.markPushAsRead($.pushid.value);
});

$.button7.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the openInbox button");
    Alloy.Globals.xtremepush.openInbox();
});

$.button8.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the Report Message Clicked button with lastPushId = " + lastPushId);
    Alloy.Globals.xtremepush.reportMessageClicked(lastPushId);
});

$.button9.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the Report Message Clicked button with lastPushId = " + lastPushId +" and action 'test'");
	var obj = {id: lastPushId, action: "test"};
    Alloy.Globals.xtremepush.reportMessageClicked(obj);
});

$.button10.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the Report Message Dismissed button with lastPushId = "+lastPushId);
    Alloy.Globals.xtremepush.reportMessageDismissed(lastPushId);
});

$.button11.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the Show Notification button");
    Alloy.Globals.xtremepush.showNotification(lastPushId);
});

$.button12.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the set External Id button");
    Alloy.Globals.xtremepush.setExternalId($.pushid.value);
});

$.button13.addEventListener('click', function(e) {
	Titanium.API.debug("You clicked the set Hit Event With Value button");
	
	var stringOrHash = {0: "number0", 1: "number1"};
	//var stringOrHash = "numbers";
	var obj = {title: "tagString", value: stringOrHash};
    Alloy.Globals.xtremepush.hitEventWithValue(obj);
});

// Declare XtremePush in alloy.js as shown here:
// Alloy.Globals.xtremepush = require("com.xtremepush.xtremepush");

var OS_ANDROID = Ti.Platform.getOsname() === "android";
if (OS_ANDROID) {
	var onRotation = function(e){
		var rotation = false;
		switch(e.orientation) {
	    case Ti.UI.LANDSCAPE_RIGHT:
	        Ti.API.info("LANDSCAPE_RIGHT");
	        rotation = true;
	        break;
	    case Ti.UI.LANDSCAPE_LEFT:
	        Ti.API.info("LANDSCAPE_LEFT");
	        rotation = true;
	        break;
	    case Ti.UI.UPSIDE_PORTRAIT:
	        Ti.API.info("UPSIDE_PORTRAIT");
	        rotation = true;
	        break;
	    case Ti.UI.PORTRAIT:
	        Ti.API.info("PORTRAIT");
	        rotation = true;
	        break;
	    default:
	        Ti.API.info("Unknown!!");
	    }
	    if(rotation)
	    	Alloy.Globals.xtremepush.onRotation();
	};
	
	$.index.orientationModes = [ 
	    Titanium.UI.PORTRAIT, 
	    Titanium.UI.UPSIDE_PORTRAIT,
	    Titanium.UI.LANDSCAPE_LEFT,
	    Titanium.UI.LANDSCAPE_RIGHT
	];
	
	Ti.Gesture.addEventListener('orientationchange', onRotation);
}

$.index.open();
```

> [!TIP]
> Make sure you set the user ID
> 
> It is recommended that at this stage you use our SDK method to set user IDs by following our [dedicated guide](/documentation/docs/set-user-id) to ensure devices can be associated and targeted in your campaigns by your own unique identifier.

## Setting Notification Icon in Android

There is a key that can be set in `register.json` called `setIcon`. If set, the program will attempt to find and use `iconfilenamewithoutextension.png` in the `platform/android/res/drawable` directory and will also search for a color entry with the same name in any of the XML files in the `platform/android/res/values` directory to use as a background colour behind the icon.

```json
setIcon: "iconFileNameWithoutExtension",
```

Android encourages you to set an icon that is in-keeping with their [design guidelines](https://developer.android.com/design/patterns/notifications.html). Further information ca be found in the guide for [Android notification icons](/documentation/docs/android-custom-icon).

## Xtremepush callback functions

`messageResponseCallback`, `deeplinkCallback`, and `inboxBadgeCallback` are JavaScript functions defined in a JavaScript file of your project. After creating, you have to define them in the `registerXtremePush` function:

```javascript
messageResponseCallback: messageResponseCallbackFunction,

inboxBadgeCallback: inboxBadgeCallbackFunction,

deeplinkCallback: onDeeplinkReceived,
```

### messageResponseCallback

```javascript
var messageResponseCallbackFunction = function(xp) {   
   if(xp.response.type === "present"){
   		alert("receive");
   } else if (xp.response.type === "click"){
   		alert("click");
   } else if (xp.response.type === "dismiss"){
   		alert("dismiss");
   }  
};
```

The `response.type` variable shown above can be one of specific values:

- present - when a push notification is received and the app is in the foreground
- click - when a message is clicked
- dismiss - when a message is dismissed

Below is a complete example of custom notification handling, which:

- shows a custom dialog when a push message is received in foreground,
- opens an article page when a message is clicked,
- saves information when one of the message buttons is clicked.

(Each message sent in the campaigns associated with the example, include a custom payload for `articleId`)

```javascript
var messageResponseCallbackFunction = function(xp) {   
	Ti.API.info(''+JSON.stringify(xp));
    if (xp.response.type === "present") {
        openArticle(xp.message.articleId);

        //when the user clicks on a message 
    } else if (xp.response.type === "click") {
        //default click action
        if (!xp.response.hasOwnProperty('action')) {
            openArticle(xp.message.articleId);

            //action for specific button click
        } else {
            if (xp.response.action === "like") {
                likeArticle(xp.message.articleId);
            } else if (xp.response.action === "share") {
                shareArticle(xp.message.articleId);
            }
        }
        //show alert if dismiss button click
    } else if (xp.response.type === "dismiss") {
        alert("message dismiss");
    } 
};
```

### inboxBadgeCallback

This is called when the badge number updates. The badge number is checked when:

- new push message arrives
- application is started
- inbox window is closed

```javascript
var inboxBadgeCallbackFunction = function(xp) {
   //do something with message
   alert('Inbox badge update with number: ' + JSON.stringify(xp)); 
};
```

### deeplinkCallback

This is called when a message with the click action *Go to deeplink* is clicked.

```javascript
var onDeeplinkReceived = function(xp) {
    alert('onDeeplinkReceived called in alloy.js with data:'+JSON.stringify(xp));
};
```

## Foreground notification handling

It is important to define the correct behaviour for the situation when a push notification is received in foreground. You don't want to interrupt the user workflow, but still be delivering important information to the user.

The default behaviour on both iOS and Android is to show OS style notification. But this can be changed, by adding the payload with key `foreground` and value `false` to your campaign.

![607](https://cdn.document360.io/b056e88b-f6c1-4bd2-b5b8-08e9336a17c9/Images/Documentation/67b297d-pg.1(1).png)

Now when the push is received, should the app be in the foreground, the notification will not be displayed.

If you wish to change the default behaviour to not show notifications when app is open, in the register function you can use the following:

```json
foregroundNotificationsEnabled: false
```

## Retrieving your Xtremepush ID

Now that your app is configured for mobile analytics and sending push notifications the final basic feature of Xtremepush is retrieving your Xtremepush ID. This can be accomplished by calling the `deviceInfo` method:

```javascript
Alloy.Globals.xtremepush.deviceInfo
```

This method returns your device's ID as obtained from Xtremepush server. If your device has not received an ID then it has not successfully registered and there is an issue with your integration. If for example you want to quickly output the the device ID to the debug area in TitaniumStudio you would use it like this:

```javascript
Ti.API.debug("deviceInfo" + Alloy.Globals.xtremepush.deviceInfo);
```

If you successfully retrieve the ID it can be used to identify your device on the platform and to send a push notification to just that device.

## User management

Set primary user on platform:

```javascript
Alloy.Globals.xtremepush.setUser("");
```

Set temporary user on platform:

```javascript
Alloy.Globals.xtremepush.setTempUser("");
```
