やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

Selenium勉強会@サイボウズに行ってきました #selenium_cybozu

10/20にサイボウズ株式会社さんで開催された『Selenium勉強会@サイボウズ』に行ってきました。

connpass.com

以下、メモ残したものだけ。内容すべて拾ってはいないので注意。

Selenium Conference 2015 参加報告

サイボウズの宮田さんより。

  • Selenium Conferenceは今年で5回目。今回はポートランドで開催。
  • 初日はワークショップ、2・3日目はセッション。セッション動画は公開されている
  • ランチ時も含めて、参加者間での議論も活発だった

面白かったセッションの紹介

  • FacebookのSimonさんのKeynote
  • Selenideの話
    • Selenide == Javaで書かれたSeleniumクライアントラッパー
    • smart waiting: shouldHave()で画面遷移・描画を待ってくれる
    • collection
    • automated screenshot
    • sizzle selectors
    • profiler
    • fast setVelue: JSでsetValueを置き換える(setValueの実行が遅いのを改善)
  • Selenium Grid Auto scale
    • AWSで構築
    • hub一つで、250並列
    • hub二つで、500並列
    • ネットワーク帯域を増やして、1000並列

テンプレートエンジンにMixer2を使うとSeleniumでのテストもラクになるかもよという話

ビズリーチの渡辺さんより、テンプレートエンジンMixer2がSeleniumによるテストと親和性が高いという話。

  • Mixer2は、Javaで書かれたテンプレートエンジン
  • DSLでなく、htmlのspan id/class指定を置き換えるエンジン -> SeleniumXPath書かずに済む
  • XHTMLJavaのObject変換が双方向 -> テストコード側では、パースして得たJava Objectに対してassertを書くことができる

SikuliXを知っていますか?

小原さんより、SikuliXの紹介と、Seleniumとの連携について。

  • sikulixからseleniumを呼ぶ
  • sikulixをライブラリとして使う
  • sikulix IDEで簡単にコードを書いたり、実行できる
  • Sikuliの開発をMITから引き継いだ時、xをつけてsikulixになった

本当にメンテナブルなSeleniumの運用について考えてみた

一休.comの赤坂さん

  • Seleniumのテストは、リグレッションテスト向けに書いて実行している
  • テストケースは30、8並列で実行
  • 本番環境は5〜7分、ステージングでは8〜10分
  • 最低限のシナリオ
  • 運用していくためにはどうするか
    • Page object design patternは手段の一つ
    • メンテナを増やす
      • 説明会、ドキュメント、継続的にアウトプット、自分でメンテしないで機能を実装した担当者にやらせる
      • フォローは喜んでやる

kintone開発を支えるSeleniumテスト

ふたたびサイボウズの宮田さん。kintoneの開発での実例。

  • 自動テストは一度壊れて放棄。『継続的デリバリー』を読んで再チャレンジ
  • テストケースは1000くらい
  • QAがテスト設計、PGが自動化実装
  • Java + WebDriver
  • 新機能追加時に受け入れテストも書いている
  • 既存機能は、手の空いた時に追加。優先順位はリスクを考慮してQAが決定
  • メインブランチに変更が入るたびテスト実行。落ちたらチャットで晒しあげられる
  • メンテナンス性
    • page object
    • 失敗時にスクショを撮る。動画も試したがリソースが辛かったのでやめた
  • コード品質を高める
  • 安定性の向上:リトライ回数。画面遷移待ちなどはラッパー(Selenideなど)でサポートされている
  • 実行時間;余計なテストは作らない、単体テスト等でカバー
  • IE, Safariはやってない

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

Seleniumデザインパターン & ベストプラクティス

Seleniumデザインパターン & ベストプラクティス

第6回「じどうかの窓口。」セミナー 〜クラウド時代のCIサービスとエコシステム〜 に行ってきました #ta_madoguchi

株式会社SHIFTさんで開催された「じどうかの窓口。」セミナーに行ってきました。今回のテーマはクラウドCIサービス(CI as a Service)。

madoguchi100.connpass.com

クラウドCIサービス5つの比較紹介

まず、SHIFTの太田さんから。

  • CI:継続的インテグレーションVCSへのコミットごとに自動テストを含むビルドを行なう、アジャイルのプラクティス。インテグレーション、せいぜいステージング環境へのデプロイまでを指す
  • CD:継続的デリバリー。CIにとどまらず、本番環境へのデプロイまでをパイプラインとして実行する
  • CIツールは、Apache Continuumなどが第一世代、Jenkins(旧Hudson)が第二世代、そしてクラウドCIサービスが第3世代と言える
    • Jenkinsの問題点として、維持管理にコストがかかる、環境が特殊になりすぎて「Jenkinsでしかビルドに成功しない」など。
  • クラウドCIサービスは、ざっと調べただけでも30以上ある
  • 代表的なクラウドCIサービスとして、5サービスを紹介・比較。
    • Travis CI
    • Circle CI
    • drone.io
    • Wercker
    • DEV@Cloud
  • Travis CIとCircle CIは、iOS/Androidアプリにも利用できる(OS Xが使えるサービスは少ない)
  • Circle CIはGitHub Enterpriseでも利用できるプランがあるが、OS Xは使えない
  • Werckerは日本で流行っている印象。利用者の4割ほどが日本人
  • DEV@CloudはJenkinsのクラウド版。無料プランは無いが、トライアル期間はある
  • どのサービスを使うにしても、そのサービスに依存してしまっては同じことの繰り返し。パイプライン構築にwalterのようなツールを使うなどしてポータビリティを上げたほうが良い

CI及びCDについて詳しく知るには『継続的デリバリー』がおすすめです。

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

また、以下の二冊にもCI/CDの概要および、Travis CIの使いかたが紹介されています。

