ご利用企業様1,300社を超えるシェアNo.1建設クラウド「&ANDPAⅮ」。図面共有サービスβ版をリリース
オクトのプレスリリース(2018年9月27日 10時00分)ご利用企業様1,300社を超えるシェアNo.1建設クラウド[&ANDPAⅮ]。図面共有サービスβ版をリリース
https://prtimes.jp/main/html/rd/p/000000019.000018154.html
株式会社オクトのアプリエンジニアの山下です。
施工管理アプリ&ANDPADのiOS/Androidアプリの開発と新規事業の立ち上げを担当しています。
私自身が一番得意な開発はiOSアプリの開発ですが、新規事業の開発ではアプリ領域に限らずサーバーサイド、インフラなど幅広い技術を使って開発を行っています。
私達の会社では絶賛開発メンバーを募集中なのですが、Saasというサービスの特性上どのような開発を行っているのか中身が見えにくいというのを課題として感じています。また、建築業界というIT化がそれほど進んでいない業界のサービス開発というイメージから使っている技術がレガシーなのではないかという誤解をよく受けます。私たちの会社の文化として最新の技術で最高のサービスを提供したいという思いがあります。そのため、会社のメンバーは最新の技術が大好きですし、積極的にサービスに取り入れています。
例えば、施工管理アプリのiOS/Androidの開発では、Swift/Kotlinを採用してRxSwift/RxJavaのMVVM構成など比較的最新の技術は取り入れる形で開発していたり、現在開発中のサービスでは、Go+Clean ArchitectureでのAPI開発、Vue/Nuxt.jsでのWebフロント開発、Flutterでのアプリ開発にチャレンジしています。今回は、新規事業として立ち上げた図面管理アプリの開発内容を説明したいと思います。
この開発では、一般的に使われるようなアプリ設計を工夫したというよりも、iOSのUIKitやCore Graphicsを駆使するなどして普段開発しないようなタイプのアプリ開発を行いました。
株式会社オクトでは、建築業界向けのプラットフォーム&ANDPADを開発しています。
&ANDPADのメインの機能は施工管理と呼ばれる職人の方々向けのプロジェクト管理ツールです。
建築現場では、図面と呼ばれる構造物の設計図が広く使われています。施工管理サービスの中では図面は単純にPDF資料として共有されていましたが、元々は紙の資料として共有されていたものなので共有された図面資料は設計者、職人と複数人の間でただ共有するだけではなく、手書きで書き込んだり、チェックマークを付けたりといった柔軟な使い方がされていたという背景があります。デジタルデータに置き換わった後でもそのような使い方をしたいといった要望が多く寄せられていたことから、紙のような柔軟な使い方ができる図面用新アプリの開発がスタートしました。こちらの開発は、無事リリースが完了してお客様に使われはじめています。
図面アプリの機能を簡単に言うと、PDF資料に保存された図面の各ページを複数人で共有しながら手書きで書き込んだり、写真付きのピンを設定できたりするアプリです。図面アプリでは、レイヤー構造を持った画面が構成されています。一番下には図面を表示する図面レイヤーが置かれ、その上にテキスト、ピン、手書きなどのオブジェクトが置かれる構造になっています。説明上このオブジェクトを装飾オブジェクトと呼び、それを配置するレイヤーを装飾レイヤーと呼びます。
図面アプリでは、以下のような装飾オブジェクトを定義しています。
・テキスト
・ピン
・スタンプ
・ペン(手書き機能)
もともとiOSのView構造もレイヤー構造で保持されいるため、なるべく同一のレイヤー構造をとれるように設計しています。また、それぞれの装飾オブジェクトは、タップやドラッグ&ドロップによって独自の動き(フリーハンド、位置の移動、選択)をするので、それぞれの動作はタップイベントをフックする形で実装しています。具体的には、hitTest:withEvent:をフックする形で対応を行いました。
装飾オブジェクトの位置情報は端末固有の位置情報として取得できます。説明の便宜上この座標系を端末座標系と呼びます。端末座標系は、端末の画面サイズから算出された値なのでその値をそのまま別の端末の座標系にマッピングすると位置がずれて表示され正しい位置に表示することができません。Androidよりも端末の種類が少ないとはいえ、iOSを搭載する端末は、iPhone8,iPhoneX,iPad,iPad miniなど様々な大きさの画面を持つ端末があるためこのような端末の種類にも対応する必要があります。
このような問題の解決方法として、端末ごとに正規化された位置情報を定義して端末間で共有する方法を採用しました。具体的には、端末ごとに取得された位置情報を端末に表示されている図面サイズで正規化して共有する方法を用いています。
実際の実装では、ユーザー操作によって画面のサイズが拡大縮小されたり、端末の向きが変わったりすることが頻繁に発生するためにその条件も考慮する必要がありますが、そのような条件を考えないで単純化すると以下のような式で表すことができます。
offset_x: 端末座標系と配置されている図面のx方向のオフセット
offset_y: 端末座標系と配置されている図面のy方向のオフセット
width: 端末座標系で表示される図面の幅
height: 端末座標系で表示される図面の高さ
x' = ( x - offset_x ) / width
y' = ( y - offset_y ) / height
この正規化座標系で表される位置情報は、端末サイズに依存しない形式で図面に対して相対的にどの位置にオブジェクトが配置されているかを表す情報になっています。したがって、この正規化座標系の位置情報をサーバー経由で複数の端末に共有することで正確に図面に対しての装飾オブジェクトの位置をマッピングできるようになります。
受信側の端末からは、自身の端末で表示している図面のサイズ情報と、端末画面に対しての図面のオフセット位置の情報が取得できれば正確に位置情報を復元することが可能です。
図面アプリの利用用途としては、図面のデータをあらかじめ端末にダウンロードしておき、インターネットに繋がっていない状態に置いても図面をチェックしながら書き込みの操作を行うなどの利用用途を想定していたため、いわゆるオフライン対応を行いました。オフライン対応では、軽量なストレージエンジンとして人気のRealmを採用して実装をおこなっています。Realmでは、リアルタイム同期機能がサービスとして提供されていますが、今回はそのサービスの採用は行わず、同期機能の実装はスクラッチで実装を行っています。
サーバーとクライアントの構成は以下のようになっています。
弊社のサーバー環境はRuby on Railsで構成されており、施工管理サービスとの連携が簡単に行えるように
今回は同一環境上にAPI機能を追加する形で実装しています。施工管理側では、容易に連携しやすいようにあらゆる機能がモジュール化されています。そのために、このようにAPIを追加するだけで施工管理側の資産を活かしながら連携機能が開発できるようになっています。
端末側での装飾オブジェクトの位置計算は、それぞれの端末座標系で計算されて表示されますが、サーバー経由で座標情報を共有する場合は図面サイズで正規化された値で共有されます。それぞれの端末で共有された座標情報は、端末座標系の値に計算しなおされ表示されています。
この方法を用いることで一旦端末内に座標情報がとりこまれてしまえばそれぞれの端末内のロジックで座標計算を行えるようになります。
図面管理アプリの構造の大枠の説明をしてみました。
実際の開発では、表示上のズレやパフォーマンスチューニングが一番大変だったのですが、そのあたりの苦労話は省略しています。弊社のアプリ開発では、施工管理アプリではUITableViewやUICollectionViewを用いた比較的標準的なアプリ開発を行っています。このように少し標準的な構成から外れたタイプのアプリ開発も新規サービスとして取り組んでいます。技術的には常にチャレンジングな環境をご用意してますので、ご興味持った方は是非一度オフィスに遊びに来てください。いつでも開発内容に関してご説明致します!