Push is one of the things you should add to any app, even if at first you’d only use it for broadcast messages. It’s the best way to keep in touch with your users, even when – or exactly because – they haven’t used your app for months.
Urban Airport
To make this a no-brainer I’ve written an CommonJS module that wraps the iOS and Android versions of Appcelerator’s open-source UrbanAirship module, and is compatible with both Alloy and Classic projects. It hides you from all implementation differences in registering for and receiving push notifications.
The module is available via my UTiL repo.
Walk-through
Let me take you through the exact steps of setting up push via Urban Airship with this wrapper:
- Sign up for the free developer edition of Urban Airship.
- Create two apps of which one you add a DEV suffix to the Application Name and select Development as Production Status.
- Follow the Set Up Your Application With Apple paragraph of the UA iOS Getting Started guide.
- Follow the Google Setup paragraph of the UA Android Getting Started guide.
- Download the latest Android and iOS (look for
.zip
) version of Appcelerator’s module and extract them to your project’s modules folder or the global~/Library/Application Support/Titanium/modules
folder. - For both the Android and iOS module copy the file in the module’s
example/platform
folder to the exact same location under your project. - Set the development and production keys and secrets in both files. Get them from the Urban Airship dashboard under Settings > API Keys for both of the 2 apps you have created.
- For Android, in the same
airshipconfig.properties
file, set transport togcm
andgcmSender
to the Project Number that can be found on the Overview tab of the project you created at step 4. - Download the urbanairport wrapper and place it in your project’s
app/lib
orResources
if you have use Titanium Classic. - In your
alloy.js
or classicapp.js
initialize the wrapper:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
var urbanairport = require('urbanairport'); urbanairport.register({ debug: true, // Show debug info // Sets push types sound: true, // iOS + Android (default) vibrate: true, // Android (default) badge: true, // iOS (default) alert: true, // iOS (default) // Set any property and call any single-property method of the extended module autoBadge: false, // Enable compatibility mode (see below) compatibility: true, // On Android these will be automatically set once UA is flying alias: 'John', tags: 'single', // Supports both a single or Array of strings! callback: function(e) { // The only callback you need // Registration failed if (e.type === 'error') { alert('Sorry, no push for you: ' + e.error); // Registration done } else if (e.type === 'success') { alert('Your token is: ' + e.deviceToken); // Received notification } else if (e.type === 'callback') { // Properties are normalized for iOS and Android: // e.payload === e.data === e.data.aps // e.message === e.data.alert === e.data.aps.alert alert(e.message); } } }); // Manually disable/re-enable push urbanairport.disable(); // enable(); // Append tags instead of resetting them urbanairport.addTags('foo'); // Both single and Array supported // Set any property and call any single-property method of the extended module urbanairport.showOnAppClick = true; |
Compatibility mode
It’s important to be aware of when the callback will be called with e.type === 'callback'
. On both iOS and Android this will only get called when the app is running. Only on iOS the app needs to run in the foreground or be called to the foreground by tapping on the notification. On Android the callback will be fired twice for the same notification if the app was running (in background) when it was received and then the app was opened because the user tapped on it. The second time e.clicked
will be TRUE
, but since the app might also not have been running when the notification was received, you cannot just ignore calls with this value.
To make up for this, you can use compatibility: TRUE
with the register
method. This will trigger the wrapper to do 2 things:
- Default
showOnAppClick
toTRUE
so that tapping the notification will open the app, just like on iOS. - Create a hash for each notification and only call the callback the first time. Pretty much like on iOS, but with the advantage of it being called also when the app is in the background.