システムテスト自動化 標準ガイド (CodeZine BOOKS)

システムテスト自動化 標準ガイド (CodeZine BOOKS)

  • 作者: Mark Fewster,Dorothy Graham,テスト自動化研究会,伊藤望,玉川紘子,長谷川孝二,きょん,鈴木一裕,太田健一郎,森龍二,近江久美子,永田敦,吉村好廣,板垣真太郎,浦山さつき,井芹洋輝,松木晋祐,長田学,早川隆治
  • 出版社/メーカー: 翔泳社
  • 発売日: 2014/12/16
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログ (3件) を見る
iOSアプリテスト自動化入門

iOSアプリテスト自動化入門

プルリクエスト駆動型国産コードインスペクションサービスSideCIの紹介と活用方法

SideCIを運営する、株式会社アクトキャットの角さんによる、SideCIの紹介、デモ。

  • SideCIは、コードレビュー向けのCIサービス。インスペクションをやってくれる
  • GitHubと連携し、pull-requestに対してコードの問題点や改善方法をコメントしてくれる
    • インスペクションの対象はpull-requestに含まれるファイルのみなので、フォーカスを絞って対応できる
  • 裏では各言語向けのLint等インスペクションツールを走らせている
    • ツールによっては、SQL Injectionも指摘してくれる
  • 現在はPHP, Ruby, Pythonなどを中心にサポート
  • 現在ベータサービスだが、ほぼすべての機能を無料で提供しているので、ぜひ使ってみて欲しい

www.sideci.com

ディスカッション:クラウドCIサービスやその周辺サービスの活用と課題

テーブルごとに分かれてディスカッション。私のいたテーブル(4名)で出た話は以下の通り。

  • 4名とも、現在はJenkinsを利用*1。しかし内情はそれぞれ異なっている
    • AWS上に構築、AWSの契約は顧客
    • 社内サーバに構築。Active Directoryを使う都合でテスト実行環境を外部に置けない
    • iOSアプリ開発ではビルド環境のバージョンアップ時期にはクラウドサービスは使いにくい
    • 本番環境には直接つながっていない、顧客管理下である、などの理由で、デリバリーまではつながっていない
  • いずれも、Jenkins専任の担当者はおらず、インフラ担当者などが兼任しているが負担は大きい
  • Jenkins環境の安定性はひとつの課題であると太田さんの話にありましたが、AWS上に構築し、イメージの履歴管理をするなど工夫している
  • テストまでは実行しているが、インスペクションについてはわかれた
    • PyLint, pep8を実行している
    • 古いコードがあり、その内部品質が悪いため、インスペクションのエラーに対処しきれない
      • エラーとなるしきい値をチューニングしては?
      • Googleの出した"bugspots"を使う/組み合わせるといいかも?
      • インスペクション対象を指定できればいいかも?
  • クラウドCIサービス導入への課題
    • テスト実行環境の制限
    • 料金。顧客に納得させるか、受託側でかぶるのか
    • 以前オープンソースのプロジェクトにpull-requestを出したとき、ビルド待ちがとても長かった(数時間〜半日)
      • Freeプランだと待つ。有料プランではもっと速いはず

最後に、他のテーブルの「クラウドサービスを利用できない理由」

  • コードを外に出せない、セキュリティ、SLA(ダウンタイムとか)
  • サービスを組み合わせて使うということは、サービスの数だけ会社の承認を取る必要がある

まとめ

みんな苦労してるんだな、というか、苦労してるからここに来たんだな、という当たり前の感想を持ちました。

クラウドサービスにはまだ課題があるとして、それ以前にテスト実行環境のコンテナ化など、テスト実行を安定させるためにできることは多そう。

蛇足ですが、SHIFTの太田さんと玉川さんが監訳された本を持参してサインいただきました!

Seleniumデザインパターン & ベストプラクティス

Seleniumデザインパターン & ベストプラクティス

*1:私も受託案件はJenkins

第2回 FOVE体験会&トークセッションに行ってきました

DMM.make AKIBAにて行われた、PANORAさん主催の『第2回開催!! FOVE体験会&トークセッション』に行ってきました。

https://atnd.org/events/67494atnd.org

FOVEは、現在Kickstarterクラウドファンディングを行なっている視線追跡ができるVRHMDです。Backer募集はあと60時間ほどで締め切られ、また締切後の一般販売はしばらく後になるそうです。気になっている方はお早めに。

https://www.kickstarter.com/projects/fove/fove-the-worlds-first-eye-tracking-virtual-realitywww.kickstarter.com

FOVE体験

受付でもらった整理券が6番だったので、トークセッションに先立って実機でデモを体験しました。装着した感じ、とても軽く感じられました。

デモの最初に視線(瞳孔?)をキャリブレーションするプロセスがあり、視界の周囲を、左上、右上、右下、左下、と緑の点が表示されるのを見つめます(まばたきしてはダメらしい)。

デモは宇宙モノのシューターで、自分の位置は固定、視線の方向に弾が発射されるというもの。視線追跡のスピードと精度は十分確認できました。 頭を素早く動かしたときの追随性も問題なさそう。ただし、デモの作りにもよるので単純に他と比較できるものではありませんが。

FOVEの紹介

FOVEのCEO小島由香さんによるFOVEの紹介。以下、簡単なメモ。

  • VRの世代として、presenceの世代、controlの世代と来た(イマココ)。そしてexpression、感情表現ができるのがFOVE
  • parallax error==左右の視差のため、咄嗟にエイムできない
  • FOVEは、FPSのほか、キーボードをタイプする用途にも使える。1cm角くらいは認識できる
  • 見ている部分だけ解像度を上げることで、1/6くらいの負荷低減が見込める
  • 用途は、わかりやすいのはゲームだが、ALS患者(末期だと眼球と脳波しか入力に使えない)、筋ジストロフィー患者

