graphql-pokemon と Paging Library を使ってアプリを作った

github.com

なかなか GraphQL を使っている Android アプリの実装が見当たらなかったので、自分で作ってみた。 ついでに、Paging Library を使いたかったので使ってみた。 題材は赤・青・緑時代の 151 匹のポケモンに関する情報を取ってくることができる API。

github.com

解説

GraphQL

以前ざっくり紹介したので概要はそちらを見ていただくとして

speakerdeck.com

今回は以下のようなライブラリを使って実装した。

GraphQL を使えるようにするために

  1. build.gradle 書く
  2. graphql.config.json 書く
  3. apollo-codegen で schema.json ダウンロードする
  4. schema.graphql 書く
  5. ビルドしたら apollo-android 経由で API を叩けるようになる

といった流れで設定している。このコミットが該当。

github.com

Paging Library

The paging library makes it easier for your app to gradually load information as needed from a data source, without overloading the device or waiting too long for a big database query.

とのこと。(公式より)

DataSource

データを取得する箇所。3 つ用意されているが、今回は PositionalDataSource を使った。

class PositionalPokemonDataSource constructor(private val apiClient: ApiClient) : PositionalDataSource<PokemonsQuery.Pokemon>() {
    override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<PokemonsQuery.Pokemon>) {
// 本当は first と offset を指定したいが、API 側で提供されていないのでとりあえず足している
        apiClient.getPokemons(params.loadSize + params.startPosition)
                .subscribeBy(
                        onSuccess = {
                            callback.onResult(it.pokemons() ?: emptyList())
                        },
                        onError = {
                            Timber.d(it)
                        }
                )
    }

    override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<PokemonsQuery.Pokemon>) {
        apiClient.getPokemons(params.requestedLoadSize)
                .subscribeBy(
                        onSuccess = {
                            callback.onResult(it.pokemons()
                                    ?: emptyList(), params.requestedLoadSize)
                        },
                        onError = {
                            Timber.d(it)
                        }
                )
    }

}

最初に loadInitial が呼ばれ、ページング処理をするときに loadRange が呼ばれる。

DataSource.Factory

Factory では DataSource を返すだけ。

class PokemonDataSourceFactory constructor(private val apiClient: ApiClient) : DataSource.Factory<Int, PokemonsQuery.Pokemon>() {
    override fun create(): DataSource<Int, PokemonsQuery.Pokemon> = PositionalPokemonDataSource(apiClient)
}

ViewModel

ViewModel では PagedListBuilder を使って PagedList の LiveData を作る。 RxPagedListBuilder を使うと RxJava の Flowable か Observable でデータを監視することができる。 詳しくは ↓

Paging Library  |  Android Developers

class PokemonViewModel : ViewModel() {

    companion object {
        private const val LOAD_COUNT = 10
    }

    private val config = PagedList.Config.Builder()
            .setEnablePlaceholders(false)
            .setInitialLoadSizeHint(LOAD_COUNT)
            .setPageSize(LOAD_COUNT)
            .build()
    val pokemons: Flowable<PagedList<PokemonsQuery.Pokemon>>

    init {
        pokemons = RxPagedListBuilder(PokemonDataSourceFactory(ApiClient()), config)
                .setFetchScheduler(AndroidSchedulers.mainThread())
                .buildFlowable(BackpressureStrategy.LATEST)
    }

}

感想

graphql-pokemon の API で、ポケモン一覧を取ってくる Query が first しか指定できなくてつらかった。 他の API にしようかと思った(スターウォーズの API とかある)けど、ポケモンのかわいさに勝てなかった。(ウィンディかわいい)

Paging Library はサンプルがわかりにくかったけど、どのクラスで何をするのかを理解したらわかりやすかった。ViewModel でやってた処理が DataSource に移るのでちょっと違和感。

GraphQL Tokyo Meetup #5 でセッションオーナーをやった

www.meetup.com

前回の #4 がいけなかったのでリベンジ。 f:id:rnitame:20180327124739p:plain

セッションの内容

  • Apollo のライブラリを使って GraphQL をプロダクション投入したけれど、キャッシュとかテストの良い書き方が見つからないのでその辺の話 /w @bird_tummy

apollo-android, apollo-ios, @nuxtjs/apollo など使っているけれど、パフォーマンス面の向上(それこそキャッシュを使ったり)とかテストの書き方は従来のアプリと同じで良いのか?というお話。 また、Android / iOS に関してはなかなかサンプルとなる実装やそもそもプロダクションに投入している事例が少ない(ように感じる)。React 等でもそういった時期があったはずだが、その時どういったスタンスで実装していたかを聞きたかった。

セッションの導入として YAPC::Okinawa で発表した資料を使った

speakerdeck.com

