はじめに
こんにちは。8月8日から6週間、LINEの技術職就業型コースのインターンシップに参加したUCLA3年生の綱脇彩恵です。私は期間中、LINEサービスプラットフォーム開発チームに配属され、GPS情報およびBeacon情報の調査機能の開発に携わりました。フルリモートのインターンシップにも関わらず、こまめに連絡を取りながら毎朝メンターのマイケルさんと打ち合わせもあり、作業は問題なく進めることができました。
本記事ではインターン期間中に実際に取り組んだ作業や実装の内容についてご紹介させて頂きます。
概要
Location Platformで収集したGPS情報およびBeacon情報を調査、及び分析できる機能を実装し、Debug Menuからその機能を手動で実行させるための開発を担当しました。
Location PlatformとはLINEのサービスに利用されるために分析されるGPSやビーコンなどのデータが集計されているLINE内部のプラットフォームです。LINEの開発用ビルドではDebug Menuが用意されていて、開発やQAをスムーズに行うための様々な機能が実装されています。その一貫として、GPSやBeaconデータの分析ができる機能を今回開発しました。以前はこのデータを画面に表示する機能が設備されていなく、データアクセスが難しい状態でした。この新たな機能を実装することによって、ユーザー同意の上で取得したデータが容易に確認できる様になり、データ分析なども可能になります。
データの種類
今回扱うデータにはBeacon情報とGPS情報があります。
Beacon(ビーコン)とは、光や電波を発する固定された無線の装置を指し、その光や信号を受信した電子機器を通して利用者がその場に来訪したことを知ることができます。そして、スマートフォンやタブレットなどの利用者に、その場のニーズに合った情報を端末を通して伝えることができます。スマートフォンの場合、Bluetoothを使って信号の送受信を行うのが一般的です。精密度と自由度の高いマーケティングのツールとしても使われており、ビーコンで得た情報を利用し、よりニーズにあったサービスを提供することが可能になります。
GPSデータは人工衛星が発する電波を利用しているので、広い範囲で受信できる一方で、その分精度はあまり高くなく、室内や人工衛星の電波の届かない地下などでは利用できません。LINEではビーコンデータとGPSデータを両方利用することによって、ユーザーのより精密な情報を取得することができます。この情報をもとに既存のサービスを最適化したり、他社に提供できる新たなサービスを作り上げることができます。
例としては、社員が会社を出社、または退社する際に精密なデータを利用して、打刻が自動的に登録されるシステムの開発などがあります。また、ある自動販売機に近づけば、LINEのアプリ上で飲み物を買う画面が表示される機能の実装なども可能になります。
データ取得の構造
LINEのアプリ上では、ビーコンデータの収集とユーザーのGPSデータの収集は独立して実行されています。以下の図では、具体的にデータがどのように取得されているかがまとめられています。