トークセッション

FOVEのCEO小島由香さん、CTOのロキ(ロックラン・ウィルソン)さん、週刊ASCII初代編集長の福岡さんによるトークセッション。以下メモ。

1. なぜFOVEを作った?

  • 元々、PS VITAのフロントカメラで表情を取るところが原点。そこからアイトラッキング
  • 企画をスタートしたとき、VRはここまで流行っていなかった
  • 1995年に『CAPE X』というVR雑誌を創刊。9冊で休刊*1(福岡さん)

2. ハードづくりで技術的に難しかったところは?

  • はじめはハードを作る気はなく、iPadとソフトの組み合わせで考えていたが、精度や画面サイズなどからHMD制作へ。試作は既存製品に穴を開けて改造
  • 小ロットで部品を調達するのは難しかった。日本企業の方がそのへんは協力的。面白そうなものには協力してくれる。
  • アメリカはお金は集めやすいけど、部品調達は日本のほうが楽。SFは家賃も高い。
  • Kickstarterのコンバージョン率は日本の方が高い
  • 視線は、瞳孔を赤外線で拾っている。可視光をブロックすることで精度を上げている。
  • 黒目を追跡==black spot tracking

3. 目線追従ってどんなことに使っていきたい?

  • ピアノを弾く少年のVTRのように養護施設への提供(Just giving project)、年内には実機が配られる予定
  • 軍事、ドライブシミュレータ。ドライバーがどこを見ているかを後から収集・解析できる
  • お店の陳列のA/Bテストを簡単に行える
  • ドローンの操作。ただし視線誘導の問題として、衝突しそうな障害異物を見てしまって、そちらに飛んでしまう
  • 犬、猫は人間より視野角が広いので、その疑似体験
  • 自閉症の人は他人の目を見るのが苦手なので、克服する訓練に使う
  • MITで面接シミュレーションの研究がされている

4. 開発にあたって他のVRHMDと異なる注意すべき点は?

  • 基本はUnity、Unreal Engineでも作れるはず
  • 全てがくっきり見えるのはVR的にはよくない。ピントが外れているところはぼやけるのが現実に近い
  • ピントの合っているものの情報を表示する(攻殻機動隊みたいに)
  • 片目をつむるとズームするなどの工夫も

5. VR業界は今後どうなる?

  • 90年代、ヒッピー、LSDVR、みたいな流れ。NASAでも研究。これらが合流したのが97年くらい。当時で2〜3千万円くらいの機材
  • 当時の問題は、解像度、コスト
  • 最近は酔わないVRコンテンツのノウハウも溜まってきている
  • personal/consumerのVR

質疑応答

  • アイトラッキングでできること → ウィンク、まばたきも取れる
  • 瞳孔の収縮をトラッキングできるか? → 瞳孔の大きさとして取得はできるが、明るさなどの要因もあって難易度は高いと思う
  • 外見デザインのこだわりは? → (CEOが)女性なので、つけて格好いいもの、シンプル、ミニマルな、無印良品的な。製品版はもっと小さくできる

懇親会でロキさんに伺ったこと

  • SDKは筐体より早め、あと3ヶ月くらいで出せると思う。早めに出して開発者の意見を取り入れたい
  • フォーカスと解像度の連動は自動ではなく、シェーダでフォーカス範囲を取得して解像度を判断する処理が必要。サンプルのシェーダが付くので、それを参考にできるはず

*1:懇親会で聞いたところ、当初月間、途中から隔月刊

Google Cloud Messaging (GCM) の新機能 Topic Messagingを試したメモ

Google I/O 2015で発表された Google Cloud Messaging(以下GCM)の新機能、Topic Messagingを試してみました。

環境、前提条件などは、先の記事を参照してください。

nowsprinting.hatenablog.com

Topic Messaging とは

Topic Messagingとは、従来のGCMおよびApple Push Notification Service(以下APNs)のような送信先デバイスのトークンを指定してのPush通知ではなく、Publish/subscribeモデルのPush送信を行なう機能です。

Publish/subscribeモデルとは、各デバイスから購読(subscribe)したいトピックをあらかじめ登録することで、メッセージ送信(publish)側では個々のデバイスを意識することなく、トピックに対してメッセージを送ることで購読デバイスすべてにメッセージを配信できるものです。

これによって、例えば、

  • ニュースの更新などをPush通知したいだけであれば、サーバアプリケーションでは受信デバイスのRegistration Tokenを管理する必要がない
  • 送信機能もクライアントアプリに持たせる場合、サーバアプリケーション自体を立てる必要がない

といった構成が実現できるようになります。

制約・制限

GCMのTopic Messagingには、以下の制約・制限があります。

  • トピックのキーは、/topics/[a-zA-Z0-9-_.~%]+の書式
  • アプリあたり*1の購読数は100万件まで
  • トピックに送信できるメッセージのペイロードは2KBまで

購読数については、ユーザが1トピックづつ購読して100万ユーザまで、平均2トピックなら50万ユーザまで…となるので、インストール数が見込まれるアプリでは注意が必要です。

トピックの購読

以下、前回同様 Try Google Cloud Messaging for iOS のサンプルを使用して試していきます。

トピックの購読は、次のメソッドで行ないます。(メインスレッドから呼ぶ必要があります)

[GCMPubSub subscribeWithToken:topic:options:handler:]

サンプルのGcmExampleでは、起動時にトピック/topics/globalを購読するようになっています。

トピックへのメッセージの送信

続いて、同じく"Get started"のサンプルプロジェクトにあるGcmServerDemoを起動すると次のウィンドウが表示されます。

f:id:nowsprinting:20150607043716p:plain

