20120118 titanium

32
Twitterクライアントをブラッシュアップ http://www.flickr.com/photos/craigsd/4687453830/

Upload: hiroshi-oyamada

Post on 22-Apr-2015

3.021 views

Category:

Documents


3 download

DESCRIPTION

Titanium+JavaScriptでiPhoneアプリ開発カフェ<vol.3> サンプルコードのブラッシュアップ編の資料

TRANSCRIPT

Page 1: 20120118 titanium

Twitterクライアントをブラッシュアップ

http://www.flickr.com/photos/craigsd/4687453830/

Page 2: 20120118 titanium

今回の狙い✤ 前回作った簡易Twitterクライアントをブラッシュアップする作業を通じて以下3テーマについて理解する✤ デバッグ✤ ファイル分割で見通しの良いソースコードにする

✤ OAuth認証✤ 1テーマを20分~25分で実施し、途中で中休憩を挟む

http://www.flickr.com/photos/alanant/4483533096/

Page 4: 20120118 titanium

✤ 積極的にはエラーを出さない✤ 変数を宣言なしに使えて、しかもそれがグローバル変数になるなど、JavaScriptは思わぬところにバグが潜みやすい言語といえます。読み取り専用のプロパティに代入してもエラーにならない(代入がスルーされるだけ)ほどです。なんとなく動いてしまったコードが後々にバグとなって帰ってきます。

✤ テストの自動実行が難しい✤ デバッグの難しさとは少し違いますが、テストを自動化し難いため、バグが再発しやすい問題もあります。

JavaScriptのデバッグは意外と大変

