ReactNativeで自分用のHBFavを作った

はてぶのお気に入りをタイムライン形式で読めるHBFavというアプリがある。

このアプリは自分にとってはTwitterFacebookの次くらいによく開くアプリで重宝している。

基本的な機能についてはほぼ不満はない。

しかし、クリップボードにコピーしたURLからブックマークをする方法については満足とはいえなかった。

この機能は、例えばTwitterFacebookなどでシェアされたURLをコピーしてHBFavを開くと、画面上部にニョキッとURLが書かれたnotification viewみたいなものがでてきて、そこをクリックするとURLのページが開き、そこからブコメを見たり、ブックマークしたりということができる。

挙動自体はワンクリックでシンプルに!という気持ちを感じるしよいのだけど、問題なのは対象のURLがブックマークできるのはそのnotification viewが出てる間だけだということだ。

つまり、ブックマークしたいURLをそのタイミングでブックマークしないと、2度とHBFav経由でブックマークができなくなる。

これは結構困る。人間何か考え事をしてぼーっとしているときもあるし、URLをコピーしている状態でHBFavを開き他のブックマークに気を取られてしまうこともある。

そういうわけでなんとかその挙動を回避したいなと思い公開されているHBFavのソースを見るのだが、RubyMotionで書かれているというところでいつも思考停止し「まぁ我慢するか...」となっていた。

ただ、ちょうど最近は本家の方も色々大変そうでアプリを弄ってる余裕はなさそうだし、ReactNativeで色々アプリを作りたいという気分もあったので勉強がてらHBFavのReactNative版を自作してみることにしようという流れになった。

実際結構前からそういう気持ちはあったのだが、どうも業務や業務や業務などがあってまとまった時間が取れなかったのでお盆休みのタイミングでガッと書いてみた。ちなみにストアには出してないです(ストアで申請するのが一番面倒くさい...)。

名前

ReactNativeで書いたので頭にRNを付けて「RNHBFav」とした。

ソース

置いときます。星くれ。

RNHBFav

対応OS

iOSのみ。Android使いではないので...。

挙動

機能

基本挙動は本家HBFavと同じです。

ただ、実装は自分が普段使っている機能のみに絞ったので色んな機能が無いです。例えばmixiシェアとかmixiシェアとか...。

で、分かる範囲で本家と違う点は下記です。

  • 人気/新着のエントリが無い
  • 他のユーザーのブックマークが一覧ページが無い
  • ブックマーク時のシェアはTwitterのみ
  • ブックマークコメントにフォロワーのコメントまとめが無い
  • クリップボードのURLからブックマークする機能が無い
  • 公開情報のみ扱う

また、オリジナルの機能としては下記です。

  • URLを入力してブックマークする機能
  • 表記や色味や文字サイズなどのデザイン

実装期間

一応自分のフロントJSスキルを書いておくと、

  • ES6は最低限書ける
  • SPAではないWebアプリでVue.jsを使う程度
  • FluxはVuexしか知らん
  • Electron+Vue.jsで小さなTwitterClientを書いたことがある

この程度。React関連はReactNativeしか知らない。

このレベルでお盆に歌マクロスのリズムゲーでイベントを走りながら3~4日くらいでとりあえず使えるとこまで実装できた感じ。

実際は今週ドッグフーディングしながら修正等を仕事から帰ってきてからやってたので細かいとこまで入れると1週間くらいかかってるかもしれない。

マクロスやってなかったらもっと早く出来た可能性がある。

フレイアが可愛すぎた。

苦労した点

苦労は以下の3点に集約される。

  • OAuth認証ライブラリを自作しようとしてハマった
  • ブコメのスター・人気スター数表示機能
  • エラー・ローディングの制御

1つめのOAuth認証ライブラリを自作しようとしてハマったというのは、お盆のハイテンションで何を思ったか0からOAuth1.0aライブラリを書いてみたいという気持ちになってしまいやり始めたが、思いの外fetchの使い方、signatureの生成、デバッグなどなどにちょこちょこ苦戦し、結局有りもののoauthライブラリを使うことになったというやつ。

実際動くレベルで大体出来たんだけど、コード汚いし、綺麗でよりvalidなライブラリあるしこっち使ったほうがよくね?という車輪の再発明が馬鹿らしくなってしまったのが敗因。

2つめのブコメのスター・人気スター数表示機能というのは、ブコメ閲覧ページに表示するスターを取得するところ。

あそこは各ブコメのURLから各スターを取得するのだけど、スター取得APIはGETで、そのエンドポイントにブコメuriをパラメーターとして付与してリクエストを投げるようになっているため、ある一定のブコメを超えると1本のリクエストでは412 URL Too Longエラーとなる。これを回避するためにリクエストを複数に分けるのだが、そうすると例えば1000ブクマとかある場合は10本以上スター取得のリクエストを発行しないといけなくなる。fetchとEventEmitterでなんとか書いたけどリクエスト数多い問題や実装汚い問題が残った。なんかもっといい方法ある気がする。

3つめのエラー・ローディングの制御というのは、アプリには付き物の非同期処理やユーザーへのレスポンスをしっかり返すという挙動を細かく設定するのが大変というやつ。

API通信をしている場合、ネットが切れてしまった場合、その他予期せぬエラーが発生した場合などなど、色々な状況が起きえるがその事象毎に適切なローディング・アラート・ページをしっかり返せるようにするのはデバッグで見落とす部分も多く、ドッグフーディングでわかることが多々あった。この辺の調整は結構再現が難しい場合も多く直すのに苦労する。

ReactNativeどう?

ページ遷移でViewの生成時のパフォーマンスで特にストレスを感じることはない。

タイムラインでは無限スクロールができるが、FlatListを使うことでかなり高速に動作する。

FlatListはやや使い方に癖があるが、リスト処理がくそ高速なので使わない選択肢は無し。

API通信周りは標準のFetch APIを利用。axiosとか使わなくても問題ない。

Reduxはメニューとタイムラインの間の状態共有で一部に使わざるを得ず導入したが、本当に必要になるまではいらない気がする。

レイアウトについて、ReactNativeはHTMLとCSSで組んでいくのとほぼおなじで本当にラクラクなので、これは推せる。

カメラ・ビデオ周りの処理や良い感じのアニメーションが苦手なのでそういう処理が必要ならばネイティブで頑張って。

iOSAndroidのソース共通化、これはOSごとの分岐が結構発生するだろうし、絶対後々しんどくなるので、デザインに凝らない人を除いてあまりしないほうが良さそうな気がする。実際やってないからなんとも言えないけど予想。

自分がReactNativeでアプリ作る時の構成とかは昔Qiitaにまとめたのでそっち見て。

他にも色々あるが細かいとこは忘れた。

いまだ謎の挙動

  • 認証してアクセストークンを得るが、それを利用してもたまに401 Authorization Errorが発生する
  • 認証画面で認証するをユーザーが選択しても失敗することがある
  • 通信状況が不安定時にwebviewでURLを開くとconnection errorの画面がブツブツ割り込んでくることがある
  • Webview周りの制御難しい...

まとめ

  • HBFavをReactNativeで書いてみた
  • そこそこJSかければ割と簡単にアプリは書ける
  • 良いユーザー体験のアプリにするためには言語やフレームワーク以外の地道な努力が必要

こんな感じです。

お盆休みの自由工作としてはまぁまぁ進捗出たし良かったです。

というか歌マクロスのVeryHard以上でフルコン出せないのなんとかしたい...。