tm_twitter_apiでうまく認証できない

tm_twitter_api - github

// Resources/app.js
var path_lib = '';
Titanium.include('lib/twitter_api.js');
Titanium.App.twitterApi = new TwitterApi({
	consumerKey: 'MY CONSUMER KEY',
	consumerSecret: 'MY CONSUMER SECRET'
});
var twitterApi = Titanium.App.twitterApi
twitterApi.init();
  • 認証ページでアカウント名とパスワードを入力し「連携アプリを認証」ボタンをおすと、なぜかhttp://mobile.twitter.com/にリダイレクトされる(下画像)。モーダルウィンドウはいっこうに閉じない。

f:id:naoty_k:20110724235009p:image

アプリ(Titanium Mobile)とサーバー(Rails)間の通信

# /app/controllers/users_controller.rb
class UsersController < ApplicationController  
  def signin
    @user = User.create({:name => params[:name], :password => params[:password]})
    respond_to do |format|
      format.json { render :json => @user.to_json }
    end
  end
end
  • アプリ側からのリクエストを受けると、Userインスタンスを新しく作成します。ここでは、セキュリティ面の実装は無視しています。
  • jsonでレスポンスを返したいので、インスタンスをto_jsonでjson化したものをformat.jsonで返します。
// /Resources/signin.js
button.addEventListener('click', function () {
	var username = usernameForm.value;
	var password = passwordForm.value;
	var confirmation = confirmationForm.value;
	
	if (username === '' || password === '' || confirmation === '') {
		Titanium.API.debug('form is blank.');
		return;
	}
	if (password !== confirmation) {
		Titanium.API.debug('confirmation is wrong.');
		return;
	}
	
	var xhr = Titanium.Network.createHTTPClient();
	xhr.open('PUT', 'http://localhost:3000/users/signin.json');
	xhr.onload = function () {
		var user = JSON.parse(this.responseText);
		Titanium.App.Properties.setString('name', user.name);
		Titanium.App.Properties.setString('password', user.password);
		Titanium.App.Properties.setInt('id', user._id);
		win.close();
	};
	xhr.send({
		'name': username,
		'password': password
	});
});
  • 会員登録画面をつくったつもりです。このコードはそのボタン部分の抜粋です。
  • サーバーにリクエストする前に最低限の検証をおこなっておきます。ひっかかったら、フォームの背景色を赤にするなど、目立たせる処理も実装するといいっすねー。
  • Titanium.Network.HTTPClientを使って、サーバー側と非同期通信します。
  • jsonでレスポンスを返してもらいたいので、URLの末尾に「.json」をつけておきます。
  • Titanium.Network.HTTPClient.onloadはレスポンスが正常に返ってきた際の処理です。jsonで返ってくるので、JSON.parse()でJavaScriptのオブジェクトに変換します。
  • Titanium.App.Propertiesで、アプリ側に変数を保持しておくことができます。ブラウザでいうところのクッキーみたいな使い方ができるので便利です。
  • Titanium.Network.HTTPClient.send()は引数にパラメータをもつことができるので、この場合だと、ユーザー名とパスワードをオブジェクトのプロパティとしてセットします。

アプリ起動時にログイン画面を表示させる

// app.js
Titanium.UI.setBackgroundColor('#000');

var tabGroup = Titanium.UI.createTabGroup();

var win1 = Titanium.UI.createWindow({
	url: 'map.js',
	navBarHidden: true
});
var tab1 = Titanium.UI.createTab({
	title: 'Map',
	icon: 'dark_pin.png',
	window: win1
});

var win2 = Titanium.UI.createWindow({
	url: 'list.js',
	navBarHidden: true
});
var tab2 = Titanium.UI.createTab({
	title: 'List',
	icon: 'dark_list.png',
	window: win2
});

var win3 = Titanium.UI.createWindow({
	url: 'registration.js',
	navBarHidden: true
});

tabGroup.addTab(tab1);
tabGroup.addTab(tab2);

tabGroup.addEventListener('open', function (e) {
	win3.open({
		modal: true,
		modalTransitionStyle: Titanium.UI.iPhone.MODAL_TRANSITION_STYLE_FLIP_HORIZONTAL
	});
});

