| Subcribe via RSS

Building Server Push Notifications with Appcelerator Titanium Cloud

May 5th, 2012 | 54 Comments | Posted in Apple, apps, Titanium

Appcelerator has blessed us developers with cloud services since release of Titanium 2. Even free registered users get 1 million server push messages a month free. Server push notification means that you can send users push notifications even when the app is not running on the device.
Cloud also gives lots of nice stuff for developers which eases the pain and the need of a custom back-end for your mobile app.

Although Appcelerator allows server push, many developers find it difficult to set it up. One of them being myself a couple of days ago, therefore I thought I’d give back to the community and wrote a little tutorial showing hot to make Server Push Notifications work for your app. I will concentrate mostly on certificate management, which is the most painful part of setting up Push Notifications on Apple devices.

 

1. Start a new Titanium project in Titanium studio. For this example we’ll call it PushTest and give an app ID com.teemusk.pushtest

Project setup in Titanium Studio

Project Setup. Make sure Cloud-enable this application is checked. Alternatively you can enable Cloud services on tiapp.xml editor.

Add a simple code to your app.js to open a window and run your app on simulator once so it’ll get registered and enabled on Titanium. The code for app.js looks like this right now:

var win = Titanium.UI.createWindow({
title:'TestPush iOS App',
backgroundColor:'#fff'
});
win.open();

1.3. Run your app on simulator once to see if it is ok. There should be nothing on the screen. Just white background.

2. Set up the cloud services and Certificates

2.1. Go to https://my.appcelerator.com/apps and find PushTest app from the list (you must be logged in to see that).
Your newly created app on Appcelerator

As you can see you have Cloud services already enabled for this app. That’s great.
2.2. Click Manage and check the settings for this app
2.3. Click Settings on top tabs. As you can see Apple iOS push certificates is empty. You will have to obtain a certificate from Apple iOS Provisioning Portal (you have to be an Apple developer to do this).
2.4. go to iOS Provisioning Portal through developer.apple.com and to Provisioning portal after logging in on Member area.
2.5. Create new App ID by choosing App IDs from left and then clicking ‘New App’ on top right corner.
2.6. Add PushTest as an app name and com.<yourdomain>.pushtest as an app id. Then click Done.
2.7. Now as you can see from the list your app is not quite set up for push notifications. You will have to configure it.
Push notifications not configured on Provisioning Portal

2.8. click Configure next to your app and Enable Apple Push Notifications on the following screen.

2.9. Next part is a bit tricky as you’ll have to work through some different things to do this, but basically you will have to get a certificate for your app to get Push Notifications working. Click Configure button next to ‘Development Push SSL Certificate’. The page that opens up is self explanatory. But in case you don’t want to read all this stuff then shortly it’ll go as follows:
2.10. Open up Keychain Access software on your mac. Choose ‘Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority…’ from top menu.
Obtain a Certificate

This will open up a dialog where just click ‘Save to Disk’ and ‘OK’ and then save the incoming certificate to your Desktop. Click ‘Save’ and ‘Done’.
2.11. You have a certificate on your desktop. It’s filename is ‘CertificateSigningRequest.certSigningRequest’.
2.12 Go back to Provisioning Portal and upload this file back to Apple. click ‘continue’, ‘choose file’, choose the certificate you just saved on desktop and click ‘Generate’. This will take a couple of seconds, but after it’s done click next and download the certification with your name called ‘aps_development.cer’.

2.13. Double click on the downloaded .cer file and it’ll be added to Keychain Access.
2.14. Select the certificate in Keychain Access with the name com.<yourdomain>.pushtest and right click (or command click) on it to open popup menu. Choose Export “Apple Development iOS Push Services” from this menu and save this file with extension .p12 on your disk. You will be asked for a password. Remember what you put in there. This is the final certificate you will have to upload to Appcelerator my apps.

2.15. Now, go back to Appcelerator my app settings for PushTest app and browse and upload the newly created .p12 certificate. Also add the password you chose in 1.16. in the box next to it.

Great, you’re done with the painful part of the tutorial. Now it’s good old titanium scripting again.

