読者です 読者をやめる 読者になる 読者になる

TitaniumMobile勉強記

Web系エンジニア向けのキャリアアドバイザーやってましたが現在はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連(Node.js、Titanium)あたり

Appcelerator Cloud Services(ACS)使ってみました

Titanium Mobile

Appcelerator Cloud Services(以下ACS)は、TCADやTCMDの試験項目でも出てくるのと、現在作ろうと思っているサービスで利用しやすそうな気がしたので、検証も兼ねてちょっと使ってみました。

当面の検証の目標

現在作ろうと思っているサービスを視野に入れてることもあり

  • Facebooktwitterのアカウントでログイン出来る
  • 上記アカウントでログインして、何らかのメッセージが投稿出来、その情報がACSに保存される

の2点を確認してみました。

※自分の環境はTitanium SDK 2.1.0.GA、MacOSX 10.7.4 です。

事前に準備したライブラリ

twitterにかぎらず、メジャーなソーシャル系のアカウントの認証処理については、@k0sukeyさんが作ったTiPlatformConnectを利用することで楽ができそうなのでこれを利用することにしました。

自分の中でのルールとして、外部のライブラリを利用する時にはResources/lib/に配置するようにしているので、このようなディレクトリ構成にしてます

Resources
├── app.js
├── iphone
│   ├──(省略)
├── lib
│   ├── app.js
│   ├── dropbox.js
│   ├── etsy.js
│   ├── flickr.js
│   ├── foursquare.js
│   ├── github.js
│   ├── google.js
│   ├── hatena.js
│   ├── jsOAuth-1.3.3.js
│   ├── linkedin.js
│   ├── mixi.js
│   ├── tumblr.js
│   └── twitter.js
├── model
│   └── twitter.js
└── ui
│   ├──(省略)

なお、上記構成にすると、twitter.jsの先頭

