Umi Uyuraのブログ

プログラミング関連の作業ログ

Asana用BitBarプラグインを作ってみた

少し前から、個人プロジェクト用に Asana というプロジェクト管理サービスを試しています。

お仕事では Backlog を使っていて、こちらはタスク管理やWiki、ファイル管理にバージョン管理と、プロジェクト管理に必要な機能を全て備えていると言っても過言ではない素晴らしいサービスなのですが、その分お値段もそれなりにすることもあり、個人で使うには敷居が高いです。

Asanaはタスク管理の機能がメインにはなりますが、プロジェクトに参加するメンバーが15名以下なら無料で使えるのが個人用途としては嬉しいところ。

多少クセはあるものの充分に使えそうという印象なので、継続して使っていこうと思っていますが、1つ不満なところは、全体的に若干重たいところでしょうか。

自分としては、その日以降のタスクを時系列順に確認することが多々あるのですが、一覧を表示するのにわりと時間がかかるので、そこが少々ネックです。

自分がふだんのタスク管理として使っているTodoistのように、Chrome拡張などがあると便利だったのですが、AsanaのChrome拡張は見た感じ登録専用のような感じだったので、使っていません。

そこで最近話題になった、Macのメニューバーにいろいろな情報を表示することができるBitBar向けに、Asanaのタスクを表示するプラグインを作ってみました。

できること

こんな感じです。

f:id:umi-uyura:20160410235221p:plain

Asanaは、まずワークスペースという単位があり、その中に複数のプロジェクトを設置することができます。ワークスペース複数作ることができるので、組織やチームなどで割り当てるのだと思います。

このプラグインでは、あるワークスペースワークスペース内で自分が担当に割り当てられている、かつ期限が設定されているタスクを日付順に表示しています。

ワークスペース表示

この部分を押すとワークスペースをブラウザで開きます。

Asanaのカレンダービューは個人的に気に入っている機能なので、このページを開く機能も付けました。

また、個別のプロジェクトを選ぶと、それぞれのページをブラウザで開きます。

タスク表示

タスクは期限、タスク名、プロジェクトを表示しています。

個々のタスクを選択すると、各タスクのページをブラウザで開きます。

期限が当日までのタスクを赤字で表示しています。

また、個人的にその週に実施するタスクというのを把握したかったので、締め切りがその週の週末(日曜日)までのタスク分で境界を入れています。

使い方

ソースはGitHubにあります。

umi-uyura/node-bitbar-asana: BitBar plugin for Asana

前提

動作はNode v4.4.2で確認しています。

インストール

理由は後述しますが、なんかBitBarプラグインとして微妙な作りにしてしまった気がするので、npmにはあげずにGitHubからインストールします。

$ [sudo] npm i -g umi-uyura/node-bitbar-asana

Personal Access Tokenの取得と設定

AsanaのAPIを使うために、アカウントの Personal Access Token というものが必要になります。

Asanaのヘルプ を見ると、 My Profile Settings という画面内に発行するUIがありそうですが、なくなっています。

新しい発行画面は以下のスクリーンショットのように、 Manage Developer Apps のリンクを選択して、

f:id:umi-uyura:20160410235241p:plain

移動した先の画面で Create New Personal Access Token をクリックします。

f:id:umi-uyura:20160410235258p:plain

Personal Access Tokenは生成直後だけ表示されて、その後見ることができなくなるので、メモっておくのを忘れないようにしてください。

Assignee IDとWorkspace IDの取得と設定

AsanaのAPIを使う際に必要な情報として、誰に割り当てられたタスクなのか(Assignee ID)と、どのワークスペースのタスクを表示するのか(Workspace ID)というものがあります。

これをあらかじめ取得しておくために、 bitbar-asana-me コマンドを実行します。

$ bitbar-asana-me
ID of your name (dummy@example.com) is <assignee id>.
Workspace that belongs is as follows.
  Test workspace (<workspace id>)
  Lab workspace (<workspace id>)

すると上記のように、自分のAssignee IDと、所属しているワークスペースのWorkspace IDが表示されます。

これを、設定ファイルに記載します。