議論できた内容

  1. テストのお話。もう少し噛み砕いてからまとめたいが、サーバとクライアントそれぞれがテストで担保する範囲を決める方法で一つの解は見えた。本業で導入してみたい
  2. キャッシュは一旦ライブラリにまかせる。CACHE_ONLY 等 apollo でサポートしてくれているものを使う

議論できなかった内容など

  • 事例が少ない時代のスタンス
  • apollo などのライブラリにロックインされてしまう現状と自前実装するしないの判断について
    • 少し joe_re さんとお話できたがもっといろんな方の話を聞きたい

まとめ

初心者向けセッションで学んでから次のセッションで実用寄りの話に行く、という流れができていて初心者でも大丈夫な環境があるのがとても良かった。

あと、この 2 つが完全に同意する話 😂

初めてのオープンスペース形式だったけど、普段の勉強会と違って特定の技術を中心とした議論が高いレベルでできたので新鮮で楽しかった! ありがとうございました&お疲れ様でした!次回も参加します!

余談

meetup.com、こういう文言がこだわっててとても好き。イベント終了後のアンケートもあったけどスクショ撮るの忘れてた ・ω・

YAPC::Okinawa 2018 ONNASON で GraphQL について話をした

yapcjapan.org

単純に沖縄に行きたくて勢いで CFP を出したら採択していただいて話してきた、というお話。

重視したこと

  • GraphQL を仕事で触っているが、まだ理解が浅いところがあるので深掘りする
  • 40 分ちゃんとしゃべる
  • 畑違いのカンファレンスだけどみんなが理解できるような発表をする

トーク内容

CFP はこちら

f:id:rnitame:20180125073735p:plain

「GraphQL って実際どうなの?というお話はいろんな方のブログで議論されたりしているが、導入してみた結果どうなったのかという部分はまだまだこれから事例が出始めるタイミングだと思う。それの先駆けというか、一例として捉えていただけたらいいな〜」という気持ちで CFP を書いた。

スライドはこちら。

speakerdeck.com

結果と感想など

  • GraphQL を仕事で触っているが、まだ理解が浅いところがあるので深掘りする
    • 深掘りはできた。けど、自分の担当ではないサーバやフロントは浅いままで終わってしまった
  • 40 分ちゃんとしゃべる
    • 35 分?くらいだった。何個か質問もらえたのでよし
  • 畑違いのカンファレンスだけどみんなが理解できるような発表をする
    • Twitter 見る限り理解していただけた…?かも?

Perl Monger な方がほとんどだと思っていたので、Perl を使っていない自分としては言語に縛られない資料づくりと喋り方を心がけたが、後半 Android 寄りになってしまったので後悔。 ただ、何件か GraphQL やってみよう的なツイートを観測できたので、これからユーザーが増えていっていろんな知見が溜まってくれると嬉しい。

今こういう気持ちです。

まとめ

高校ぶりの沖縄だけど最高!!!

もう少し満喫してまた来週から仕事がんばる〜〜

Homebrew で Vim の最新版を入れようとしたら make でこけた

けど解決したお話。

事象

teratail.com

全くこれと同じ状況だった。下記コマンドでインストールしていて、使っているプラグインの都合上 Lua と Python は外せなかった。

brew install vim --with-luajit --with-python3

MacVim 入れるのもちょっと面倒だし嫌だな〜〜と思っていろいろ探っていたら解決した。

方法

brew doctor したら以下のメッセージが表示された。

f:id:rnitame:20180112121813p:plain

Homebrew でインストールした Ruby に link されていなかったのが原因だった。。 なので、brew link ruby してやり直す。

f:id:rnitame:20180112122159p:plain

めでたしめでたし。

SHISHAMO っていうバンドがすごいので聴いてほしい

http://spice.eplus.jp/articles/155716/images/388980 http://spice.eplus.jp/images/MQFvU5uUP5tQnaxNwUmCDBFloqfD5rPzYgNWrqoOwxMOGKsY9s2KFM7tnxdtF1Ye

adventar.org

Dark アドベントカレンダーの記事。 なんでもありとのことだったので、SHISHAMO について書こうと思う。

筆者の SHISHAMO ファン歴は 4 年ほどで、今年からライブに本格参戦し始めた勢。 最近 Dark の #music チャンネルで徐に「明日も」の YouTube リンクを貼り付けたら、テンションが上がってしまい以下のような感じになってしまうくらいにはまっている。

f:id:rnitame:20171112235305p:plain

SHISHAMO とは?

公式サイトから抜粋。

Gt.&Vo.

f:id:rnitame:20171117111840p:plain

通称:朝ちゃん。歌声はかわいい感じだけど地声は低く、よく自分でネタにしている。
ファインディング・ニモのクラッシュが大好き。最近、ディズニーシーのタートル・トークで「カメと人間の恋愛ってありですか…?」って聞いて「まずは海で泳げるようにならないとな」と返されてイケメンじゃね!?!?!って言う話をライブでしてたのがおもしろかった :D