アプリが立ち上がると、ビーコンのスキャンが行われます。その際に確認されたビーコンの情報がLINEのサーバーに送られ、サーバー側からそのビーコンに対する指示を受け取ります。ビーコンへの距離を RSSI (Received Signal Strength Indication)を使い計算し、ユーザーが一定の距離に近づけば、サーバーからの指示が実行される仕組みになっています。ビーコンのスキャンが行われていると同時にGPS情報も取得されます。取得されたGPSデータとビーコンデータが合わさって一つのデータとなります。
このデータを取得する間隔は reportTimeInterval によって定められています。(上図では180s)
今回のプロジェクトではこのデータを保管し、Debug Menuを経由してデータアクセスが可能な機能を実装しました。
業務内容
デバッグ環境の設備
まずはじめに、データを取得する間隔を示すreportTimeIntervalをユーザーが指定できるように実装をしました。今回の開発ではデータが思い通りに保管できているかの確認がこまめに必要だったので、デフォルトの180秒では長過ぎました。iOSにGPSデータを更新する時間を設けるために、ユーザーが指定する時間間隔が20秒以上であるように制限もかけました。データの取得間隔を自由に指定できると、データ分析が効率的になり、その後の開発に役に立ちます。
データの保管
次に、データ保管の開発に進みました。データに含まれる複数の値をオブジェクトで管理するための構造体、またその構造体の変数や関数などの処理が記述されているクラスを定義しました。
GPSデータには以下のような値が保管されています。
- Latitude/Longitude:GPSデータの緯度経度
- Timestamp:GPSデータが取得された時間
- Beacon Data:ビーコンスキャンから取得されたビーコンデータの配列
- Accuracy Mode:ユーザーのGPSデータの使用を許可されている場合のデータの精度レベル
- Trigger Mode:GPSデータレポートを開始するトリガー
ある一定の場所からビーコンが数個確認できる場合があるので、ビーコンデータは配列として保管しました。
また、常にこのデータを保管したいわけではないので、デバッグ画面からデータの保管を有効、無効にできる機能も実装しました。
データの表示
この保管したデータを実際に画面に表示する機能を次に実装しました。画面の実装にはUIKitという、Appleが提供してくれているiOSアプリケーションを構築するためのグラフィカルUIフレームワークを使用しました。経験のない新しいフレームワークだったので最初は苦戦しましたが、メンターさんのサポートもあり、勉強をしながら開発を続けました。事前にメンターさんが作って頂いた画面のプロトタイプをもとに作業を進めましたが、開発中に気付いた改善点などを導入し、変更しながら取り掛かりました。例えば、当初のデザインでは画面の左上にあったリフレッシュボタンですが、前の画面に戻るボタンが必要だったので、右上に変更したりなど、UINavigationBarの配置に関する修正が多くありました。
GPSデータをテーブルビューで表し、それぞれのセルをクリックするとそのデータの詳細が表示されます。また、Google Mapを画面の上部に表示し、各データごとに緯度経度を用いてマーカーを重ねました。これらのマーカーにクリックすると、そのデータに相当するテーブルのセルがハイライトされる仕組みになっています。新しいデータが保管されるたびに画面のデータが更新されるようにリフレッシュボタンも実装し、使いやすさを重視した開発を進めました。データの削除 (delete) や書き出し (export) の機能も加え、保管されているデータをデベロッパーが自由に扱えるようにしました。
今回実装したメイン画面のビュー階層は以下の様になっています。階層を事前に明確にすることによって親子関係が表せられ開発が容易に進められ、関係性を一目でわかるのが便利でした。iOS開発ではどのようなレイアウト構成にするかは大きな検討ポイントとなるので、ビュー階層の作成は重要な開発過程です。

全ての機能が揃ったところ、以下のUIが完成しました。(テストデータを使い表示)

経路の表示
マップ上にたくさんのデータが表示されていますが、これらのマーカーを結ぶ経路を作成して画面に表示させます。そうすることによって、実際にユーザーが進んだ経路や通った道順などを具体的に調査することができ、そのデータをもとに更なるサービスの向上につながります。経路の書き方はシンプル経路とスムーズ経路の2種類に分けて実装しました。
- シンプル経路:以下の様な一番容易な経路の書き方です。マップ上のマーカーをタイムスタンプによって順番付け、一つずつ結んでいきます。実装は簡単ですが、たくさんのデータが集まると少し見にくくなってしまいます。

- スムーズ経路:シンプル経路の問題を解決するために使用したアルゴリズムです。この場合、ある一定の個数のデータポイントをクラスターとして定義し、そのクラスター内の平均座標が頂点となり、それらをつなげたものが経路となります。以下の通りに、シンプルな経路よりスムーズで見やすい経路が描かれます。経路の種類は一定の方向に進むだけではなく、円に沿って進む場合や往復するような場合でも経路が見やすく描かれるように工夫しました。Timestampがデータの一部として保管されていたため、ユーザーの大まかな経路がGPSデータが送られた時間によって定めることができたので、開発に役立ちました。

