| Subcribe via RSS

Building Server Push Notifications with Appcelerator Titanium Cloud

May 5th, 2012 | No 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 

Tags: , , , , , , , ,

MovieClip Exploder class

January 18th, 2012 | No Comments | Posted in Adobe Air, adobe flash, flash

I built a logo particle explosion class for a client. Unfortunately they decided not to take this route. It came out rather cool so I thought I’d share this with all of you. You can download the source code and use it anywhere you like. It would be cool if you would tell me where you used it tho.

Download MovieClipExploder source code

Usage:

1. Download the zip file
2. Copy the ‘com’ folder in there to your project directory
3. Make a ‘particle’ sprite/MovieCilp in your .fla file and  choose ‘Export for Actionscript’ when you make it as a MovieClip. Type: ‘particle’ in the ‘Class’ field. (you can use custom shapes if you want to).

Settings for Particle movie clip in flash

3. Particle creation Settings

4. Make the shape inside the particle movie clip as another movie clip and call it “gr”. No actionscript export necessary here. But you can now add effects to this asset. I added a little blur in the example.
5. Make sure your logo has an instance name and it’s on the stage. Then add the code:

import com.teemusk.ExplodeMovieClip;
var logoexploder:ExplodeMovieClip = new ExplodeMovieClip(logo);
addChild(logoexploder);
logoexploder.startEmitter();

6. Publish your movie and watch those particles fly.

That’s it. Enjoy!

Tags: , , , , , , , , , , , , , , , , ,

Passing variables to a function

January 11th, 2012 | 1 Comment | Posted in adobe flash, flash, Objective-C

My lingo is so Actionscript, but that is changing slowly. Variables are methods, and we’re actually passing properties in Objective-C. But ok. Yesterday I wrote about declaring and calling functions/methods in Objective-C. Now I’ll try to explain how to declare functions that accept variables and how to pass variables to them. Also I cover briefly how to get ‘trace’ statements in Objective C.

So let’s cut to the chase.

Trace Statements

Actionscript:

var string:String = "I AM STRING";
trace("I am getting traced in the console ");
trace("I am a variable: "+string);

Objective-C

NSString *string = @"I AM STRING";
NSLog(@"I am getting traced in the console");
NSLog(@"I am a variable %@",string);

Now note how variables work in NSLog statements. characters starting with % sign will get substituted by comma separated variables. Also all string defined have to have “@” in front of them.
They’re a bit to get used to. I will pass a cheatsheet of different variables

Actionscript

private function myFunction(foo:String){
trace("I got the variable "+foo);
}

 Passing a variable to a function

Passing a var to a function in Actionscript:

private firstFunction():void{
var str:String = "This is passed data";
anotherFunction(str);
}
private anotherFunction(s:String):void{
trace(s); //Output: This is passed data
}

Passing a variable to a function with Objective-C:


//First add this line to your header (.h) file;
- (void)anotherFunction:(NSString *)s;

//then in Class file (.m) you can call this function like so:
-(void)firstFunction{
NSString *str = @"This is passed data";
[self anotherFunction:str];
}
- (void)anotherFunction:(NSString *)s{
NSLog(@"%@",s); //Output This is passed data
}

Make sure ‘firstFunction’ is called. Try to use AppDelegate’s initWithOptions as your firstFunction.

Objective C NSLog cheatsheet:

%@     Object
%d, %i signed int
%u     unsigned int
%f     float/double
%x, %X hexadecimal int
%o     octal int
%zu    size_t
%p     pointer
%e     float/double (in scientific notation)
%g     float/double (as %f or %e, depending on value)
%s     C string (bytes)
%S     C string (unichar)
%.*s   Pascal string (requires two arguments, pass pstr[0] as the first, pstr+1 as the second)

%c     character
%C     unichar

%lld   long long
%llu   unsigned long long
%Lf    long double
Tags: , , , , ,

Objective-C Here I come

January 10th, 2012 | No Comments | Posted in adobe flash, Apple, flash, Objective-C

Okay. I’ve been learning Objective-C on and off for quite a while now. I’ve been doing it mostly using The Big Nerd Ranch books.

I can tell you it has not been easy. While all tutorials in these books are quite straightforward and work out just great when you follow a book, they still haven’t helped me to get my head around this language. I get the syntax, I get how the structure should work, but some of the concepts are so different coming from ECMA script language background such as Actionscript or Javascript. Painful.

Also I have googled around a lot. While there are some blogs that describe a bit about migrating from ECMA script to C based language, they haven’t helped me out too much.

Therefore I will try to add my 5 cents to the blogosphere about this subject. (And don’t judge me if I’m wrong in my theories presented here. I’m just a n00b.).

Declaring and calling a function

This is probably the first thing you want to do. In Actionscript 3 I would do this:

Defining a function:

private myFunction():void{
//Do something;
}

To call this function from another function I would just:

private anotherFunction():void{
myFunction();
}

In Objective C it’s not as straightforward. Defining a function like this won’t allow to call it from another function.

Defining a function:

First add the function description to an interface (yeah that’s the myClass.h file. Objective C calls them Headers).

- (void)myFunction;

Then in the class itself (myClass.m file) define this function completely:

-(void)myFunction{
//Do something
}

And then you can call it from another function:

-(void)anotherFunction{
[self myFunction];
}

 

I hope you get the idea how it works. I will try to add more examples soon.

Tags: , , , , , , ,

Writing to applicationDirectory with Adobe Air

October 27th, 2011 | 3 Comments | Posted in Adobe Air, flash

I had a lot of painful trouble with flash.filesystem.File functionality the other day. The problem is that File.applicationDirectory is read-only. I understand that it’s read only as on a mac we’re inside the <myair>.app/Contents… folder when we’re executing scripts and it is not very wise to write stuff in there.

Most of the times the File.desktopDirectory or File.documentsDirectory will meet our needs just fine and we can write stuff there. That was not the case for me. I needed an air desktop app which would work like a website or projector with loading data next to itself (from ‘images’ or ‘data’ folder etc.). Also I really needed to write a log out of the app so I can see how people are using it and if it’s app’s problem when it crashed.

Long story short. Here is my solution which is a bit of a hack but not too bad and at least it works ‘unlocking’ the File.applicationDirectory so we can have read/write access to it.

The trick is to resolve path for the applicationDirectory first and according to it’s native path we resolve the folder as File.userDirectory. My code goes like this:


var appPath:File = File.applicationDirectory.resolvePath("");
var fromUserPath:File = File.userDirectory.resolvePath(appPath.nativePath);

fromUserPath will take us to the exact same place as appPath, but with a difference that it is read/write and also you can do fromUserPath.parent.parent.parent to it to get to the folder next to the air app on a mac.

So my code that handles the starting path for my app on win and mac (and debug mode) goes as follows:

if (Capabilities.os.toLowerCase().indexOf("win") > -1){
localPath = File.applicationDirectory.resolvePath("");
}else if (Capabilities.os.toLowerCase().indexOf("mac") > -1){
var appPath:File = File.applicationDirectory.resolvePath("");
var fromUser:File = File.userDirectory.resolvePath(appPath.nativePath);
localPath = fromUser.parent.parent.parent;
}
if(Capabilities.playerType == "Desktop" && Capabilities.isDebugger){
localPath = File.applicationDirectory.resolvePath("");
}

//if you trace localPath.nativePath now you can see that you’re on a directory that your air app is at.

I had a terrible headache with this and could not find a straight answer by googling so I thought I’d give something back to community. Enjoy.

Tags: , , , , , , , , ,

Apple Design Award Winners 2011

June 27th, 2011 | 1 Comment | Posted in Apple, apps, iPad, iPhone

Apple has awarded the coolest iOS apps with it’s Apple Design Awards for 2011.

I have tried couple of the awarded and can comment the prizes as follows.

infinity blade icon

1. Infinity Blade

Quite nice iOS game with really awesome graphics. The only problem with the game is the story. It’s a bit repetitive. You always get to the final monster but you can never beat him. At least not before you’ve gained many many levels. And to gain levels you follow the same path again with slightly different level monsters. No offence. The game is really great. And the graphics are astounding for such limited hardware. So this software has really earned it.


Cut the rope icon

2. Cut the rope

This is the best game I’ve seen on iOS so far. It is the best in everything. It’s playful, it has really cool story. It has really nice graphics with totally awesome animation. And it has puzzles that will crack your head. Oh and did I mention the physics. Just awesome. Well done and well earned it’s name on the list.


3. Pulse

This is a feedreader. You can add your favorite feeds and read them in a really nicely designed interface. It got the award for Student Developer Showcase. If it’s done by a student then sure. It’s a really nicely done app and the design is awesome. 
But with all this in mind I don’t see why Apple did not give an award to FlipBoard? While pulse is great reader, FlipBoard is great plus really innovative.


Anyway. It’s really cool that Apple does such a thing and I hope that someday my own apps are gonna be on that list.

Link to Apple Design Awards

How to delete flash cookies and cache

November 25th, 2010 | No Comments | Posted in adobe flash, cache, flash, flash cookie, shared object

It’s rather easy to flush browser cache for different browsers but regular “clear cache” command through browser menu does not kill flash shared objects (flash cookies).

To clear browser data which will delete all xml files and regular cookies set by server-side scripts is easy and can be done as follows:

Clear cache in safari (mac): Safari(menu item next to the apple icon)>Empty Cache..
clear cache in Chrome(mac): Chrome>Clear Browsing data…