apiKey欄にGCMのAPI Keyを入力し、"Send to topic"ボタンをクリックすると、送信メッセージの(本来、宛先のRegistrationTokenを設定する)toに、/topics/globalを設定して送信が行われます。

具体的には、以下のメッセージが送られます。

[
    "to": "/topics/global",
    "notification": [
        "body": "Hello from GCM"
    ]
]

これだけで、トピック/topics/globalを購読しているデバイスすべてにPush通知が送信されます。

トピックメッセージの受信

受信は通常のPush通知と同様です。受信側でトピックメッセージ固有の処理を行いたい場合は、 [UIApplicationDelegate application:didReceiveRemoteNotification:]メソッドで以下のように判定できます。

-(void)application:(UIApplication)application
        didReceiveRemoteNotification:(NSDictionary)notification {
    if ([notification[@"from"] hasPrefix:@"/topics/"]) {
        // トピックメッセージを受信した
    } else {
        // 通常のメッセージを受信した
    }
}

なお、今のところ、購読されているトピックのリストを取得するようなインタフェースは、サーバ側にもクライアント側にも定義されていないようです。

その他、エラーハンドリングなど詳細は公式のガイドを参照してください。

Implementing Topic Messaging

App nameとBundle ID, Androidアプリとの関連

GCMの利用登録を行なうページでは、"App name"と"iOS Bundle ID"を入力します。ここで、"App name"は、Google Developer Console(API Console)の"Project name"となります。

f:id:nowsprinting:20150615112845p:plain

これに対し、"iOS Bundle ID"は1:nの関係で登録することが可能です。 同様にAndroidアプリ場合、Bundle IDの代わりに"Android package name"欄にパッケージ名(ApplicationID)を登録しますが、これも1:nの関係になります。

トピックメッセージを送信するためのAPI Key、およびSender IDは、"App name"単位に割り当てられます。これに、複数の"iOS Bundle ID", "Android package name"を紐付けられますので、iOS版とAndroid版、また、Lite版やOEMしたアプリなどに対し、一括してトピックメッセージを送信することができます。

なお、iOSアプリ向け設定ファイルであるGoogleService-Info.plistにはSender IDしか書かれていませんので、複数のビルドターゲットで共有することができます。

Androidアプリ向けのgoogle-services.jsonには、Sender IDのほかに登録されたパッケージ名が書かれますが、登録されたパッケージ名が全て配列で書かれるようです。 そのため、フレーバーを定義して複数のアプリをビルドする場合でも、ひとつのgoogle-services.jsonを共有して問題ありませんでした。

*1:おそらく、Google APIs ConsoleのProject単位のこと

Google Cloud Messaging (GCM) でiOSデバイスにPush通知を送る

Google I/O 2015で発表された、Google Cloud Messaging(以下GCM)を使ってiOSデバイスにPush通知を送る手順が公開されていたので試してみました。

developers.google.com

なお、GCMを使うと言っても最終的にiOSデバイスにPush通知を行うのは従来通りiOS標準のApple Push Notification Service(以下APNs)です。 従来、サーバアプリケーションが直接デバイストークンを管理し、APNsにメッセージを直接送信していましたが、サーバアプリケーション→GCM→APNsと、GCMを介してPush通知を行なうことができます。

GCMにおいて端末固有のトークンとなるRegistration Tokenは、iOSの(APNsの)Device Tokenとは異なる、次のような*1文字列です。

bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1pLTQ/8t-5QNiXbYwZYEWiSFD-frQKlsV8lgI

iOSアプリでGCMを利用するメリットとしては以下が挙げられます。すでにMBaaSのPush通知サービスなどを使っているのであれば、実現できているものだと思います。

  • iOSAndroidのデバイストークン(Registration Token)を一元管理できる
  • iOSAndroidのPush送信ロジックを共通化できる
  • Topic Messagingを利用することで、デバイストークン指定でなくトピック文字列指定で該当するデバイスにPush通知できる

環境

今回試した環境は以下の通りです。

  • OS X 10.10.3
  • Xcode 6.3.2
  • iOS 8.3(Push通知を受けるには実機である必要があります。シミュレータはNG)
  • GCMクライアントライブラリ 1.0.7

なお、GCMクライアントライブラリを利用するには、iOS 7以上が必要です。*2

事前準備

前述の通り、APNsを利用することになりますので、App IDごとの"Push Notification"を許可し、APNsのSSL証明書を生成しておく必要があります。

証明書は、Development(sand box)、Productionいずれも利用可能です。今回はDevelopmentのみ試しています。

サンプルアプリのビルド

以下、Try Google Cloud Messaging for iOSの手順について補足します。

  1. CocoaPodsでサンプルを取得します

    $ pod try Google

    使用するサンプルを聞かれるので、 4: Samples/gcm/GcmExample.xcodeprojを選択。Xcodeでサンプルプロジェクトが開きます。

    サンプルプロジェクトには、クライアント二種類(Objective-C版とSwift版)、送信側のMacアプリケーションの、計3つのビルドターゲットが含まれます。

  2. Google Developersサイトで、GCMのAppと、iOSアプリのBundle IDを登録します

    Try Google Cloud Messaging for iOSページにある"GET A CONFIGURATION FILE"ボタンで登録ページに遷移できます。

    ここでApp Name(Androidアプリと共有するならば同じ名前で)、アプリのBundle IDを入力し、続いてAPNsのSSL証明書(p12形式)をアップロードします。すると、API KeyとSender IDを取得でき、GoogleServices-Info.plistがダウンロードできます。

  3. GoogleServices-Info.plistをサンプルアプリ(クライアント側)に取り込みます

    GoogleServices-Info.plistには、Sender IDが書かれています。

  4. サンプルアプリ(クライアント)を実行します

    実行すると、GCMにRegistration Tokenが設定され、Push通知を受け取る準備が整います。また、Topic Messagingのためのトピック/topics/globalにも登録されます。

    なお、このときコンソールにRegistration Tokenが出力されていますので、文字列をコピーしておきます。