※JavaScriptのデバッグTIPS(http://d.hatena.ne.jp/os0x/20101207/1291736377) より引用

Page 5: 20120118 titanium

Q.JavaScriptでの開発をどのように乗りこなすか?A.JavaScriptの構文エラーを避ける工夫をまずはしましょう

http://www.flickr.com/photos/stevecorey/4131860845/

Page 6: 20120118 titanium

Titanium Studioで構文エラーをさけるためのTIPS:目視✤ 構文ミスがある箇所はある程度その場で把握できるので入力中も意識しましょう✤ 該当行で赤い印が付く✤ 制御文などが通常のテキストと同じ色になっている※制御文や変数には色がついて他と区別しやすくなっています。

✤ 初歩的だけどこれはアナログすぎる

こういう印がついていたらその行周辺で構文エラーがあることを示してます。(この例はfor文がまだ入力中のため結果として構文上エラーとみなされています

if 文のelse をタイプミスしているためelsの色が通常の文字と同じ色で表示されている

Page 7: 20120118 titanium

Titanium Studioで構文エラーをさけるためのTIPS:コード補完✤ Titanium Studioのような統合開発環境には通常コード補完機能があるので積極的に利用しましょう✤ 例えば Tiの後のドット(.) を入力してしばらくすると、入力候補が自動的にリストアップされます

✤ 入力候補は矢印キーの上下で選ぶことが出来、Enterキーにて確定します

•矢印キーの上下で候補を選ぶことができます•選択したものはEnterキーにて確定できます

•入力途中にこのように該当するAPIの説明、引数なども表示されます

Page 8: 20120118 titanium

Titanium Studioで構文エラーをさけるためのTIPS:Snippet機能の有効活用✤ Snippetとは?

✤ 「切れ端」「断片」という意味。プログラミングの開発環境では、定型文を補完する機能のことを意味します

✤ Snippetの何がうれしいのか✤ あらかじめ用意しておいた定型文をコピペするのとは違い、変更したい箇所をTabキーなどで順次移動しながら入力できるので使いこなせると大変便利

✤ Titanium Studioもですが、高機能なテキストエディタにはたいていこの機能はあるので、「日頃使っているテキストエディタの名前 + snippet」でググると有益な情報が見つかると思います

✤ Snippet使ってみましょう✤ 今回以下情報を参考にしてますhttp://d.hatena.ne.jp/donayama/20110820/tistudio_bundle_snippet

Page 9: 20120118 titanium

Snippetを使ってみよう①

✤ TitaniumStudioを起動した後、File→New→Titanium Mobile Projectと進みます

✤ 右記画面が表示されますので今回は以下入力してプロジェクトの設定を行います✤ Project name: 20120118TiStudy

✤ App Id:jp.co.pasonatech.20120118TiStudy

✤ 補足)今回はローカルでの作業のため App Idを仮にこのようにしましたがAppStoreで配布する場合、他のアプリケーションと重複することは出来ません。

Page 10: 20120118 titanium

Snippetを使ってみよう②

✤ プロジェクトの設定が完了したら Commands→JavaScript→Edit this bundleと進みます

✤ しばらくするとApp Explorer上にJavaScriptというプロジェクトが追加され自動的にいくつかのファイルが出来上がります✤ 今回のSnippetに関連するのはsnippets.rbとbundle.rbという2つのRubyで書かれたファイルです

Page 11: 20120118 titanium

Snippetを使ってみよう③

✤ snippets.rbをダブルクリックして開くとすでにいくつか定義されたsnippetが存在してます。

✤ コードの見方✤ snippet... end までが1つの処理のまとまりになってます。

✤ snippetの後のダブルクオーテーションで囲まれているのはその処理の説明文章です

✤ s.triggerの部分がsnippetを呼び出すためのコマンドになります

✤ s.expansionが実際に展開されるソースコードのsnippet(=断片)になります

Page 12: 20120118 titanium

Snippetを使ってみよう④

✤ ためしにapp.jsで以下のようにタイプしましょう

1. forと入力

2. 入力後、タブ(tab)キーを押す

3. 入力すると、for文が展開されます。for文のsnippetは2つ設定されており、矢印キーの上下でどちらかが選択出来ますがひとまず上の方を選択した状態でEnterキーを押します

4. 変更する箇所に自動的にカーソルが移動してますので、試しに「container」と入力してみましょう

Page 13: 20120118 titanium

Snippetを使ってみよう⑤

snippet "Create Titanium Mobile UI Widget" do |s| s.trigger = "creui" s.expansion = "var ${1:name} = Titanium.UI.create${2:_widget_class_}({ top: ${3:top_px}, left: ${4:left_px}, width: ${5:width_px}, height: ${6:height_px}, $0});"end

オリジナルのsnippetを追加してみましょう。※http://d.hatena.ne.jp/donayama/20110820/tistudio_bundle_snippet より引用

core_menu.menu "Titanium Mobile" do |control_menu| control_menu.command "Create Titanium Mobile UI Widget"end

snippets.rbの90行の後にこの内容を追記します

bundle.rbの48行目の後にこの内容を追記します

Page 14: 20120118 titanium

見通しの良いソースコードhttp://www.flickr.com/photos/chrissuderman/904382775/

Page 15: 20120118 titanium

これまで書いてきたソースコードの問題点var xhr = Titanium.Network.createHTTPClient();var twitterTL = 'https://api.twitter.com/1/statuses/public_timeline.json?count=3&include_entities=true';xhr.open('GET',twitterTL,false);xhr.onload = function(){ var tweets = JSON.parse(this.responseText); var container = []; for(var i=0;i<tweets.length;i++){ var row = Titanium.UI.createTableViewRow({ height:80 }); var tweetText = Titanium.UI.createLabel({ top:10, left:60, width:240, height:'auto', text:tweets[i].text }); row.add(tweetText);

UI関連のAPI利用時にプロパティ情報が多数出てくるとソースコードがやや読みづらくなる

Titanium.UI.createXXXを利用するとどうしてもこういう記述が多数出てくる

Page 16: 20120118 titanium

ソースコードの見通しを良くするヒントBEFOREvar label1 = Titanium.UI.createLabel({! color:'#999',! text:'I am Window 1',! font:{fontSize:20,fontFamily:'Helvetica Neue'},! textAlign:'center',! width:'auto'});

ユーザーインターフェイス(UI)関連を別ファイルに切り出すだけでも見通しが良くなる

AFTER//app.jsvar style = require('styles');var label1 = Ti.UI.createLabel(style.prop.label);

//styles.js var theme = { color:'#999', backgroundColor:'#fff', font:{fontSize:20,fontFamily:'Helvetica Neue'}, textAlign:'center', width:'auto', viewIcon:'KS_nav_views.png', uiIcon:'KS_nav_ui.png'};//以下省略

Page 17: 20120118 titanium

切り出し方は色々あります

CommonJS形式のモジュール使ったやり方になれると色々な場面で応用が効くので現時点ではこれが個人的にオススメ!

http://www.flickr.com/photos/bunchofpants/36924662/

Page 18: 20120118 titanium

UI関連の情報を別ファイルに切り出す①

✤ 先ほど作った20120118TiStudyプロジェクトをそのまま流用して作業を進めます

✤ App Explorer上のResourcesフォルダをOptionキーを押しながらクリックして、New→Fileと選択します

✤ ファイル名:styles.jsと入力してFinishボタンをクリックします

Page 19: 20120118 titanium

UI関連の情報を別ファイルに切り出す②

propオブジェクトにて、Titaniumの各APIに紐付くプロパティを設定します。(この場合にはwin、label,tab1,tab2の4つのプロパティを設定していることになります)

styles.jsを以下のように入力することでCommonJS形式のモジュールとして活用できます

themeというオブジェクトを作り、色、背景色、フォント、幅・・などに関連する情報をまとめます

上記で設定したpropを別のファイルから利用できるようにするためにexportsします。(これはCommonJSで規定されているモジュールの作り方です)

var theme = { color:'#999', backgroundColor:'#fff', font:{fontSize:20,fontFamily:'Helvetica Neue'}, textAlign:'center', width:'auto', viewIcon:'KS_nav_views.png', uiIcon:'KS_nav_ui.png'};var prop = { win: { backgroundColor:theme.backgroundColor }, label : { color: theme.color, textAlign:theme.textAlign, width:theme.width }, tab1:{ icon:theme.viewIcon }, tab2:{ icon:theme.uiIcon }};

var exports = { prop:prop};

Page 20: 20120118 titanium

UI関連の情報を別ファイルに切り出す③

先ほど作ったstyle.jsを読み込むためにrequire()という機能を利用します。なお拡張子のjsは不要です。

先ほど作ったstyle.jsをapp.jsで利用するには以下のようにします。

var $$ = require('styles');

var tabGroup = Titanium.UI.createTabGroup();

var win1 = Titanium.UI.createWindow($$.prop.win);win1.title = 'Tab 1';var tab1 = Titanium.UI.createTab($$.prop.tab1);tab1.window = win1;var label1 = Titanium.UI.createLabel($$.prop.label);label1.text = 'I am Window 1';win1.add(label1);

var win2 = Titanium.UI.createWindow($$.prop.win);win2.title = 'Tab 2';var tab2 = Titanium.UI.createTab($$.prop.tab2);tab2.window = win2;var label2 = Titanium.UI.createLabel($$.prop.label);label2.text = 'I am Window 2';win2.add(label2);

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

$$.prop.xxx を設定することでそれぞれのUI要素のプロパティ情報を設定出来ます

Page 23: 20120118 titanium

twitter連携するアプリ利用時によく見る画面

Page 24: 20120118 titanium

✤ あらかじめ信頼関係を構築したサービス間でユーザの同意のもとにセキュアにユーザの権限を受け渡しする「認可情報の委譲」のための仕様

✤ OAuthに対応したサービスでは,ユーザが外部サービスにパスワードを教えることなく,認可情報の委譲が可能です。また認可情報の適用範囲を指定したり,有効期限を設定することができるため,ユーザが外部サービスにすべての権限を渡すこと無く,自分が利用したいサービスに最低限必要な権限のみを委譲することができます。

※http://gihyo.jp/dev/feature/01/oauth/0001より引用しました

OAuthとは?

users

consumers

( Webサービスを利用する開発者)

service providers

Page 25: 20120118 titanium

認証と認可の違い

✤ 認証✤ 英語ではAuthentication✤ 平たく言えば本人確認のこと

✤ 認可✤ 英語ではAuthorization✤ 何らかのサービス/リソースへのアクセスに対してアクセスする権限を与えること

1.本人確認1.本人確認

2.認証結果

3.閲覧不許可3.閲覧許可

認証

認可

Aさん Bさん

認証サーバ

サービス/リソースなど

Aさん:閲覧出来るBさん:閲覧出来ない

http://www.itmedia.co.jp/enterprise/articles/0804/22/news044.htmlのサイトをベースに作図

Page 26: 20120118 titanium

Titanium Mobileの開発におけるtwitterのOAuth処理✤ OAuthの認証処理をイチから全部実装するのはとても大変。Titanium Mobileで利用するのに大変便利なライブラリがあります✤ 古川大輔さん(twitter id:mogya)がGitHubで公開してます(https://github.com/mogya/tm_twitter_api)

✤ 上記からZIPファイルをダウンロード&解凍したlibフォルダを今回作成してるプロジェクトのResourcesフォルダ配下に配置します

✤ ユーザ認証が必要となるTwitter API利用にあたっては事前にアプリケーションの事前登録が必要になります✤ これはtwitterに限らず他のWebサービスで同様のことをやる場合に必ず行う作業になります

✤ 次のスライド以降でアプリケーション事前登録方法について解説します

Page 27: 20120118 titanium

twitterのアプリケーション登録申請①

✤ アプリケーション登録申請ページ(https://dev.twitter.com/apps/new)にアクセスします

✤ 以下3項目を入力✤ Name:twclientby+あなたのtwitter id例:twclientby+h5y1m141

✤ Description:twitter client made w/ titanium

✤ WebSite:www.facebook.com/pasonatech

✤ 利用規約のチェックボックスをonにしてCaptchaの文字入力してCreate your Twitter appicationをクリック

Page 28: 20120118 titanium

twitterのアプリケーション登録申請②

✤ アプリケーション登録申請が成功すると右記のような画面が表示されます

✤ Consumer keyとConsumer secretは後で利用する情報になります✤ twitter側ではこの情報を信頼して 認可情報の委譲をしているためとても大切な情報になります

✤ 取得したConsumer keyとConsumer secretは大切に管理しましょう

✤ ※今回はtwitterにログイン&タイムラインを表示するだけの機能を実装するためApplicationのPermissonはReadのままにしてます

Page 29: 20120118 titanium

Twitterのタイムラインを表示する①app.jsの処理先ほど作った20120118TiStudyプロジェクトをそのまま流用してapp.jsに以下を追記します

twitter_api.jsライブラリをここで読み込みます

var $$ = require('styles');var ui = require('ui');// 中略Ti.include("/lib/twitter_api.js");var twWin = Titanium.UI.createWindow($$.prop.win);twWin.title = 'twitter';var twTab = Titanium.UI.createTab($$.prop.tab1);twTab.window = twWin;var twitter = new TwitterApi({ consumerKey:'YOUR CONSUMER KEY', consumerSecret:'YOUR CONSUMER SECRET'});twitter.init();twitter.statuses_home_timeline({ onSuccess: function(tweets){ var rows = []; var items = {}; for(var i=0;i<tweets.length;i++){ var tweet = tweets[i]; var row = ui.createTweetRow(tweet); rows.push(row); } var tableView = ui.createTableView(rows); twWin.add(tableView); }, onError: function(error){ Ti.API.error(error); }});// 中略tabGroup.addTab(twTab);

twitterのアプリケーションの登録申請の際に発行されたconsumer keyとconsumer secretの値をここで設定します

Twitte APIの1つstatuses_home_timelineを呼び出す処理を実施してます。

後述するui.jsモジュールのcreateTweetRowメソッドを呼び出して、TableViewRowを設定していきます

後述するui.jsモジュールを読み込むます

Page 30: 20120118 titanium

Twitterのタイムラインを表示する②UIのパーツ生成するモジュールについて

var exports = { createTweetRow:function(/* JSON */ tweet){ var row = Ti.UI.createTableViewRow($$.prop.viewRow); row.data = tweet; row.addEventListener('click', function(e){ alert('finish'); }); var title = Ti.UI.createLabel($$.prop.tweet); title.text = tweet.text, row.add(title);

var screen_name = Ti.UI.createLabel($$.prop.screenName); screen_name.text = tweet.user.screen_name; row.add(screen_name);

var icon_iamge = Ti.UI.createImageView($$.prop.iconImage); icon_iamge.image = tweet.user.profile_image_url;

row.add(icon_iamge); return row; },

createTableView:function(/* array */ rows){ var len = rows.length; var tableView = Ti.UI.createTableView($$.tableView); for(var i=0;i<len;i++){ tableView.appendRow(rows[i]); } return tableView; }};

ui.jsというUIの各パーツを生成するためのモジュールを作成。2つのメソッドを定義

tweet内容、twietter id名、twitterアイコンの画像パスの情報が含まれたJSONオブジェクトを引数にTableViewRowオブジェクトを生成するcreateTweetRowというメソッドを定義してます

rowが複数格納された配列を引数にして、TableViewオブジェクトを生成するcreateTableViewというメソッドを定義してます

Page 31: 20120118 titanium

Twitterのタイムラインを表示する③

styles.jsのtab2:{..}の後に以下を追記します viewRow:{ width:'auto', height:'auto' }, tweet:{ font:{fontSize:12}, left:55, top:30, width:245, height:'auto' }, screenName:{ font:{fontSize:16}, color:'#000', left:55, top:5, width:'auto', height:20 }, iconImage:{ left:5, top:5, width:30, height:30 }, tableView:{ backgroundColor:theme.backgroundColor }};

この部分でTableViewRowの幅と高さの設定をしています。

この部分でtweetの表示位置、テキストサイズ、幅、高さの設定をしています。

この部分でtweet idの表示位置、色、テキストサイズ、幅、高さの設定をしています。

この部分でtweet アイコンの表示位置、幅、高さの設定をしています。

この部分でtweetの格納をするTableViewの背景色の設定をしています

Page 32: 20120118 titanium

配列rows

参考情報:ui.jsの処理イメージ

row

tweet内容

tweet内容

tweet内容

createTweetRow(json)

row

row

createTableView(array)