Tuesday, August 20, 2013

Batch rename images to sequence number with script

To get some test images.
Get images from images.baidu.com, as follows,

















create a shell script (.sh) file with following content

n=0
for file in *.jpg; do
    file_name="$n.jpg"
    n=$(( $n+1 ))
    mv $file $file_name
done


Images are renamed to sequence number


Monday, August 05, 2013

iOS handle Remote Push Notification

There are three cases to handle remote push notification.
  1. Your app was just launched
    handle callback didFinishLaunchingWithOptions application launched by clicking "View" when app is not running
  2. Your app was just brought from background to foreground
    by clicking "View" when app is running in background.
    handle callback didReceiveRemoteNotification
  3. Your app was already running in the foreground
    handle callback didReceiveRemoteNotification
Both (2) and (3) are handled by didReceiveRemoteNotification, use the following code to distinguish forground and background.

Thursday, August 01, 2013

Using Ti.Google.Analytics in Titanium Mobile

In previous post "Titanium Javascript Execution Context", we know that different javascript execution context == different scopes. When implementing the Google Analytics, we will meet this problem.

The Ti.Google.Analytics project has been converted to use CommonJS. [1]

var gaModule = require('Ti.Google.Analytics'); var analytics = new gaModule('UA-XXXXXX-X'); // Call the next function if you want to reset the analytics to a new first time visit. // This is useful for development only and should not go into a production app. //analytics.reset(); // The analytics object functions must be called on app.js otherwise it will loose it's context Ti.App.addEventListener('analytics_trackPageview', function(e){
analytics.trackPageview('/iPad' + e.pageUrl); }); Ti.App.addEventListener('analytics_trackEvent', function(e){ analytics.trackEvent(e.category, e.action, e.label, e.value); }); // Starts a new session as long as analytics.enabled = true // Function takes an integer which is the dispatch interval in seconds analytics.start(10,true); // You don't need to call stop on application close, but this is just to show you can callstop at any time (Basically sets enabled = false) Titanium.App.addEventListener('close', function(e){ analytics.stop(); });
By using commonJS, all of our windows are in same context, we can simply call analytics.trackPageview directly inside windows.

However, for windows created by window.url property, the global variable "analytics" is not available.  For compatible reason, in window created by "url" property, we can still fire a global event to track.  Like this,

    Ti.App.fireEvent("analytics_trackPageview", {pageUrl:'myhomepage'});


Titanium Javascript Execution Context

Some notes from "Understanding Execution Contexts"
http://developer.appcelerator.com/blog/2010/08/execution-contexts.html

"A JavaScript application running in a web browser is single threaded and has a global variable scope for the entire application. A Titanium Mobile application is similar"

app.js creates one execution context.

" New execution contexts are created when a window is created that points to an external JavaScript file, which would then bootstrap the new window."
We call it "heavyweight" window.

var win = Titanium.UI.createWindow({
  title: 'New Window',
  url: 'win.js'
});


"When this new window is opened, it will have it’s own context and scope, so any variables declared in other contexts will not be available."

The variable defined in app.js is out of scope in win.js, because it's another execution context.


You can fire application-level events that will be received in all currently active execution contexts (app.js plus any open windows) via fireEvent. Custom events can have arbitrary data passed along with them, as shown in the example below:

Ti.App.fireEvent('myCustomEvent', {
  myCustomEventValue: 'someValue'
});

"You can listen for these custom events in any context by using addEventListener at the application level as well. The example below listens for our custom event – you’ll notice that any properties of the object passed as the second argument to fireEvent are available on the event object the callback function takes as an argument:"

Ti.App.addEventListener('myCustomEvent', function(event) {
  Ti.API.info('You sent me: '+event.myCustomEventValue);
});

"Note that only ACTIVE execution contexts will receive a custom event when it is sent, so any windows that are not yet open will not receive the event."