To clear flash cookies and cache you will have to do it through adobe’s website:

go to: Adobe Flash Player settings
there you will see a window like this:

Click on folder icon on top if it’s not selected (not the one with the globe icon but the other one).
from there on you can select websites which you want to delete from flash cache or you can delete all sites, which will clear all flash cookies.
Hit Confirm and you’re done.
Now you can experience flash sites from the clean sheet once again.

Enjoy!

Tags: , , ,

My favorite iPad Apps to date

November 14th, 2010 | 1 Comment | Posted in apps, iPad

The following are my favorite apps for iPad:


1. Evernote.

The best notes app. Syncs into a cloud and has apps for your iPhone and desktop as well. covers all my note taking needs.

FREE | iTunes Link


2. Flipboard

This app will display news, facebook feeds, twitter feeds etc. in a really really nice way. You’ll love reading the news after you get it.

FREE | iTunes Link


3. Twitter

This app is for tweeting. Very well done. With a nice design and great usability.

FREE | iTunes Link


4. Angry Birds

Really cool puzzle game where you have to smash stuff by slinging birds. Very good physics engine. Great fun. plus this game has an awesome backstory.

4.99$ | iTunes Link


5. Cut The Rope

Another awesome genial puzzle game where you’ll have to feed a frog a candy. Great physics and a lot of fun for hours. Nice backstory as well.

1.99$ | iTunes Link


6. Vacation Mogul

Really nice strategy game. A lot like build-a-lot. Levels are really well done. this game will keep you entertained for hours. The story sucks but the game is well worth the price.

6.99$ | iTunes Link


7. SketchBook pro

Drawing app. The best one. really intuitive and nice to use.

7.99$ | iTunes Link


8. Dungeon Hunter

Really great role-playing game for iPad. Intuitive, with a great story and well done graphics.

4.99$ | iTunes Link


There is much more cool apps out there and in my iPad as well, but these 8 are really the cream for me so far.

If you have great recommendation for good apps then please let me know in the comments and I’ll check them out.


Thanks.

Tags: , , , , , , , , , ,

Apple compressor and h.264 strange 1px line problem.

September 4th, 2010 | 1 Comment | Posted in apple compressor

Apple Compressor is an awesome little encoder which comes along with Final Cut Studio bundle. I don’t use it all of the time but when I have a lot of rendering to do I usually lean towards using compressor. It’s got queue rendering and you can share the rendering between different machines etc. And did I mention it’s fast. So yeah I recommend it to anyone doing video production and wants to render stuff out for different media. But I’m not here to praise but rather talk about a strange problem I had.

The Problem

I’m rendering a h.264 video out to a flash website. I’ve done this before and it always works out as expected (sometimes making 3-4 test renders to see the quality/size ratio). This time however I get good quality as always, but also a thin 1px grey (or white) line is rendered into a video. I would not mind usually, but for this site and video you can really see the line when in fullscreen mode. And the video being really dark is not helping much. The grey line really stands out.

The Solution

Googling like a mad maniac and reading through tons of forums didn’t help. Finally I found an apple support discussion that handed me a solution.
It seems that h.264 video is compressing video in 16pxX16px chunks. So basically, if you give the encoder odd sizes to chew it’ll go a bit cuckoo with unexpected results. It’s not a problem with video when width and height can both be divided by 16. 
So when you are doing odd sizes, be sure to have both dimensions be a multiplication of 16 and you’ll avoid this annoying problem.

My dimensions:
1280X573 Failed with grey line on the bottom
when changed to:
11280X576 Perfect video.

Stupid problem with a really simple solution you just have to know.

Tags: , , , , , , , , , , , , ,

If you want to make a sale, be different

July 21st, 2010 | No Comments | Posted in Marketing

I do flash, photography and video for a living. I freelance. That means I talk a lot with small business owners and startup people who target local markets. Once in a while I get into discussions with them, about their image. What most small business owners do when they start to build their homesite, they look what their competitors have. And this action, for me is not the smartest move.

To make a sale means to be great. To be great we cannot run after our direct competitors.

The biggest mistake while creating a public image through design, visual identity, photographic style etc. to a local market, is to be and look exactly like your competitor. Don’t try to be like like the best performer in your market. Don’t even look at their website nor their logo. It’s a bad idea that gives you bad ideas. Do Mercedes-Benz and BMW have the same look in their branding strategy? Absolutely not. Do Apple Macintosh and Microsoft look the same? Absolutely not.

If you have any guts and will to succeed then find your own style. Gather inspirational content from the world leaders. They don’t have to be from your field, but they can be anything. There’s some great stuff all over the web. Find your unique style and present your findings to your creative resource. Let them get their brains working without seeing your competitors website. I’m pretty sure you’ll get the best outcome that way.

Tags: , , , , , , , , , , , , , ,
  • Latest Tweets