送信サンプルの実行

サンプルプロジェクトのGCMServerDemoが送信側のサンプルです。起動すると下図のウィンドウが表示されます。

f:id:nowsprinting:20150607043716p:plain

apiKey欄にGCMのAPI Key、Registration TokenにクライアントのRegistration Tokenを入力し、"Send notification"ボタンをクリックすると、該当するiOSデバイスにPush通知が届きます。

f:id:nowsprinting:20150607044650p:plain

送信フォーマット

GCMに渡すメッセージが、APNsの形式に置き換えられてデバイスに届きます。例えばサンプルでは以下のフォーマットをGCMに送っています。

[
    "to": to,
    "notification": [
        "body": "Hello from GCM"
    ]
]

デバイス側ではPush通知のuserInfoとして、以下の形式で受け取ることができます。

aps =     {
    alert = "Hello from GCM";
};
"gcm.message_id" = "0:1433613206212203%4deaf3f24deaf3f2";

badge, sound

badgeとsoundも以下のように指定できました。

[
    "to": to,
    "notification": [
        "body": "Hello from GCM",
        "badge": 10,
        "sound": "default"
    ]
]

iOSデバイスのアプリアイコンにバッジが付き、またPush通知の受信音が鳴ります。 またアプリでは下記形式で取得できました。

aps =     {
    alert = "Hello from GCM";
    badge = 10;
    sound = default;
};
"gcm.message_id" = "0:1433613206212203%4deaf3f24deaf3f2";

その他のパラメタ

上記以外のパラメタは、notification下、もしくはdata下に設定することでアプリに渡すことができます。

[
    "to": to,
    "notification": [
        "body": "Hello from GCM",
        "key2": "value2"
    ],
    "data": [
        "key1": "value1"
    ]
]

アプリでは下記形式で取得できました。

aps =     {
    alert = "Hello from GCM";
};
"gcm.message_id" = "0:1433613206212203%4deaf3f24deaf3f2";
"gcm.notification.key2" = value2;
key1 = value1;

notification下に書いたkey2は、受信側ではgcm.notification.key2というキーに置き換わっています。構造を見る限り、data下に置くほうがよさそうです。

ペイロードに指定できる内容の詳細はリファレンスを参照してください。

Notification payload support

Topic Messaging

Topic Messagingについては次の記事を参照してください。

nowsprinting.hatenablog.com

*1:GCMのサイト内にサンプルとして掲載されていたもので、実在のトークンではありません

*2:ただし、サンプルアプリをそのままiOS 7で動作させるとクラッシュします。iOS 8で導入された[UIApplication registerUserNotificationSettings]を呼んでいるためで、iOS 7以前では[registerForRemoteNotificationTypes]を使用するように書き換える必要があります

#TwitterFlock でFabricの話を聞いてきたメモ

Twitter社主催のアプリ開発者向けイベント"Twitter Flock Tokyo"に行ってきました。このイベントはTwitter社が提供しているFabricについてのもので、各都市で開催されています。

f:id:nowsprinting:20150520075937j:plain

Fabricではいくつかのサービスが提供されています。これまで、ベータ版配布サービス"Beta"、クラッシュログ解析サービス"Crashlytics"については導入事例も聞いており、興味を持っていました。

しかしそれだけでなく、ユーザ認証、Twitter連携、広告までひとまとめのSDKで提供されています。むしろ逆に、『広告SDKに、"Beta"、"Crashlytics"、ユーザ認証などの機能が無償でついてくる』くらいの印象を持ちました。

それぞれ(有償の)競合サービスが出ている中、これら機能を無償で提供して広告でマネタイズするということなので、頭ひとつ抜けたというか、もう別格と考えて良さそうです。

以下、セッションの内容のメモ。

Keynote

はじめに、サービスの全体像、Fabricの機能を一通り紹介。

実装サンプル"Cannonball"は、iOS/AndroidそれぞれGitHubにプロジェクトが公開されている。iOS版はSwiftで書かれている。

github.com

github.com

iOS/Androidとも、SDKの組み込みは非常に簡単。

日本企業の導入事例として、Cyber Agentさん、cameranさん、OneNewsさんの紹介。

Twitter主催のスタートアップコンペ"Hatch"の紹介。

DIGITS

  • DIGITSは、電話番号認証。Fabricの"Twitter Kit"に含まれる。
  • モバイルを前提としたサービスでは、電話番号認証はとても有効
  • これまでも類似サービスは存在したが、以下の理由で難しく、サービス利用も高額だった
    • SMS APIは国・キャリアによって異なる
    • 電話番号からキャリアを判断する必要もある
  • Twitterでは独自にこの機能を構築しており、9年の実績がある。DIGITSはこれを一般の開発者に無償で提供するもの。
  • 認証用ボタン、認証画面はSDKで提供。コールバックを書くだけで使える
  • 認証画面のbackgroundColor, accentColorなどカスタマイズ可能
  • userID, authToken, phoneNumberを取得可能
  • SMSメッセージはローカライズされる
  • AndroidではINTERNETパーミッションが必要
  • Androidで以下のパーミッションを許可すれば、1タップでログインも可能
    • READ_PHONE_STATE
    • RECEIVE_SMS
  • iOS/Androidネイティブアプリだけでなく、html5でも利用可能
  • digits.comで、電話番号変更やTwitterアカウントとの統合などを行える
  • 電話帳マッピングで友達のアカウントを探す