設定ファイルは、GitHubリポジトリexample/bitbar_asana を落としてきて、 $HOME/.bitbar_asana として配置します。

設定ファイルには以下のキーが用意されているので、Assignee IDとWorkspace ID、それとPersonal Access Tokenを該当する箇所に記載してください。

Key Value
BITBAR_ASANA_ACCESSTOKEN Personal Access Token
BITBAR_ASANA_WORKSPACEID Workspace ID
BITBAR_ASANA_ASSIGNEE_ID Assignee ID
BITBAR_ASANA_LANGUAGE (optional) 曜日表示部の言語指定
ja を指定すれば月・火・水…で表示されます
BITBAR_ASANA_MENUBARICON (optional) メニューバーに表示するアイコンイメージ
Base64エンコードした画像データ

BitBarプラグインの設置

GitHubリポジトリexample/asana.10m.sh をBitBarプラグインフォルダにコピーするだけです。

設定が問題なければ、指定したワークスペースのタスクが表示されると思います。

複数ワークスペースで使う

設定ファイル( example/bitbar_asana )を別のファイル名で用意し、プラグインスクリプト内で bitbar-asana の引数としてファイルパスを渡すことで、複数設置することができます。

f:id:umi-uyura:20160410235314p:plain

例としては example/asana_other.10m.sh を参考にしてください。

感想

で、作ってから気付いたのですが、Nodeというか、npmで入れるパッケージにしてしまうと、BitBarプラグインとしては若干ポータビリティが悪いですね。

他のスクリプトを見ても、せいぜい外部のコマンドを叩くくらいにして、基本的にプラグインスクリプト単独でまとめている感じ。

それを考えると、そもそもNodeってMac標準で入っていないこともあるので、汎用性を考慮するならRubyなどで作ったほうが良かったかも…

とりあえず、自分の目的は達成できているので、気が向いたら作りなおすことにします。

マンガでわかるプロジェクトマネジメント

マンガでわかるプロジェクトマネジメント

iOS/AndroidでiBeaconを扱うTitaniumモジュールについて調べてみた

Titaniumで、iOSAndroid両方でiBeaconを扱うアプリを作ってみようかと思い、それらしいモジュールを探してみました。

さらに、どうせTitaniumでやるのであれば、なるべく処理を共通化できると良いなということで、まずはそれぞれで提供されているAPIを比較してみることに。

対象モジュール

今回使おうとしているのは以下のモジュールです。

プラットフォーム モジュール バージョン オリジナル
iOS Sensimity/TiBeacons 0.11.1 jbeuckm/TiBeacons
Android Sensimity/android-altbeacon-module 1.4.0 dwk5123/android-altbeacon-module

探していたところ、どちらも Sensimity というBeacon Management Systemのサービスを提供している会社の GitHub で公開されているものに行き着きました。

どちらのモジュールもオリジナルは別の人が開発したものなのですが、それらをフォークして改善が加わっているバージョンが公開されていて、さらにBeacon Managementしている会社のものであれば信頼性も高いのではということで、これを使ってみることにしました。

APIを比較

それぞれのモジュールに用意されているAPIを比較。

主要なAPIは同じ構成になっているので、挙動の差異が少なければ、共通化できそう。

それ以外は、直接iBeaconを扱えないAndroid用モジュールに、そのあたりをカバーするためのAPIが用意されている感じ。