Ba.

f:id:rnitame:20171117112105p:plain

通称:彩ちゃん。ライブに行ってたら朝ちゃんに声をかけられて、親を説得し上京。2014年に加入。 声も仕草もかわいく、ファンから人気高め(だと思っている)。ライブですぐかわいい〜〜〜と言われるため、朝ちゃんによく怒られる。

Dr.

f:id:rnitame:20171117112400p:plain

通称:みさきちゃん。朝ちゃんと彩ちゃんのやりとりを後ろからツッコミ入れたりするお母さんみたいな存在。エゴサの鬼。サッカーがうまい。ライブの MC のコンテンツになっている、最近あった出来事を話す回がおもしろい。笑

www.youtube.com

川崎フロンターレ大好き

朝ちゃんとみさきちゃんが川崎出身というのもあり、川崎フロンターレをめちゃくちゃ応援している。
Gゾーン(応援の中心エリア)ど真ん中で飛び跳ねたりするレベル。
「明日も」の PV を等々力で撮ったり、応援チャントになったり、ライブを等々力で開催するなど密接な関係になっている。

www.youtube.com

まだデビュー 5 年目

高校の部活時代からバンドを組んでいたものの、デビューアルバム( http://amzn.asia/bi0SCUD )を出してから4年しか経っていない。
しかもインディーズ。最近テレビでも言っていたが、健康でよりよい音楽を届けることが信念で、最初から人気になりたい!とかは思っていなかったらしい。
でも今年の docomo の CM 曲に抜擢されてからの SHISHAMO の認知度の上がり具合はすごかった。いいよ。 SHISHAMO いいよ。

ブスかわいい?

そんなこんなで知名度上昇中の SHISHAMO だが、Google 先生はちょっと非情な検索候補を出してくる。

f:id:rnitame:20171117113901p:plain

右下の「不適切な検索候補の報告」を今すぐ押したい

そんな見た目は気にせず!!歌に注目してくれ!!!って気持ちしかないのであまり触れない。

女子中高生に人気とはいうものの

フロンターレ経由だったり、最近であれば docomo の CM やミックス。の映画経由で知ってくれた人が増えたので、年齢層の幅は広がってきた。 ライブのコールアンドレスポンスで年代ごとにうぇーい!っていうやつがあるけど、前までは中高生が多かったのが最近は大学生以上(大人でくくられている)が多くなってきた印象がある。なのでみんなライブに行こう!!

SHISHAMO のこれから

年末は紅白にでるし、春はまたワンマンツアーが始まる。7月には念願の等々力ライブがあるのでもうライブに行くしかないですね!!!

まとめ

YouTube にあるから見てくれ!!!聴いてくれ!!! 記事の最初にある画像が載っているインタビュー記事も最高なので読んでくれ!!! そしてちょっとでも良いなって思ったらぜひ一緒にライブに行こう!!!頼む!!!

spice.eplus.jp

実装のバリエーションを増やすために(続)

rnitame.hatenablog.com

ライセンスページとか build.gradle 見てバリエーション増やしたいねって話を書いたがそれの続編。 変わらず Android を例にしている。

最近

日々 GitHub のトレンド眺めながら使えそうなものとか参考になりそうなものに star をつけていて、以前 star をつけていたライブラリを実戦投入する機会があった。 README とか wiki を見ながら導入はできたのだが、ライブラリが推している範囲を超えて機能を実装しようとしたときに手が止まってしまうことがあった。

そんなときに mizchi さんのとあるツイートを見た。

もう、俺じゃん!!!!!って気持ちでしかなかった (´・∀・`)

じゃあどうする?

ってなったとき、OSS を使えるようになることはそれはそれで良いと思うけれども、ちゃんと OSS のコードも読んで中で何をしているかを理解するといいと思った。 例えばこのライブラリ。

github.com

Epoxy is an Android library for building complex screens in a RecyclerView

とあるとおり、Epoxy は RecyclerView で複雑な画面を作るためのライブラリ。 Basic Usage を見ると、

f:id:rnitame:20171211103007p:plain

EpoxyModel と EpoxyController の 2 つがメインのコンポーネントらしい。 なので、EpoxyModel と EpoxyController のコードを読んでみる。

GitHub で読むのつらいし Android Studio も重いので clone したらコードジャンプと検索だけができるエディタが勝手に立ち上がってほしい

EpoxyModel

epoxy/EpoxyModel.java at master · airbnb/epoxy · GitHub

EpoxyModel は ViewType ごとのレイアウトを決める要素。っぽい。 EpoxyModel を管理するために使う id を生成するメソッドがあったり、後述の EpoxyController に対して EpoxyModel を追加するための addTo メソッドがあったり。EpoxyAdapter を使って作る場合は bind を使うのかな?

EpoxyController

epoxy/EpoxyController.java at master · airbnb/epoxy · GitHub

EpoxyModel で決定した要素に対してデータをあてて表示するために使うもの。 add で Controller に Model を追加して、requestBuildModel で追加した Model に対してデータあてたりしてる?っぽい。addInterceptor は OkHttp の Interceptor みたいな感じなんだろうか。

といった感じで理解が進む。 コードを読み進めるとどういった条件で Exception を投げているかもわかるので、そこから粗方使い方が想像できるし、テストが書かれていれば(ほとんどのライブラリで書かれていると思うので)それを見て使い方を確認することもできる。

Android 特有の書き方を深く学ぶために

冒頭に貼った記事を書いたときに比べ、ライブラリのコードを読むようになったが、Android 特有の書き方に関しても知らないことが増えてきたのでおさらいしている。 今見ているのは公式のトレーニングページ。

developer.android.com

…の横にあるこれ。

f:id:rnitame:20171211170859p:plain

(いつのまに Best Practices for ... とかできてたの…) これを見てみると、

Build a Responsive UI with ConstraintLayout | Android Developers

ConstraintLayout を使ってレスポンシブな UI を作るために、ConstraintLayout の導入方法が説明されていたり、

developer.android.com

ANR を避けるために気をつけることが説明されていたりする。100〜200ms を超えるとユーザーは遅いと感じるらしい。すごいためになることがたくさん載っている。

まとめ

ライブラリの内部実装読もうねって話と、基本に立ち返って公式のページを見てみるのもありかもって話をした。 Android、完璧に理解できるようにがんばりたい。

実装のバリエーションを増やすために

最近仕事をしながらこういうことを思っていて。

その難しさの要因の1つに、自分の中に実装のバリエーションが少ないことがあるんじゃないか、と思っていろいろ考えてみたのでまとめてみる。 筆者が Android アプリメインであるため、Android を例にご紹介。題材は最近はまっている Dropbox Paper。

play.google.com

実装のバリエーションとは

ここではエディタなどのコンポーネント、そのコンポーネント内の細かい挙動やアニメーションなどを指す。

実装のバリエーションを増やすと何が嬉しいの?

今いるチームでは、デザイナーがプロダクトとしての世界観を維持しつつ a11y などを意識してデザイン。エンジニア(自分)はそれを見つつ Material Design により準拠できるようにデザイナーと話し合いながら実装する形で進めている。

その中で、デザイナーから「こういうデザイン実現したいんだけどできそう?」という質問によく遭遇するのだが、今はそれに対して調べないとわからないことが多い。バリエーションを増やせばスパッと答えることができるし、バリエーションが多いともっと UX 的に良いデザインが提案できる(かもしれない)と思った。

やはりエンジニアとしてアプリを作っている以上、ユーザーに価値を届けられることが一番の目的であるので、その価値を届けるための近道ができるようになるのが嬉しい

バリエーションを増やす方法

Play Store で配信されているアプリ

Dropbox Paper のように配信されているアプリは、だいたい設定画面あたりにオープンソースライセンスへの導線が存在する。Dropbox Paper だとここ。

f:id:rnitame:20171112184941p:plain

それを活用して、知らなかった OSS 等を見つけたらひたすら触ってみる。ただただ触っても楽しくないのでいろんなアプリをカテゴリごとに分けて、それぞれのカテゴリから1つアプリを選んで比べながら触ってみるGoogle Play Store で配信されているアプリは必ず1つのカテゴリーに属しているため、それで判断すると良い。例えば、Dropbox Paper は仕事効率化(PRODUCTIVITY)だった。

f:id:rnitame:20171112183156p:plain

Dropbox Paper を触ってみると、 このページは ViewPager で作ってるのかなーとか。

f:id:rnitame:20171112184935p:plain

このページだとタブは TabLayout か何かで、FAB があって、RecyclerView か ListView でリスト出しつつ、EditText の onTextChanged が発火したときにリストの内容を変更するのかな?とか考える。

f:id:rnitame:20171112184939p:plain

OSS

OSS は build.gradle を見てビルドして触る。 基本ストアで配信されているアプリと同じ要領だが、気になった挙動があればコードを見ることができるのでより詳細に把握できる。 最近は各地で Droidcon が開催されているので、それの公式アプリやスライドで使われたリポジトリをよく見ている。

github.com

github.com

github.com

まとめ

実装のバリエーションを増やすために、いろんなアプリを触ってみようねというお話。 最近 Kotlin が流行ってるけど、そういう言語も含めて実装のバリエーションを常にアップデートするようにしたい。