tabGroup.open();
// registration.js
var win = Titanium.UI.currentWindow;
win.backgroundColor = '#fff';

var button = Titanium.UI.createButton({
	title: 'Close',
	top: 150,
	width: 100,
	height: 50
});

button.addEventListener('click', function (e) {
	win.close();
});

win.add(button);
  • window.open()の引数にmodalを指定することで、モーダルウィンドウを実装できる。
  • tabGroupのopenイベントでログイン画面をopenさせる。
  • ログインしているかによって、モーダルウィンドウをopenするかを切り替えればおk
  • Titanium.UI.iPhone.MODAL_TRANSITION_STYLE_FLIP_HORIZONTALはクルッと横回転するアニメーション。ほかにもいくつかある。
  • ログイン画面はcloseすれば、クルッと回転して元の画面が表示される(tabGroupがopenされる)。

基本的なログインフォーム

f:id:naoty_k:20110616225637p:image

var win = Titanium.UI.currentWindow;

var title = Titanium.UI.createLabel({
	text: 'TestApp',
	top: 100,
	height: 40,
	color: '#008800',
	font: {fontSize: 40},
	textAlign: 'center'
});
var usernameForm = Titanium.UI.createTextField({
	hintText: 'Username',
	top: 200,
	width: 250,
	height: 40,
	borderStyle: Titanium.UI.INPUT_BORDERSTYLE_ROUNDED,
	returnKeyType: Titanium.UI.RETURNKEY_NEXT,
	autocapitalization: false
});
var passwordForm = Titanium.UI.createTextField({
	hintText: 'Password',
	top: 250,
	width: 250,
	height: 40,
	borderStyle: Titanium.UI.INPUT_BORDERSTYLE_ROUNDED,
	returnKeyType: Titanium.UI.RETURNKEY_NEXT,
	passwordMask: true
});
var confirmationForm = Titanium.UI.createTextField({
	hintText: 'Confirmation',
	top: 300,
	width: 250,
	height: 40,
	borderStyle: Titanium.UI.INPUT_BORDERSTYLE_ROUNDED,
	returnKeyType: Titanium.UI.RETURNKEY_GO,
	passwordMask: true
});
var button = Titanium.UI.createButton({
	title: 'Sign in',
	top: 350,
	width: 100,
	height: 40
});

win.add(title);
win.add(usernameForm);
win.add(passwordForm);
win.add(confirmationForm);
win.add(button);

Titanium Mobileで現在地を表示する

var win = Titanium.UI.currentWindow;
// Titanium.Map.createViewで地図表示部品MapViewを作成する
var mapview = Titanium.Map.createView({
    mapType: Titanium.Map.STANDARD_TYPE,
    animate: true,
    regionFit: true,
    userLocation: true
});
win.add(mapview);

if (Titanium.Geolocation.locationServicesEnabled) {
    // 継続的な位置測定にはlocationイベントを用いる
    Titanium.Geolocation.addEventListener('location', funtion (e){
        // e.errorにエラー時のプロパティがセットされる
        if (!e.success || e.error) {
            alert('error: ' + JSON.stringify(e.error));
            return;
        }
        // e.coordsに位置情報のプロパティがセットされる
        var lat = e.coords.latitude;
        var lon = e.coords.longitude;
        // latitude, longitudeを動的に指定
        mapview.region = {
            latitude: lat,
            longitude: lon,
            latitudeDelta: 0.01,
            longitudeDelta: 0.01
        };
    });
}

Titanium Mobileによる開発環境の構築

0. 環境

  • Mac 0S X 10.6.7

Titanium MobileでiOS, Androidのアプリを開発する環境を構築した手順はこんな感じ。
1. iOS SDKをインストール

  • Xcodeをインストールするときについてくる。
  • こちらで登録すればXcodeをインストールできる。

2. Android SDKをインストール

3. Titanium Developerをインストール

  • こちらからインストール。
  • これはエディタではないので、別にエディタを用意する。

(こっからは任意)
4. Titanium Studioをインストール