Crashlytics Kit

  • stability, testing, analyticsにまつわるサービスが統合されている
  • デバイス、OSバージョン、3G/WiFi、メモリなどの情報も収集
  • ユーザセションに属性をセットすることで、セグメント分析も可能
  • answersは、リアルタイムの分析エンジン。セットアップするだけでいくつかの指標で分析できる
    • ダッシュボードで見るほか、Emailでレポート
    • stability alert。安定度がしきい値を割るとアラートメールを送ってくれる
    • カスタムイベント(beta)
    • アプリのバージョンアップ当日、以前のバージョンとのクラッシュ率などを比較

Twitter Kit

  • "Fablic.with(TwitterKit)"で利用可能。様々なモジュールがあるので、"with"で宣言。"start"なども検討したけど"with"に。
  • Twitterアカウントによるシングルサインオン
  • シェア
    • TweetComposerクラスにチェインで指定。text().url().image().show()
    • 埋め込みツイート。リアルタイム、コンテンツの補完
    • TWTRTweetViewで表示もViewレベルで提供。サイズ、テーマなど設定が可能
    • TweetViewDelegete
      • willShareTweet
      • didSelectTweet
      • etc..
  • ゲスト認証(limitはある)
  • REST API Client
  • 使いかたはCannonballを参照

広告

  • オーガニック
    • Twitter Card。いくつか種類がある中に、App card。
    • アプリのページにmeta tagで書く
  • deep link
    • アプリのURLスキーム起動、Twitterカードからインストール通知を受けられる
    • カード表示のとき、URLスキームを見て「ストアで開く」か「アプリ起動」ボタンになる
  • full deep link
    • URLスキームに続けてパラメタを渡す
  • 分析
    • analytics.twitter.com
    • アプリのコンバージョン測定
    • Twitter card経由のインストールも計測できる
    • cardのインプレッション、アクティビティ
    • インフルエンサーと人気コンテンツを計測(インプレッション、インストール)。インフルエンサーに直接コンタクトできるのがTwitterの強み
    • CrashlyticsのアカウントとTwitterアカウントを連携することで、cardの計測が可能
  • プロモーション(paid)
    • セグメントを絞って広告を出せる。id指定もできるので、既存ユーザのみ、既存ユーザを除く、といった指定も可能。
    • ペイド:オーガニックには相関関係がある。ペイドの3.9〜5.2倍のオーガニック(インプレッションやクリック)が得られる

MoPub

  • 広告SDK
  • AdMob, iAdなど、他の広告ネットワークにも接続できる
  • 表示される広告は、MoPubと広告ネットワーク混在でオークションされ、高値の広告を表示できる

所感

評判の良い"Beta"、"Crashlytics"に、Analyticsの"Answers"もセットになってるなら使ってみよう、くらいに思っていましたが、他の機能も強力。

MoPubも筋が良さそうな印象で、広告SDKに対する締め付けも色々出てきている中、単に「セットだから」でなく、これ単体でも十分検討に値するのではないかと。

また、Twitter連携、DIGITSは、MBaaS各社とも競合しそうですね。この先もしPush通知などをサポートしてくると、MBaaSでなくFabricだけで足りるというアプリも出てきそう。 (Twitter社としては、Push相当のことをTwitterでやらせたいような気もするので、実現性は低いかも)

第1回 #DroidKaigi に行ってきました

AndroidエンジニアのAndroidエンジニアによるAndroidエンジニアのためのカンファレンス、第1回*1 DroiKaigiに参加してきました。

f:id:nowsprinting:20150427003737j:plain

発表資料は公開されていますので、簡単なメモと感想だけ残します。

droidkaigi.github.io

基調講演(@yanzmさん)

  • マッチョなActivity
    • Android 2.2までは個人開発者の時代
    • Android 4.3まで、アプリベンチャーの時代
    • Android 5.0はインフラ化の時代。Material Designはアニメーションに本気で取り組むと大変
    • Activityにすべて書いていたら破綻する
    • Activityはテストしにくい
  • 分割先の選択肢として、FragmentとCustomView
    • FragmentはActivity寄り
    • CustomViewについては『Android Pattern Cookbook』の第6章参照
  • Activityがマッチョになる要因と対策
    • 画面回転のときの値保持は、CustomViewのonSave/RestoreInstanceState()に実装する(Activityに書かない)
    • データとViewのマッピングもCustomView内に実装する
    • バリデーションも同様
  • Fragmentではまらないために
    • FragmentへのコールバックはsetTargetFragment()を使う
    • バックスタックは難しい
    • FragmentからstartActivity()ははまる。startActivityForResult()はもっと危険。
    • Fragment in Fragment、Loaderとの組み合わせは危険。startActivityForResult()も危険。

Fragmentは手を出すのが遅かったので未だに恐る恐る使っていますが、このセッションを聴いて恐怖++と同時に、このままFragmentを使っていくという方向は腹をくくっていいのかな、と。

データとViewのマッピングやバリデーションは、私はViewModel的なクラスに実装することが多いかも。分量次第ですが。

参考書籍。『Master of Fragment』は、ベータ版を脱するための加筆候補がたくさんあるそうです。

tatsu-zine.com

CardboardのUXをカメラで向上する(@ken1_takaさん / Room B)

  • Oculus Riftはケーブルとか面倒
  • Cardboardはお手軽。でもタッチパネルが使えないので操作に難あり
  • Cardboardにはカメラ穴があいてるので利用したい
  • Cardboard SDK: 複眼ビュー、樽ゆがみ、マグネットボタン
  • OpenCVでカメラ画像を認識させて、ジェスチャー操作させる

デモアプリが(高速化に失敗して)動かなくなったとのことで残念。OpenCVで指の形状・ジェスチャーを認識できるデモは見ることができました。

