React Nativeで 位置情報アプリをつくった話

React Nativeで 位置情報アプリをつくった話

【第2回】ReactNativeにゆかりのあるスタートアップが集う会
https://r-n.connpass.com/event/117895/

332a3cac4844d33179de6389b9d5f186?s=128

Tsuyoshi Higuchi

February 21, 2019
Tweet

Transcript

  1. React Nativeで 位置情報アプリをつくった話 Tsuyoshi Higuchi @tyshgc 2019.02.21

  2. 今回のトピック React Native と Google Mapsを利用 位置情報の追跡・大量のマーカーの取り扱い ユーザの現在地追随アプリを作成した際に得た知見

  3. 自己紹介 樋口 剛 Tsuyoshi Higuchi 今日はエンジニアとしてやってきました。 基本はサービスとUIをデザイン(設計)する人ですが インフラとバックエンド以外は基本何でもやります。 Reactは5年くらい、React Native歴は半年程度。 @tyshgc

  4. サービスの紹介 KiiiN - キーン - という現実世界に 金塊「キーン」をばら撒いて それを集めてモノと交換する 位置情報 ×

    ロイヤリティプログラムサービス 33,503 33,503
  5. インセンティブを提供し ユーザを特定の場所へ誘導・現実世界の活動を 流動的にすることによって ビジネスの機会をつくろうというサービス

  6. アプリの要件 ❶ユーザの現在地に追随する ❷大量のカスタムマーカーを配置・更新する 現在地の取得の精度・デバイス依存問題 マーカーのレンダリングコスト問題 ISSUE

  7. 主に利用している位置情報関連のライブラリ https://github.com/react-native-community/react-native-maps react-native-maps https://github.com/manuelbieh/Geolib geolib https://github.com/neuberoliveira/react-native-gps-state react-native-gps-state

  8. アーキテクチャ 今回は状態管理周りにMobXを採用 社内的にVue.jsユーザが多い & 堅牢性は(設計次第で)劣るが記述量はReduxより少ない コンポーネントはContainer Component Pattern Atomic Designの粒度定義は無駄にファットになるのでいれない

  9. Container Component Model UseCase A User Event 1 User Event

    2 UseCase B User Event 1 User Event 2 Domain Store = [ State, State, … ] Presentational Store = [ State, State, … ] Stores MobX ࣮ମԽ Model Element Component Element Component 1SPWJEFSܦ༝Ͱ ঢ়ଶมߋ࣌ʹ ࣗಈͰ౉͢ API / Realm / NativeAPI !BDUJPONFUIPEΛୟ͍ͯ4UBUFͷঢ়ଶΛมߋ 1SPQTͰ஋ͱ6TF$BTFΛ౉͢ 6TF$BTFͷ ΠϕϯτΛୟ͘ 4UPSF͸αʔϏευϝΠϯʹؔ͢Δ΋ͷͱ 1SFTFOUBUJPOBM (6* ʹؔ͢Δ΋ͷͰ෼͚Δ
  10. None
  11. None
  12. None
  13. None
  14. 位置情報を扱う React Nativeで位置情報といえば Geolocation APIは、Geolocation Web仕様を拡張したもの navigator.geolocation

  15. None
  16. 現在地の取得は一部のAndroidデバイスで 取得できたりできなかったり、精度微妙… RN公式でも react-native-geolocation-service を 使えとのこと

  17. Geolocation APIは積極的に使わず react-native-mapsの MapViewコンポーネントの onUserLocationChange を活用 onUserLocationChange: (event=> { const

    { latitude, longitude } = event.nativeEvent.coordinate }) 返り値(緯度・経度)をUsecase経由でStoreへ投げて諸々処理する方向へ
  18. None
  19. None
  20. None
  21. onUserLocationChange は、 showsUserLocationとfollowsUserLocationを trueにしないと返り値を返さない… { showsUserLocation: true, followsUserLocation: true, onUserLocationChange:

    (event=> {…}) } ただしこれらをアクティブにするとMap上に青い現在地が表示されてしまう
  22. 33,503

  23. また、onUserLocationChange は、 かなり小さい移動も検知するため イベントを呼ぶ回数をgeolibで間引く必要がありました。 { showsUserLocation: true, followsUserLocation: true, onUserLocationChange:

    (event=> {…}) }
  24. 大量のCustomMarkerと闘う マーカーを独自のイメージに変更したい場合は… <Marker image={画像} coordinate={現在地} />

  25. iOSは表示も周りのインタラクションも激重!! CPUを食いまくるらしくFPSは大幅に低下する

  26. tracksViewChangesでfalseを指定する <Marker image={画像} tracksViewChanges={false} coordinate={現在地} /> falseだと何も表示されないので componentDidMountでMountできたらfalseにする

  27. None
  28. None
  29. マーカーに込み入ったことをする こんな感じにマーカーをしたい場合は… 33,503

  30. <Marker image={画像} tracksViewChanges={false} coordinate={現在地} > <View style={…}><SvgOriginalImage /></View> </Marker> <Marker

    />にchildrenを渡せばいい アプリではSvgのアイコンイメージをマーカーにしようとした
  31. Androidでchildrenが表示されない… iOSとAndroidで微妙に表示の扱いが違うぽい

  32. <Marker …> <Svg width={MARKER_WIDTH} height={MARKER_HEIGHT}> <View style={…}><SvgOriginalImage /></View> </Svg> </Marker>

    AndroidはSvgコンポーネントで挟んであげる ※iOSはSvgいれると表示されなくなるので注意
  33. ReactNative所感 ReactNative自体はReact経験者にはやさしい Native Bridgeコードも言うほど障壁高くない ただ、OSSのライブラリはインストール時にコケることが 多く特にXcodeが辛すぎた… AndroidStudioはSDKバージョン周りで最初にコケた…

  34. ご静聴ありがとうございました