API TiBeacons android-altbeacon-module 関連イベント
アドバタイズ開始 TiBeacons.startAdvertisingBeacon() Altbeacon.startBeaconAdvertisement() ※1 advertisingStatus
アドバタイズ停止 TiBeacons.stopAdvertisingBeacon() Altbeacon.stopBeaconAdvertisement() ※1 -
モニタリング開始 TiBeacons.startMonitoringForRegion() Altbeacon.startMonitoringForRegion() enteredRegion, exitedRegion, determinedRegionState
全てのモニタリング停止 TiBeacons.stopMonitoringAllRegions() Altbeacon.stopMonitoringAllRegions() -
ビーコンとの距離測定 TiBeacons.startRangingForBeacons() Altbeacon.startRangingForBeacons()
(Altbeacon.startRangingForRegion())
beaconRanges, beaconProximity
全ての距離測定を停止 TiBeacons.stopRangingForAllBeacons() Altbeacon.stopRangingForAllBeacons() -
BLEサポート有無 TiBeacons.isBLESupported() Altbeacon.isBLESupported() -
BLE有効無効 - Altbeacon.checkAvailability() -
Bluetoothの状態確認 TiBeacons.requestBluetoothStatus() - bluetoothStatus
Beaconサービスへ接続 - Altbeacon.bindBeaconService() -
Beaconサービスへの接続を解除 - Altbeacon.unbindBeaconService() -
Beaconサービスとの接続状態確認 - Altbeacon.beaconServiceIsBound() -
バックグラウンド動作設定 - Altbeacon.setBackgroundMode() -
ビーコンレイアウト追加 - Altbeacon.addBeaconLayout() -
ビーコンレイアウト削除 - Altbeacon.removeBeaconLayout() -
距離測定間隔設定 - Altbeacon.setProximityBounds() -
自動測定を有効化 ※2 Altbeacon.enableAutoRanging() -
自動測定を無効化 ※2 Altbeacon.disableAutoRanging() -
自動測定の有効無効 - Altbeacon.setAutoRange(boolean autoRange) -
サービス内動作設定 - Altbeacon.setRunInService(boolean runInService) -
サービス内動作確認 - Altbeacon.isRunInService() -
測定間隔の設定 - Altbeacon.setScanPeriods(scanPeriods) -

補足

  • ※1 Altbeacon.start(stop)BeaconAdvertisement() は完全にテストされていないもよう
  • ※2 TiBeacons.enable(disable)AutoRanging() はあったが0.8で廃止されたもよう(APIだけ残っている)

イベント

iBeaconを扱う際に発生するイベントは以下のとおり。

イベント名は双方同じものを使っているようなので、この点も挙動の差異次第で共通化できそう。

イベント 内容
advertisingStatus アドバタイズ状態
bluetoothStatus iOSのみ。Bluetooth状態
enteredRegion 領域侵入
exitedRegion 領域退出
determinedRegionState 領域状態を測定
beaconRanges 領域検出
beaconProximity ビーコンとの距離測定結果
changeAuthorizationStatus iOSのみ。パーミッション状態の変化

まとめ

当然細かい挙動は違ってくるのだと思いますが、API構成などはほぼ同じようなので、基本的な流れは共通化できそうな印象。

次は実際に組み込んでみて検証してみる予定。

iBeacon ハンドブック

iBeacon ハンドブック

BacklogのSubversionリポジトリをバックアップ

お仕事ではプロジェクト管理ツールとして Backlog を使っています。

年度末ということもあってプロジェクトの整理をしていたところ、過去に使っていたSubversionリポジトリをバックアップする必要がでてきたので、やり方を調べてみました。

リポジトリをエクスポート

いくつかやり方はあるなかで、もっとも一般的と思われる svnadmin dump をしてみようと思ったのですが。

$ svnadmin dump <REPO_PATH> > <DUMP_FILE>

ひとつ問題があり、それは svnadmin dump 時に指定するエクスポート元のリポジトリは、ローカルのパスでないとダメだということ。