var exports = exports || this;
exports.Twitter = (function(global) {
  var K = function(){}, isAndroid = Ti.Platform.osname === "android", jsOAuth = require('jsOAuth-1.3.3');

のjsOAuth-1.3.3の部分がパスが通ってないためにErrorになるため、require('lib/jsOAuth-1.3.3')と修正してから作業してます

検証用に作ったアプリのソース

ひとまず検証目的のアプリなので、Titanium Studioでプロジェクトを作って、最初に出来る雛形のアプリをベースにつくりました

app.jsのソース
Titanium.UI.setBackgroundColor('#000');
var tw = require('model/twitter');
var Cloud = require('ti.cloud');
var tabGroup = Titanium.UI.createTabGroup();
var win1 = Titanium.UI.createWindow({
    title:'Tab 1',
    backgroundColor:'#fff'
});
var tab1 = Titanium.UI.createTab({
    icon:'KS_nav_views.png',
    title:'Tab 1',
    window:win1
});
var label1 = Ti.UI.createLabel({
  top:30,
  left:5,
  width:200,
  height:300,
  text:'投稿結果'
});

var button1 = Ti.UI.createButton({
  top:5,
  left:5,
  height:20,
  width:50,
  title:"start"
});

button1.addEventListener('click',function(){
  tw.auth();

  var twToken = Ti.App.Properties.getString('twitterAccessTokenKey');
  Cloud.SocialIntegrations.externalAccountLogin({
    id:'YOUR TWITTER ACCOUNT',
    type: 'twitter',
    token: twToken
  }, function (e) {
    if (e.success) {
      Cloud.Posts.create({
        content: 'twitteアカウントを利用しての投稿',
        title: '果たしてうまくいくか?'
      }, function (e) {

        if (e.success) {
          var post = e.posts[0];
          console.log('success'+post.id);
          label1.setText(post.id + '\n' +
                            'title: ' + post.title + '\n' +
                            'content: ' + post.content + '\n' +
                            'updated_at: ' + post.updated_at);
        } else {
          label1.setText = ('Error:\\n' +
                            ((e.error && e.message) || JSON.stringify(e)));
        }

      });

    } else {
      console.log('Error:\\n' +
                  ((e.error && e.message) || JSON.stringify(e)));
    }
  });
});
win1.add(label1);
win1.add(button1);

var win2 = Titanium.UI.createWindow({
    title:'Tab 2',
    backgroundColor:'#fff'
});
var tab2 = Titanium.UI.createTab({
    icon:'KS_nav_views.png',
    title:'Tab 2',
    window:win2
});
var label2 = Ti.UI.createLabel({
  top:5,
  left:5,
  width:200,
  height:300,
  text:'投稿結果'
});


Ti.Facebook.appid = 'YOURAPPID';
Ti.Facebook.permissions = ['publish_stream']; // Permissions your app needs
Ti.Facebook.addEventListener('login', function(e) {
  if (e.success) {
    console.log('Logged In');
    Cloud.SocialIntegrations.externalAccountLogin({
      type: 'facebook',
      token: Ti.Facebook.accessToken
    }, function (e) {
      if (e.success) {
        Cloud.Posts.create({
          content: 'Facebookアカウントを利用しての投稿',
          title: 'Facebookから投稿。果たしてうまくいくか?'
        }, function (e) {

          if (e.success) {
            var post = e.posts[0];
            label2.setText('Success:\n' +
                'id: ' + post.id + '\n' +
                'title: ' + post.title + '\n' +
                'content: ' + post.content + '\n' +
                'updated_at: ' + post.updated_at);

          } else {
            label2.setText =( 'Error:\\n' +
                ((e.error && e.message) || JSON.stringify(e)));
            console.log('Error:\\n' +
                        ((e.error && e.message) || JSON.stringify(e)));
          }
        });

      } else {
        console.log('Error:\\n' +
                    ((e.error && e.message) || JSON.stringify(e)));
      }
    });
  }
});

Ti.Facebook.addEventListener('logout', function(e) {
  console.log('Logged out');
});
win2.add(Ti.Facebook.createLoginButton({
  top : 5,
  left:5,
  style : Ti.Facebook.BUTTON_STYLE_WIDE
}));
win2.add(label2);

tabGroup.addTab(tab1);
tabGroup.addTab(tab2);
tabGroup.open();
twitterの認証部分を行う model/twitter.jsのソース
var twitter = require('lib/twitter').Twitter({
  consumerKey: 'YOURKEY',
  consumerSecret: 'YOURSECRET',
  accessTokenKey: Ti.App.Properties.getString('twitterAccessTokenKey', ''),
  accessTokenSecret: Ti.App.Properties.getString('twitterAccessTokenSecret', '')
});
var twitterAuthorize = function(event){
  twitter.addEventListener('login', function(e){
    if (e.success) {
      Ti.App.Properties.setString('twitterAccessTokenKey', e.accessTokenKey);
      Ti.App.Properties.setString('twitterAccessTokenSecret', e.accessTokenSecret);

      twitter.request('1/account/verify_credentials.json', {}, {}, 'GET', function(e){
	if (e.success) {
	  var json = JSON.parse(e.result.text);
	  if (event) {
	    twitterRow.removeEventListener('click', twitterAuthorize);
	  }
	} else {

	}
      });
    } else {

    }
  });

  twitter.authorize();
};

var exports = {
  auth:twitterAuthorize
};

上記ソースでbuildしてシミュレーターが起動して、startボタンをクリックすると以下のように投稿成功した旨になります
f:id:h5y1m141:20120808083155p:plain
ついでにACSのコンソールの一部ですがこんな感じで表示されます
f:id:h5y1m141:20120808083355p:plain

最後に

ここまでの作業は、昨日の出社前の90分ほどで出来ました。試した後に


と呟いてるようにACSは中々面白く、自分が欲しいアプリというかサービスの用途としてかなり向いているような気がするので、明日以降もうちょっと(特にPlacesの機能中心に)いじってみようと思います