なお、OpenCVで頑張るほか、Leap MotionAndroid SDK(今はアルファ版)を待つという選択肢もありますね。

www.leapmotion.com

あるゲームアプリケーションの構成とアップデートサイクル(@iizukakさん / Room B)

  • KLabさんの某音ゲーAndroid 2.3以降対応、2〜3ヶ月に一度アップデートしている
  • ビルド〜デプロイプロセスを「パイプライン」と呼んでいる。GitHub, Jenkins, API, アセット類はAmazon S3にデプロイ
  • 50MBが非Wi-Fiでのapkサイズ限界。ゲームでは足りないので、リソースは追加ダウンロード
  • アップデート、Google Play(apk)は2〜3ヶ月ごとに、追加DLで済むものは数週間ごとに実施。
  • 開発後半は、apkはデイリーで作成してテストエンジニアに配る
    • リリース向けのDL版でなく、アセットを全部バンドルした「フル版」数百M〜数GBのapkを使う
    • 開発終盤はDL版でテスト
    • 実装者は思い込みや見落としがあるので、テストエンジニア重要
  • クラッシュレポート、Developer Consoleはあまり参考にならないので、ほかのサービスを使う
    • 遅延なく監視できるのか、NDK部分を分析できるか
    • Crashlytics, SmartBeat

ビルド〜デプロイプロセスの自動化は、テスト自動化を伴わないとしても開発効率を上げるものなので、KLabさんのように専業のパイプラインエンジニア(ビルド職人)がいなくても、ちょっと時間を取って整備するといいですね。

内部テスト向けの配布はDL版でなくフル版を配る、というのは良さそう。ぜひ真似したい。

紹介されていた書籍。ビルド職人の端くれ(兼業)として、ポチりました。

ゲーム・映像制作パイプライン構築マニュアル

ゲーム・映像制作パイプライン構築マニュアル

ソフトウェア一般としてはこちらもオススメ。

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

アプリの企画、プロトタイプからリリースに至るまで(@__chocomelonさん / Room A)

  • pixivマンガ。少人数のチーム、ファーストリリースまで3ヶ月
  • 以下の順で開発
    1. ストアの紹介文をメンバー全員で持ち寄って大喜利。アプリの売りを明確化
    2. 雑なプロトタイプ。機能ごとに、雑に。メンバーが物理的に近いことが大事。
    3. イメージ共有後、デザイナーがSketchでライブデザイン
    4. アプリのプロトタイプを作る
      • これもコードは捨てる前提。言語、ライブラリなどを試す。
      • DeployGateで社内で使ってもらう
      • バグの印象がユーザに残ってしまうので、雑過ぎなのもよくない
      • 毎日やっていると、バグフィックスなどに追われて本来のプロトタイプとして機能しなかったので、3日サイクルくらいに。
      • ふりかえり
    5. コーディング。プロトは捨てる
      • サービスで使う言葉を統一する("編集部オススメ"→"EditorsPick"とか)
      • CircleCIでdevelopブランチの変更ごとにビルドして、DeployGateにcurlで上げる
      • 新規開発なのでPull Requestが巨大になりがち。こまめにコミット、こまめにPR
      • ちゃんとKPTでふりかえるようにした。週一。
      • リリース前2weekをバグフィクスにあてる。機能の多さよりクオリティを担保。
  • 以降のリリースサイクルは2week、月曜から段階的に20% → 50% → 100%
  • リリース前週の水曜にコードフリーズ、金曜にチェックシート
  • 朝会後、5〜10分チームメンバー全員でドッグフーディング(立ったまま)
  • 毎週、KPTとはべつに、アプリの今後を全員で考える「ヴィジョナリータイム」実施。エモい。
  • チャットツール(idobata)にcrash hook。Crashlytics連携でメインのチャットに投げられる
    • Play Storeのレビューもhook。gsutilで取得する。ただし2日遅れ
    • ご意見フォーム(id入力とかの要らないカジュアルなもの)もhook

ストアの紹介文から入る点、機能ごとの「雑なプロトタイプ」を作る点と、それでイメージを共有した上でデザイナさんがデザインを作っていく、というプロセスは面白そう。

チャットにクラッシュやユーザの反応を流していくのも良いアイデアだと思いますが、それをissue化する作業が誰か(当事者意識を持った人)に依存してしまう恐れがありそう。真似るなら、KPTや「ヴィジョナリータイム」もセットでやらないと危険かも。

大容量データのダウンロード戦略(@misyobunさん / Room A)

  • android.app.DownloadManagerを使う選択肢。ただし、
    • アプリ内でやりたい。統一されたUIを提供したい。
    • Googleのダウンロードアプリに状況を出したくない
  • 自力で実装。android.app.DownloadManagerのソースを参考にする
  • DLタスクの状態を管理するContentProvider
  • Serviceを使う。Activityをまたぐ処理を行なう場合
    • Serviceから、startForeground()でNotificationを出せる。プライオリティも上がるので死ににくい
    • Activityとプロセスを分けると、ヒープも別になり死ににくい。AndroidManifestに書ける
    • IntentServiceはシリアル実行なので、パラレルしたければ自力でServiceから書く。
    • 生死ハンドリング、プロセス名を使って生存確認
      • onTaskRemoved()は機種によっては呼ばれないので注意

進化するランタイムART(@kmt-tさん / Room A)

  • ARTを理解するには、まず『Android仮想マシン Dalvik編』を読むべき
  • LollipopからはART
  • OATファイル、OATコンパイラが吐く
  • DEXファイルは、OATファイルに埋め込まれる。Annotationなどのメタデータ
  • OAT
    • ELF形式、共有ライブラリ(.so)と同じ
    • リンカ、ローダはOAT独自
    • .rodataセクション:Linux標準のものに加え、DEXそのもの、GCガイド情報など
    • .oat_patchesセクション:OAT独自。イメージの再配置情報
  • QuickコンパイラJITコンパイラベース(だけどARTでは高速化されている)
  • ほかのコンパイラは最新のmasterでは削除されている
  • Quickは、LIR層までCPU依存でない(DalvikはLIRはCPU依存だった)