それぞれの経路アルゴリズムを実際に画面上で作動してみると、以下の様になります。シンプル経路に比べ、スムーズ経路の方が大まかな順路が見やすくなっているのが分かります。


タスク管理
LINEではJiraを利用した開発を採用しています。実際に開発を行う前に、メインタスクを複数のサブタスクに分解し、それぞれをBTSチケットとして発行します。サブタスクに分けることによって、完成までの必要作業や現在の進捗状況がイメージできるので業務が進めやすかったです。サブタスクの開発を終えるとGitにおけるPR (Pull Request)を出し、チームメンバーや他の部署の方にレビューをしてもらいます。これらのフィードバックをもとに適宜修正や改善をしながら開発を進め、クラス設計に関わるレベルの指摘から、チーム内のコーディングスタイルの違反まで、非常に丁寧なレビューを行っていただきました。綺麗で読みやすいコードを書く際のコミュニケーションとフィードバックの重要さを、これを通して身に感じました。
改善点
今回のプロジェクトは6週間という限られた期間での作業だったので、改善点がいくつかあります。
まず、経路の表示では2種類の経路アルゴリズムしか実装することができませんでした。シンプル経路に比べ、スムーズ経路は確かに見やすくなっていますが、問題点はまだいくつかあります。もしユーザーが一つの場所で長時間過ごした場合、受信した座標は一つの地域に集まり、スムーズ経路でも見にくくなってしまいます。この問題の解決策としては、ある一定の半径Rを定め、この半径内にある座標を一つのクラスターとすることです。その場合、次のクラスターの中心は前のクラスターの平均座標から半径Rの場所にあり、その方向はデータに含まれているTimestampで定めることができます。この様なアルゴリズムを実装することによって、もしユーザーが一つの場所に止まっていても、見やすい経路情報を表示することができます。
次に、データ表示の画面にオプション設定を実装すれば、さらに使いやすい機能が作れたかと思います。ある一定のトリガー種類だけのデータの表示、ビーコンが何個以上スキャンできたデータの表示、何時何分以前に報告されたデータの表示など、フィルターをかけることによって、求めるデータがすぐに表示されるのはとても便利な機能だと思います。
また、現在のデータはメモリーに保管されている状態なので、データ削除が簡単にできてしまいます。データを永久保存する場合はデータベースにコネクトし、安全に保管すると良いかもしれません。
まとめ
今回のプロジェクトではGPSやBeaconという今の時代には欠かせないデータを扱う機能の開発に携わりました。データの扱いやUIの開発に加え、経路を表示するアルゴリズムなど、多様な分野からの豊富な経験が積めてとてもやりがいのあるプロジェクトでした。実際にユーザーが目にしないようなデバッグ画面でも見やすさや使いやすさを重視する姿勢に驚き、丁寧にコーディングする重要さを学びました。今回実装した機能が今後開発者の役に立ってくれれば良いなと思います。
おわりに
インターン開始前は不安が大きく緊張していましたが、初日からメンターさんとの顔合わせでとてもフレンドリーに対応して下さり、楽しく働くことができました。今回の開発はあまり触れたことがなかったSwiftで行い、最初は慣れていないコードスタイルに苦戦しましたが、開発経験を積むことで効率的に技術を習得することができました。6週間という期間はあっという間に過ぎてしまい、多様な技術だけでなく、コミュニケーションやチームワークの重要さを実際に働いてみて学びました。メンターさんからもコードの書き方が最初に比べ良くなったと褒めて頂き、最終的にはスムーズに開発が進められるほどの実力がつきました。インターン期間中は業務に加え、定例のミーティングにも参加させて頂き、LINEで実際にエンジニアとして働いた際のイメージを持つことができました。
基本リモート勤務でしたが、最後まで楽しく業務を行えたのはメンターさんや開発チームのメンバーの皆様のおかげです。インターン中に関わった方々、大変お世話になりました。この6週間で身につけた知識と経験を大事にし、今後の開発に活かしていきたいと思います。とても貴重な経験を心から感謝しております。ありがとうございました。