数が多くなければそれでも良いのですが、やはり複数リポジトリをチェックアウトしてダンプして…というのを繰り返すのは面倒なので、できればBacklog上のリポジトリURL( https://<SPACE_KEY>.backlog.jp/subversion/<PROJECT_KEY> )からエクスポートしたいところです。

そこで、Backlogでエクスポートする機能などないのかな、と思って調べてみたところ、それ自体はないものの、FAQでバックアップ方法について紹介されているのを発見しました。

Subversionのリポジトリのエクスポートサービスはありますか? | FAQ | Backlog [バックログ]

紹介されているスクリプトを使うと、内部的に svnsync というミラーリングツールを使って、リポジトリの複製を作ってくれます。

作られた複製はリポジトリのフォルダ構造が再現されている状態なので、そのフォルダをリポジトリパスとして指定することで、 svnadmin dump にてダンプファイルにまとめることもできました。

リポジトリのインポート

念のため、ダンプファイルからの復元手順も確認。

svnadmin create で新しいリポジトリを用意し、 svnadmin load でダンプファイルからインポートすることで、ローカルにリポジトリを復元することができました。

$ svnadmin create <NEW_REPO>                    # リポジトリを作成
$ svnadmin load <NEW_REPO> < <DUMP_FILE>        # ダンプファイルからインポート

ただし、この方法は通常Subversionサーバー上で実施するらしく、少し調べてみましたが、例えばBacklogのような公開されているSubversionリポジトリへ直接インポートする方法は見つけられませんでした。

Backlogでは有料(税抜き30,000円)にてSubversionリポジトリをインポートするオプションを提供しているので、やはりそういった手段はなさそうな印象。

まあ今後はGitを主流に使うでしょうし、バックアップしたSubversionリポジトリは何か合ったときに参照に使う程度なので、今のところ、自分的には問題はなさそうです。

スクリプトをちょっと改良

というわけで、紹介されていたスクリプトをベースに、取り回ししやすいようにダンプファイルを出力して、念のためダンプファイルが読み込めるかを確認するために新しいローカルリポジトリを作成するという処理を追加してみました。

BacklogのSubversionリポジトリをバックアップする

引数にスペースIDとプロジェクトキーを指定して実行すると、ローカルに以下の3つを生成します。

  • <PROJECT_KEY> フォルダ ... svnsyncミラーリングしたSubversionリポジトリの複製
  • <PROJECT_KEY>.dump ファイル ... 上記をもとに出力したダンプファイル
  • <PROJECT_KEY>_CHECK フォルダ ... 上記ダンプファイルをインポートした新しいリポジトリ

<PROJECT_KEY>_CHECK フォルダをsvnXなどで開いてみると、履歴を読み込むことができたので、問題なさそう。

という感じで一通り必要なリポジトリはバックアップできました。

参考

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

R-BROS. FEST 2016でGRIM SPANKYとLIFE IS GROOVEを観てきました

3/18(木)、ニコ生で放送している「ロック兄弟」という番組のイベント「R-BROS. FEST 2016」に行ってきました。

一昨年くらいに車のCMで流れていたジャニス・ジョプリンの「MOVE OVER」、てっきり外人さんのカバーなのかなーと思っていたんですけど、歌っているのはGRIM SPANKYという日本人のバンドということを知りまして。

それで聴いてみた彼らのファースト・アルバム「SUNRISE JOURNEY」がカッコよく、さらに先日出たミニアルバム「ワイルド・サイドを行け」が5曲ながら名曲ばかりな感じで、最近のお気に入りアーティストのひとつでした。

これはライブで観てみたいな―とウォッチしていたところ、今回のイベントが行けそうだったので、チケットを申し込むことに。

で、そのイベントは対バン形式で、もう一組アーティストが出演するというので名前を見てみたら、なんとLIFE IS GROOVEではないですか!

実はこちらも以前から気になっていて、かつてTBSで放送されていた「さんまのスーパーからくりテレビ」で天才少年ギタリストとして紹介されていた山岸竜之介君が参加しているバンド。しかもメンバーがRISEのベーシストKenKenに、レジェンド・ムッシュかまやつ氏!年齢差60歳、どんな音を出すのか、非常に気になる!


当日は本編開演時間ギリギリに到着したら、オープニングアクトを務めていたarko lemmingというバンドが終わる頃でした。残念。

ステージ準備中は、OKAMOTO'Sのドラマー・オカモトレイジがDJとして会場を盛り上げていました。

「ロック兄弟」の番組MCの方々の諸々が終わって、いよいよGRIM SPANKY登場!

GRIM SPANKYの魅力のひとつは、やっぱりヴォーカル・松尾レミの声だと思いますが、ライブでのシャウトもかっこ良い。あの声にあの音、ドンピシャです。

疾走感のある「ワイルド・サイドを行け」から始まって、コール&レスポンスが盛り上がる「NEXT ONE」、バラード「大人になったら」などなど、少ない曲数でしたが、堪能しました。

それにしても、ほとんど直立で無表情な感じなのに、指がめっちゃ動いてブイブイやっていたベースの人はどなたなんだろう。

でもって、後半はLIFE IS GROOVE!

ドラム、キーボードに2名のホーン・セクションにお三方という編成。

のっけからKenKenのベースがブリブリ鳴って超ファンキー!ボリュームメーターが2、3個あがったような音圧。

山岸竜之介君は、まだ16歳ですかー。なんだかさわやか好青年になっていてビックリ。

そして、そんな2人を見守るというより見守られながら、飄々とマイペースにステージを彷徨うお茶目なムッシュ。

体を動かさずにはいられなくなる感じのバンドサウンドと、ゆる〜い感じのKenKenのMCとの落差もまた面白かった。

さらにアンコール。

GRIM SPANKYとLIFE IS GROOVEがステージにあがると、KenKenが「GRIM SPANKYとぜひこの曲をやってみたかった」といって始まったのは、あのドラム!そう、MOVE OVER!イベントだし、対バン形式で曲数少ないし、まさか演奏するとは思っていなかった!

あの声でMOVE OVER、やっぱりカッコよい。

しかも何がスゴいって、下北沢のジャニスの息子と同じステージにいるんですよね。

その後もスパイダースの「バン・バン・バン」を全員で演奏!そのどさくさに紛れてムッシュにサインをもらうオカモトズ・レイジ(笑)

いやー、とっても濃厚なイベントでした。

GRIM SPANKYは4月に「“ワイルド・サイドを行け”ツアー」をはじめ、イベントにも多数出演予定のようなので、詳しくは 公式サイト をどうぞ。

LIFE IS GROOVEは4/27にシングルが出るそうで、発売記念的なイベントもあるようなので、こっちも LIFE IS GROOVE OFFICIAL SITE をチェック。

どちらも改めて単独公演で観てみたいなー。

f:id:umi-uyura:20160317221019j:plain

ロック兄弟、番組自体は観たことがないけど、最高なイベントをありがとうございました。

ロック兄弟

ワイルド・サイドを行け(初回限定盤)(DVD付)

ワイルド・サイドを行け(初回限定盤)(DVD付)

Generations

Generations

Titaniumもくもく会に参加しました

先週のことですが、久々にTitanium仲間のゆる〜い集まりがありました。

ひさびさ〜と思ったら、去年の Twilio & Titaniumミートアップに行ってきました - Umi Uyuraのブログ 以来ぶりだったんですね。

1月には新年会があったようですが、私は都合があわず参加できなかったので、半年以上ぶりの集まりでした。

Titaniumもくもく会 - Titanium | Doorkeeper

今回の会場は大日本印刷株式会社(DNP)様でした。

以下、発表された方のメモです。

Titanium周りの最新動向 - @kaz_konnoさん

まずは @kaz_konnoさん からTitaniumの最新動向について・・・ということだったのですが、特にないとのこと(笑)

とは言え、やはり年初に飛び込んできたAxway社によるAppceleratorの買収のニュースは驚きでした。

Axway Acquires Appcelerator—And Why This is Great News for All

Axwayという会社についてはよく知らないのですが、エンタープライズ向けの製品をいろいろと持っているところのようです。

まさかTitanium終了か!?という懸念もありましたが、今のところ製品・サービスラインナップはこれまでと変わりなく提供されるようなので、一安心。

Co-FounderのJeffもそういった相手を選んでの決断だったのではないか、ということでした。

Indie foreverプランについて

昨年、Appcelerator Platformという基本有料のサービス体系に変わってから、それ以前にTitaniumアカウントを持っていれば、Indieを永久無料で使えるというプランが期間限定で提供されていました。

このプランへの切り替えは、本来は昨年の6/30までに以降手続きが必要で、もう終了しています。

ただ、この切替方法が少々わかりにくく、実は新しいアカウントに切り替わった時点では Developer プランという状態で、アカウントの設定から Indie に手動でプランを変更しないといけないのです。

これに気づかずに Indie へ切り替えそこねてしまった人も多いようで、期限を過ぎてしばらくは直接サポートに連絡するなどしてIndieに切り替えてもらったようなケースもあるようですが、その救済措置も終了ということのようです。

Developer Portal

Developer向けのポータルページが新しくなりました。

Appcelerator Developer

最新情報は Appcelerator Developer Updates というページに集約されているようなので、Titanium/Appcelerator Platformに関して情報が欲しい人は、定期的にこちらをチェックすると良いでしょうとのこと。

公式のDeveloper Blogや、Webinarやチュートリアル動画を掲載しているAppcelerator University、そしてMediumに投稿されたTitanium関連の記事をピックアップしているAll Titaniumというコーナーがあります。

以前あったQ&Aフォーラムについては、Stack Overflow上でサポートに移行したそうです。

Newest 'appcelerator' Questions - Stack Overflow

投稿する際は appcelerator タグを付けておくと、Appceleratorの人も見てくれているようです。

ただ上記は英語のサイトになってしまうので、日本語でサポートが必要な方は Titaniumユーザー会のサポートBBS へ投稿するか、Twitterハッシュタグ #TitaniumJP を付けて投稿すると、どなたか拾ってくれるかもしれません。

最新のSDK情報

最新のSDK 5.2.0がリリースされていて、3/10の時点で5.2.1のRCも出ています。

SDK 5.2.0で提供される新機能などは、以下のラップアップ記事にある動画が非常にわかりやすいので、サンプルと合わせて見てみると良いと思います。

Titanium Mobile DNPの取り組みについて - DNP山下さん

続いて、会場を提供していただいた大日本印刷株式会社の山下さんから、DNPのTitanium Mobileへの取り組みについて紹介していただきました。

DNPでは、特に2011〜2012年ころ、Titanium meetup TokyoやTitanium mobile 2.0ローンチ記念イベントなどで会場提供などでTitaniumコミュニティ活動を支えてくれていました。

DNP自体もネイティブ以外の開発プラットフォームも幅広く取り入れているということで、そのひとつとしてTitaniumも実践活用されているとのこと。

法人向け業務支援やカスタマイズアプリなど、特にタブレット向けアプリのUI構築などで使っていて、分野としてもサイネージやアンケート、コンシェルジュ、教育など多岐に渡るそう。

最近の事例としては、京都のギャラリーなどで鑑賞補助用のアプリに使っていたり、DNPオリジナルタブレット向けにAndroidホームアプリなどに使っているそうです。

TitaniumでAndroidのホームアプリも作れるというのは知らなかったので、ちょっとやってみたい。

今後は、Titanium×Windowsも視野に入れて研究中ということで、特にWindowsタブレットをターゲットに活用していきたいということでした。

ただ、このあとのWindows開発の発表にもありましたが、SDK 5.2.1時点ではまだまだ使い物にならない状態ということで、前途多難な道のりにはなりそうな感じ。

最近は、特に企業から改まってTitaniumの事例などを耳にすることは少ないので、適材適所を見極めて活用されているところがあるというのを聞けたのは心強いですね。

faster-titanium - @shinoutさん

続いて CureApp@shinoutさん の発表は、TiShadow/LiveViewを凌ぐ新たな爆速開発ツール「faster-titanium」の紹介。

どういうものかは、GitHubリポジトリのアニメーションGIFを見ていただくとイメージしやすいかと思います。

CureApp/faster-titanium: Accelerate Titanium development

TiShadowやLiveViewは便利ですが、落ちやすかったり、なんだか動かないということが多かったので、LiveViewをベースにしつつ、中身をES6ベースにして徹底的にリファクタリングしたそうで、安定性とReact Native並のリロード速度を実現されたそうです。

現状はiOSでしか動いていませんが、ベースとなるLiveViewがAndroidについてはできているので、同様にできるであろうということと、のちのちはWindowsにも対応していきたいという話でした。

Titaniumの特徴として、各プラットフォーム向けのUIをJavaScriptAlloyフレームワークなど簡略化された構文で構築できる点にあると思いますが、どうしてもビルドして動作確認という部分に時間がかかってしまいます。この部分がfaster-titaniumで短縮できると、さらに開発効率があがるので、Titaniumの強みがより活かせるツールだと思います。

まだ出来たてということもあり、絶賛フィードバック募集中ということなので、ぜひ使って行きたいと思います。

Titanium x Windows開発 - @flat_8_kikiさん

最後は @flat_8_kikiさん による、TitaniumによるWindowsアプリ開発についての発表。

もはや涙無くしては語れない物語で、メモを取る手も止まってしまうほどでした。

この過酷な闘いについてはQiitaに記録されていますので、ぜひご覧ください。

そもそもユニバーサルWindowsアプリ開発自体の情報もまだまだ少ない気がするので、そういった点でも貴重な情報だと思います。

SDK 5.4.xおよび5.5.xあたりで改修されている見込みのようなので、最低限の開発ができるようになるのは、その頃からという感じでしょうか。

まだまだ闘いは始まったばかりということで、ガンガン地雷を踏み抜いてくださる覚悟ということなので、今後のWindows×Titaniumの進展も期待できそうです。

※2016/03/25追記

資料公開していただいたので、追記しました。

おわり

終わってみると、非常に濃い話が多くてもくもくどころじゃなかった会でした。

最近は同じマルチプラットフォーム開発でも、React NativeやMSに買収されたXamarinなどに話題を持って行かれている感がありますが、Titanium自体も着実に進化していて、実績という点では他に負けていない製品だと思います。

そして表に出てきてはいないけど、実は使っているという人もけっこういるようなので、そういった人にもぜひもくもく会などに遊びに来ていただいて、情報交換させてもらえると嬉しいですね。

Google Play Musicにアップロードした楽曲を再ダウンロードする

定額の音楽配信サービスは、Google Play Musicを使っています。

umi-uyura.hatenablog.com

特に邦楽は聴きたいアーティストの作品がないことも多いわけですが、Google Play Musicには、手元の音源をアップロードしておくことで、登録しているデバイスに同期して聴くことができる機能があります。

Google Play ミュージック マネージャで音楽を追加する - Google Play ヘルプ

アップロードは50,000曲までできるということなので、ざっくりアルバム4,000〜5,000枚分くらいと考えても、自分の持っているCD全て入ってしまうくらいアップできます。(ちゃんと数えたことないけど、たぶん500枚くらい?多くても1,000枚はない程度)

それならGoogle Play Music上に自分のライブラリを集約させてしまうことも可能なわけですが、もしそうした場合に気になるのが、アップロードした楽曲を再び手元にダウンロードすることはできるのか?ということ。

これができるのであれば、バックアップとしても使えるので、自分的に使い勝手があがるかもと思い調べてみたところ、ちゃんと?その手段が用意されていました。

設定画面の ライブラリのダウンロードダウンロード ボタンを押すと…

f:id:umi-uyura:20160314235849p:plain

おもむろにダウンロードが始まりました。

f:id:umi-uyura:20160314235900p:plain

途中でブラウザを閉じるなどしても、またログインするとダウンロードが再開されるようで、進捗状況は左下に表示されています。

f:id:umi-uyura:20160314235912p:plain

ダウンロードされる場所は、設定画面(スクリーンショット一枚目)にある ダウンロードフォルダ で指定できます。

個別ダウンロードはできない

残念ながら、今のところアップロードした楽曲を個別にダウンロードする手段はなさそうです。

もし50,000曲をアップロードしていたと仮定すると、1曲5MBとしても250GBにもなってしまうので、これを一括ダウンロードしかないとなると不便。

とは言っても、それだけの曲数をアップロードするような頃には何かしら改善されていそうな気もしますし、それまで使い続けているかもわからないので、今のところは問題なし。

Alloy Modelの学習・その4(REST API)の続き

前回、REST APIのData Bindingを使ってみたのですが、

umi-uyura.hatenablog.com

そのときに課題として残していたエラーハンドリングなどレスポンスに対する処理に関してと、開発中にAPIエンドポイントを分離したい場合の方法についてメモ。

レスポンスに対する処理

napp.alloy.adapter.restapi を使う際の、エラー処理を含むレスポンスの処理方法を調べてみました。

napp.alloy.adapter.restapiのリポジトリに掲載されている例では引数を受け取っていませんでしたが、各メソッドでは、以下のように successerror のコールバックを受け取ることができます。

function doOpen() {
  memos.fetch({
    success : function(models, response){
      Ti.API.debug('memo fetch() - success = ' + models + ' / ' + response);
    },
    error : function(models, response){
      Ti.API.debug('memo fetch() - error = ' + models + ' / ' + response);
    }
  });
}

successerror コールバックは、サーバーからのレスポンスのHTTPステータスコードによって判断されて呼びだされるため、基本的に意識する必要はありません。

受け取ったモデルの加工だったりエラーに対する処理のほか、通信中のローディング画面の制御などもここでハンドリングできますね。

コールバックの形

操作対象がCollectionなのかModelなのかによって、コールバックには大きく2種類の形があるようです。

メソッド コールバック コールバックの形
Collection.fetch() success
error
function(models, response)
Model.save()
Model.destroy()
success
error
function(model, response)

各コールバックの第1引数は、主に操作したモデルデータを受け取るようです。

次に、共通している response には、Titanium.Network.HTTPClientの responseText が入ってくるようです。通信をJSONでやりとりする場合は、必要に応じて JSON.parse() するなどして扱うことになると思います。

コールバックの形を見るに、 responseText 以外の情報は受け取っていないようなので、例えばもしアプリ側でもHTTPステータスコードが必要な場合は、あらかじめレスポンスボディに含めるなどする必要がありそうです。

iOSAndroidでエンドポイントを分ける

特にPCローカルのサーバーと、iOSAndroidのシミュレータ/エミュレータで通信確認をする場合のメモです。

iOSのシミュレータでは 127.0.0.1 で開発しているMac側で立ち上げているAlloyModelStudyRestStubにアクセスできるのですが、AndroidエミュレータやGenymotionの場合、 127.0.0.1 は端末自体を示すらしく、 10.0.2.210.0.3.2 といったIPになるようです。

モデルの URL を書き換えれば対応できますが、その都度実施するのも面倒なので、あらかじめ config.json に設定しておき、そのURLを使うようにしました。

app/config.json

{
  ...
  "os:android env:development": {
    "API_URL": "http://10.0.3.2:4321/memos"
  },
  "os:ios env:development": {
    "API_URL": "http://127.0.0.1:4321/memos"
  },
  ...
}

config.json で設定できる値は、 os:androidos:ios といったプラットフォームをあらわすオブジェクトに、動作環境をあらわす env:development などを組み合わせることで、「Androidエミュレータの場合」「iOSエミュレータの場合」に使う値、というようにバリエーションをつけることができます。

それをモデルの中で参照することで、環境ごとに異なるURLを使えるようになりました。

app/models/memo.js

exports.definition = {
  config: {
    columns: {
      "id": "integer",
      "contents": "text",
      "priority": "text"
    },
    adapter: {
      type: "restapi",
      collection_name: "memo",
      "idAttribute": "id"
    },
    "URL": Alloy.CFG.API_URL,           // <== config.jsonに定義したURL
    "debug": 1
  },
  ...
};

env:production などと組み合わせれば、本番環境向けビルドで使うURLも設定できます。

なお、以前はモデルの中でグローバルな Alloy オブジェクトを参照できなかったので、こちらの記事( AlloyのModelでREST APIからデータを取得する - Qiita )のように一手間必要だったようですが、Alloy 1.4.0?あたりから参照できるようになったようです。

Backbone.js的な対処方法

モデル側のURLの指定を変更する方法とは別に、Backbone.js的に、モデル操作時にオプションとしてURLを渡すという対処方法もあります。

その場合は、 Collection.fetch({url: <url>})Model.save(<params>, {url: <url>})Model.destroy({url: <url>}) といったあたりのメソッドを使えば良いようです。

エンドポイントを動的に変更するようなケースがあれば、使いみちがあるかもしれません。

まとめ

APIのレスポンスに関しては、自前で用意するAPIであれば設計段階で調整できますが、既成サービスのものなどを使う場合はいじりようがないので、実戦使用するときに、また色々と検証しようと思います。

Appcelerator Titanium Smartphone App Development Cookbook - Second Edition

Appcelerator Titanium Smartphone App Development Cookbook - Second Edition