3. Code the app
I consider this tutorial not to be a scripting tutorial. Therefore I will just paste my app.js code below. I tried to comment my code so you can see what each function does. This code works on your phone. To run it on your phone you will have get a provisioning profile from Apple Provisioning Portal. I also uploaded an app.js for you to download and investigate.
The results of this code will add 4 buttons on the stage. When running the app on your phone the first time start pressing the buttons from top and after each tap wait for success alert dialog. Once you reached the end you’re all set.
var Cloud = require('ti.cloud');var trace = Ti.API.info;
var user_device_token = Ti.App.Properties.getString("device_token",null)var win = Titanium.UI.createWindow({
title:'TestPush iOS App',
backgroundColor:'#fff'
});
win.open();function init(){
buildUI();
}
setTimeout(init,500);function buildUI(){
var register_local_push = Ti.UI.createButton({
width:200,
height:30,
top:30,
title:"REGISTER LOCAL PUSH"
});
win.add(register_local_push);
register_local_push.addEventListener('click',getDeviceToken);var register_user_btn = Ti.UI.createButton({
width:200,
height:30,
top:70,
title:"REGISTER USER"
});
win.add(register_user_btn);
register_user_btn.addEventListener('click',registerUser);var login_btn = Ti.UI.createButton({
width:200,
height:30,
top:110,
title:"LOGIN"
});
win.add(login_btn);
login_btn.addEventListener('click',login);var register_server_push_btn = Ti.UI.createButton({
width:200,
height:30,
top:150,
title:"REGISTER SERVER PUSH"
});
win.add(register_server_push_btn);
register_server_push_btn.addEventListener('click',subscribeToServerPush);
}//REGISTER USER ON CLOUD
function registerUser(){
trace("REGISTER");
Cloud.Users.create({
username: "new_username",
password: "new_password",
password_confirmation: "new_password",
first_name: "Firstname",
last_name: "Lastname"
}, function (e) {
if (e.success) {
alert("USER CREATED SUCCESSFULLY.");
// user created successfully
} else {
// oops, something went wrong
alert("USER not created. something went wrong "+e);
}
});
}//LOGIN TO CLOUD AS A USER THAT WE CREATED BEFORE
function login(){
Cloud.Users.login({
login: 'new_username',
password: 'new_password'
}, function (e) {
if (e.success) {
var user = e.users[0];
alert('Success:\\n' +
'id: ' + user.id + '\\n' +
'first name: ' + user.first_name + '\\n' +
'last name: ' + user.last_name);
} else {
alert('Error:\\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}//REGISTER LOCAL PUSH NOTIFICATION HERE
function getDeviceToken(){
trace("REGISTERING LOCAL PUSH");
Titanium.Network.registerForPushNotifications({
types: [
Titanium.Network.NOTIFICATION_TYPE_BADGE,
Titanium.Network.NOTIFICATION_TYPE_ALERT,
Titanium.Network.NOTIFICATION_TYPE_SOUND
],
success:function(e)
{
user_device_token = e.deviceToken;
Ti.App.Properties.setString("device_token",user_device_token);
alert("Device token received "+user_device_token);
},
error:function(e)
{
alert("Error during registration: "+e.error);
},
callback:function(e)
{
// called when a push notification is received.
alert("Received a push notification\n\nPayload:\n\n"+JSON.stringify(e.data));
}});

}
//REGISTER SERVER PUSH
function subscribeToServerPush(){
Cloud.PushNotifications.subscribe({
channel: 'friend_request',
type:'ios',
device_token: user_device_token
}, function (e) {
if (e.success) {
alert('Success'+((e.error && e.message) || JSON.stringify(e)));
} else {
alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e)));
}
});
}

 The code above is also uploaded as a file. You can download it here

4. Send your first Server Push notification
After running the app.js code on your iPhone start to tap the buttons from top to bottom. After each tap wait for the alert message with success message.
The app looks like this:

When you’re done with this sequence you’ll ready to send your first push.
Go to Appcelerator my apps section. Choose ‘notifications’ from the tab on top and check that you have a device registered with server push. My window looks like this:

Close the app on your phone (close it totally from bottom). Fill in the fields and push send notification. Now wait a bit to receive the push on your phone.

 

That’s it. I hope you get it working and find that it’s actually quite simple once you get it to work the first time. Also I hope this tutorial saves your time a bit.

Thanks for reading.

Tanel Teemusk
teemusk.com 

 

 

 

EDIT:

An extra checklist for debugging.
1. You cannot use wildcard development certificate for trying this. be sure to use com.yourdomain.yourapp or similar and not com.yourdomain.* or anything that involves asterisk. Otherwise push won’t work. (Thanks to TaMaX for pointing this out)
2. After your app goes live to AppStore be sure to upload another p12 certificate to Appcelerator using iOS Production Push certificate from Keychain Assistant. Development Push certificate won’t work after going live. (Thanks for DevMan for pointing this out)

Tags: , , , , , , , ,
  • Ads