他のセッションと比較して、はじめからハードル高めな低レイヤの話でした。まずDalvikを知るべし。

tatsu-zine.com

買ってあるけど読めてません…

ARTのメモリ管理(@haru067さん / Room A)

  • GC ルートスキャンと再マークの一部を並行実行されるので、停止は3msくらい
  • LOS(large object space): 大きいオブジェクト専用スペースを設け、フラグメントを抑える
  • 並行(concurrent)GCの実行タイミングが賢くなった
  • 並列(parallel)GC、マルチコアな端末に向けて
  • 世代別GC
  • アロケータ、ResAlloc。並行メモリ割り当てが改善され、ロック不要になった
  • 質疑応答
    • コンパクションは基本やらない。backgroundのアプリを対象

GC(Garbage Collection)の話。Androidはmark and sweepだという認識を持ったままでしたが、色々進化していることを知りました。

つかえるGradleプロジェクトの作り方(@zaki50さん / Room A)

  • 設定するとできること
    • buildToolsVersionなどの一元管理
    • デバッグ証明書をプロジェクトに含めて管理
    • リリースapkへの署名
    • バージョンコード設定
    • git hashを埋め込む
  • Android StudioGUIでもかなり色々設定できる(build.gradleに反映される)
  • 記述方法は、『Android実践プログラミング』第5章および、GitHubで公開しているandroid_gradle_templateリポジトリを参照

techbooster.booth.pm

github.com

アプリを公開する前に、最低限知っておきたいセキュリティ事項(@tao_gakuさん / Room A)

Android Security 安全なアプリケーションを作成するために

Android Security 安全なアプリケーションを作成するために

Material Design を取り入れたデザインリニューアル(@ninjinkunさん、@yuki930さん / Room A)

Fril 3.xにおける、マテリアルデザインのキャッチアップから実装まで。

design

  • キャッチアップ。Feedlyが参考になる。Googleガイドラインは頻繁に更新されている。
  • ユーザテストを実施。既存ユーザの体験を損なう変更があった。
    • 画面下にあったタブをドロアに入れたため、
      • お知らせを開くのに2タップ必要になった
      • 未読バッジが見えなくなった
    • ActionButtonでお知らせに遷移するように変更した。標準的なUIから外れるが、ユーザテストの結果を尊重した
    • ユーザの動線。タイムラインを見た後、お知らせがあれば見て終了、という流れだった
  • 標準のタイポグラフィに合わせると日本語フォントに合わないので調整した
  • Sketch向けUIパーツがGoogleから配布されている
  • アイコンはsvgをIcoMoonというサイトでフォント化して使用。アプリサイズも削減できる。
  • textAppearanceを活用。styleの切り分けが楽に。

code

  • Support Libraryが出る前だったので、UI部品も自力で実装。後のバージョンでSupport Libraryに切り替え
  • リニューアルと同時に構造もモダンに。Fragment, Retrofit, RxJavaを導入
  • calligraphy。textViewに外部フォントを読み込み可能にしている
  • ListViewスクロールに合わせてActionBarを隠す
  • @yanzmさんに加わってもらったことを契機に、メンバー増加に備えた
    • コーディング規約などを整備、CONTRIBUTIONS.mdに集約した
    • JavaDocはちゃんと書くようにした。API Clientは特に丁寧に書く。
    • ActivityやFragmentの継承(BaseActivity/Fragment)をどうすべきか問題。Frilでは使わないこととした
  • リニューアル後、滞在時間2倍くらい、継続率も伸びてる、売買の成約率も上昇。
  • 登録の動線も見直し、離脱率も削減。
  • Googleの2014 Best Appに選ばれた
  • Android 4.0以上にした。2.3向けに旧バージョンを提供はしている。

今ならSupport Libraryがあるとは言え、「導入しました」では済まないところなので大変参考になりました。

なかでも、ガイドラインユーザビリティのくだりは身につまされました。ActionButtonをタブのように使うのは気持ち悪いだろうな、と。でも、既存ユーザの慣れの問題なのか、動線の問題なのかまで踏み込んでいるので、気持ち悪いながらも決断したというところでしょうか。

所感

connpassによる募集は瞬殺、大量のキャンセル待ちを抱えたイベントでした。通常、首都圏のこの手の参加費無料イベントは当日キャンセルも多く、6〜7割くらいの入りになってしまうものですが、今回は10:00の開始時点でかなり席が埋まっているという状態。しかも年齢層が若い。

Android関係の開発者コミュニティの活動が鈍っている、という話はかなり前から聞き、また実感していたところですが、これを見ると需要はあって、個々のコミュニティでうまく世代交代ができずに失速しただけなのかも。

またスタッフの人数も多く、とても至れり尽くせりなイベントでした。スケジュールアプリの提供と、アプリからアンケートフォームを開き、回答してくれた人にステッカーを提供、という流れはとても良いですね*2。 アンケートの回答率がどれくらいだったか、大本営発表が楽しみです。

主催の@mhidakaさん、スタッフ、登壇者の皆さん、また会場提供のサイバーエージェントさんに感謝。 次はDroidcon Tokyoを開催してJeke神を呼ぶ、という話がかなり現実的に聞こえて(見えて)いるので、引き続き期待しています。

*1:と言っていい気がしたけど、次はDroidcon Tokyoになる可能性も?

*2:この手のイベントを主催するとだいたいいつも問題になるので、できれば真似したい