Amazon

2012年5月19日土曜日

TitaniumでSQLiteを使う際のキホン

TitaniumでSQLiteを使う際の良く使うものをまとめておきます

○データベースの作成

var db = Titanium.Database.open('db_name'); // db_name は任意のデータベース名

○データベースのパス確認
Titanium.API.info('DB PATH : ' + db.file.getNativePath()); // file://localhost/Users/〜省略〜/xxx 
Titanium.API.info('DB PATH : ' + db.file.resolve()); // /Users/〜省略〜/xxx

○データベースの削除
db.execute('DELETE FROM db_name');

○データの確認
~/Library/Application Support/iPhone Simulator/User/Application/アプリ別のディレクトリ/Library/Application Support/database/
の下に、db名.sql の名称で保存されている。

○ あるテーブルが存在するかを確認して、存在しなければテーブルを初期化する
var dbName = 'dbname';
var db = Titanium.Database.open(dbName);
var existTable = db.execute('select count(*) from sqlite_master where type=\'table\' and name=\'TABLENAME\'');
var count = existTable.field(0);
if(count == 0) {
  Ti.include('./initDB.js');
  db = dbInit(db);
}


○Insert処理を早めるためのコツ
db.execute('BEGIN');//トランザクション開始
Insert処理
db.execute('COMMIT');//コミット

TitaniumのaddEventListenerでハマる

TitaniumでTableViewRowにテキストや写真を追加して、各要素をクリックするとそれぞれのアクションを起こしたいとする。
このとき、各要素にaddEventListenerを追加することでアクションを拾ってもらうようにコードを書いてしまいがちだが、上手く行かない。
例えば、以下のコードでは、TableViewRowである変数rowに、photo, name, updateTime, textを追加しており、TableViewの行およびphotoをクリックすると、それぞれのJavaScriptファイルが別Windowで読み込まれるというもの。
この時、ハマったのはrowのaddEventListenerでpost.idを別Windowのwinに渡そうとしても上手く渡らなかった


var win = Ti.UI.currentWindow;
var tableView = Ti.UI.createTableView({
 top : 50
});
win.add(tableView);

Ti.Facebook.requestWithGraphPath('me/home?date_format=r&limit=5', {}, 'GET', function(e) {

 if(e.success) {
  var result = JSON.parse(e.result);
  var data = result.data;
  tableView.setData([]);
  for(var i = 0; i < data.length; i++) {
   var post = data[i];
   var row = Titanium.UI.createTableViewRow({
    layout : 'vertical',
    height : 'auto',
    postId : post.id,
   });
   row.addEventListener('click', function(e) {
    var win = Titanium.UI.createWindow({
     postId : this.postId,
     url:'./row.js',
    });
    Titanium.UI.currentTab.open(win, {
     animated : true
    });
   });
   
   var photo = Titanium.UI.createImageView({
    image : 'http://graph.facebook.com/' + post.from.id + '/picture?type=square',
    width : 50,
    height : 50,
    top : 5,
    left : 5,
    borderRadius : 5,
    postId : post.id,
   });
   photo.addEventListener('click', function(e) {
    var win = Titanium.UI.createWindow({
     postId : this.postId,
     url:'./photo.js',
    });
    Titanium.UI.currentTab.open(win, {
     animated : true
    });
   });
   
   var name = Titanium.UI.createLabel({
    text : post.from.name,
    top : -50,
    width : 200,
    height : 30,
   });
   
   var updateTime = Titanium.UI.createLabel({
    text : Date.parse(post.created_time),
    width : 200,
    height : 25,
   });
   
   var text = Titanium.UI.createLabel({
    text : post.message,
    top : 'auto',
    height : 'auto',
   });
   
   row.add(photo, name, updateTime, text);
   tableView.appendRow(row);
  }
 }
});



みたいなコードを書いてしまうが、どうもEventListnerが複数あると、上手くイベントをハンドルできなくなるようです。 そんなわけで、EventListenerはTableViewに一つ登録しておき、TableViewのイベントで、クリックされた行を検知して、その行にセットしておいた変数(ここではextというオブジェクトリテラルを各要素に定義)別に処理を返るという方法を採用した。
var win = Ti.UI.currentWindow;
var tableView = Ti.UI.createTableView({
 top : 50
});
tableView.addEventListener('click', function(e) {
 var postId = e.rowData.postId;
 var type = (e.source.ext) ? e.source.ext.type : "";
 if(type === "photo") {
  var win = Titanium.UI.createWindow({
   url:'./photo,js',
   postId : postId,
  });
  Titanium.UI.currentTab.open(win, {
   animated : true
  });
 } else {
  var win = Titanium.UI.createWindow({
   url:'./row.js',
   postId : postId,
  });
  Titanium.UI.currentTab.open(win, {
   animated : true
  });
 }

});
win.add(tableView);

Ti.Facebook.requestWithGraphPath('me/home?date_format=r&limit=5', {}, 'GET', function(e) {

 if(e.success) {
  var result = JSON.parse(e.result);
  var data = result.data;
  tableView.setData([]);
  for(var i = 0; i < data.length; i++) {
   var post = data[i];
   var row = Titanium.UI.createTableViewRow({
    layout : 'vertical',
    height : 'auto',
    postId : post.id,
   });
   
   var photo = Titanium.UI.createImageView({
    image : 'http://graph.facebook.com/' + post.from.id + '/picture?type=square',
    width : 50,
    height : 50,
    top : 5,
    left : 5,
    borderRadius : 5,
    postId : post.id,
    ext:{
     type:'photo',
    },
   });
   
   var name = Titanium.UI.createLabel({
    text : post.from.name,
    top : -50,
    width : 200,
    height : 30,
   });
   
   var updateTime = Titanium.UI.createLabel({
    text : Date.parse(post.created_time),
    width : 200,
    height : 25,
   });
   
   var text = Titanium.UI.createLabel({
    text : post.message,
    top : 'auto',
    height : 'auto',
   });
   
   row.add(photo, name, updateTime, text);
   tableView.appendRow(row);
  }
 }
});

こちらを参考にしました。

2012年5月2日水曜日

JavaScriptで非同期処理を逐次実行

Titaniumで非同期処理を逐次実行するにはこちらとかこちらを参考にしながらJSDeferredというlibraryを使うこと
JSDeferredの解説はこちら 

他にも、非同期処理を逐次実行にする方法はあるようで、
ここだったり、ここだったり、ここだったり、と。

Amazon3