お疲れさまです。
APP/UI チームの玉置です。
最近のマイブームは鬼滅の刃 (きめつのやいば)です。
ツイッター のタイムラインで鬼滅の刃 のワンシーンを見てしまい「おっ、刀がメインのアニメか!」と思ってNetflix で動画を見始めたのがきっかけです。
当時の動画のワンシーンは登場キャラの善逸くんが雷の呼吸「雷の呼吸 壱の型 霹靂一閃」を解き放って敵キャラを瞬殺したシーンです。
善逸くんのキャラが「るろうに剣心 」の十本刀の「宗次郎」にとても似ていてそのシーンだけで気に入ってしまいました。
(* 善逸くんは宗次郎のキャラとは全然違います)
そんなこんなで動画を見つけた日は善逸くんの上記のシーンまでの動画を徹夜で観ていました。
さて、そんな話しは置いとくとして今日は先月ずっと行っていた
レッスンルームのチャットのデザインで使っていたライブラリのリプレイス作業をずっと行っていました。
そして、やっと今月リリースできそうなのでその当時に色々思うことがありましたので文章化してみました。
リプレイスする前に使っていたライブラリについて
リプレイス前に使っていたライブラリは「JSQMessagesViewController 」という名称のものです。
github.com
2016年頃まではチャットアプリでごく一般的に使われていた有名なライブラリです。
こちらのライブラリですが2016年に大体の開発が終了してしまって2017年1月で完全に開発がストップしてしまいました。
github _commit_log
現在は非推奨となっています。
レアジョブアプリはライブラリ管理でcocoapodsを採用しているため、ターミナルでpod install
をした際にこのライブラリが非推奨というワーニングが表示されます。
depricated_JSQMessagesViewController
今はチャットライブラリで有名なものとして「MessageKit 」というOSS があります。
チャットアプリを開発する場合は自作するかこちらのライブラリを使うことが一般的になっています。
github.com
今回はこの「JSQMessagesViewController」からの脱却をメインに書いていきます。
リプレイスするきっかけと足枷になったこと
本当はすぐにでもJSQMessagesViewControllerを脱却したい気持ちがありました。
その理由を挙げるだけでも
2017 年から公式が非推奨
公式からのサポートが得られない
事業的にリファクタリング よりも新規機能の開発が優先
リファクタリング のコストを支払っても利益が出ないため報われない
リプレイスにかかるコスト(工数 見積が定かではない)
iOS のライブラリ管理ツールである「CocoaPod」からdepricated というワーニングが表示
などの要因がありました。
また、当社にはカスタマーサポートの部署があり(以下、CSと省略します)、CSよりユーザー様から
「講師側から長い文章が送信されると最後の1行が途切れている」という問い合わせを受けていました。
最後の1行のメッセージの空白
この問題に対して臨時対応を5月頃に実施して解消されているはずでしたが今年8月にも別のユーザー様から同じような問い合わせを受けてしまいました。
そのため使っていただいているユーザー様のためにもできるだけ早くこの問題の根本原因を解消しなければならないと思い、
チームのタスク的にも8月までに必要なタスクを終えて9月は1ヶ月丸々リファクタリング 期間を頂いたのでこれを機会にチャットUIライブラリを差し替える業務に本格的に着手することにしました。
リプレイスする上でのツラミ
実際にライブラリのリプレイスをすると決意してからが大変です。
今回のライブラリは「レッスンルーム」に直接影響を与える箇所ですのでデグレ に気をつけなければなりません。
その他、個人的に感じたリプレイスする上でのツラミは
開発メンバーに申し訳ない感
iOS のキーボードが意図通りに表示してくれない
差し替えたあとにiPad 横画面でデグレ が起きる
という三点でした。
それぞれ解説していきます。
開発メンバーに申し訳ない感
こちらはリプレイス云々とは関係ありませんが事前に工数 見積をしていても全てが事前に見積もれる訳ではありません。
特に今回のようなレアジョブアプリのメイン機能である「チャット」のデザインだと寧ろデザイン崩れやデグレ が発生している方が問題になります。
つまり既存仕様を全て正確に新しいライブラリで再現する必要がでてきます。
ただしどうしても新しいライブラリで「再現できない機能」はチームメンバーやプロダクトオーナーに相談して捨てることは可能だと思っています。
「デグレ 」と「捨てて良い機能」の定義はタスクや機能によって違いますが、
今回の定義では「事前に把握しているかどうか」です。
それはそうとして話しを戻しますが
今回のような見え方や挙動がだいたい同じデザインだと、作業中も私の中ではタスク全体として「達成感」はあまり感じられませんでした。
着手前と着手後で表向きとしては成果物が「同じ」ですので事業にインパク トを直接与える作業ではないのであまり楽しくなかったんですよね。
なので自分が楽しくないことにひたすら挑戦していたので(おまけに事業の売上に貢献していないことも含めて)
メンバーにその感覚が伝わってそうでリプレイス中はずっとメンバーに申し訳ない気持ちで一杯でした。
このツラさを解消できるKPT でいうところ、「Try」があればいいなと思いました。
そのためチーム全体が楽しくレガシーコードと向き合える方法があればリファクタリング が楽しいものになるんだろうなと思いました。
iOS のキーボードが意図通りに表示してくれない
後述する内容ですがリプレイス先の「MessageKit」のInputBarAccessoryViewがうまく意図通りに動いてくれなかったため、全ての挙動を既存仕様に合わせることが難しかったです。
特にキーボードの表示・非表示の制御がiPhone ・iPad に関わらず大変で着手中ずっとキーボードの制御に苦しめられました。
レアジョブアプリではチャットのviewがメインのViewControllerにCotainerとして乗っている設計でchildViewController になっています。
(main) RoomViewController > MenuViewController > ChatViewController (child)
という設計になっています。
この場合は ChatViewController で MessageKit のInputBarAccessoryViewを表示しようとすると初期表示時にInputBarAccessoryViewが画面外に隠れてしまう現象が起きます。
InputBarAccessoryViewが画面下にあるので表示されない
このような問題にも対応しなければなりませんでした。
念の為、この問題を解消するのに参考になったページを張っておきます。
github.com
github.com
差し替えたあとにiPad 横画面でデグレ が起きる
最後のツラミとして、今年5月頃に私が開発したものですがiPad のレッスンルームを横画面にも対応したのですが、MessageKitがそのあたりもいい感じに補正してくれると期待していたところ見事にそれを裏切ってくれました。
iPhone でだいたい既存の同じ挙動になることを確認してからデグレ 起きなかったらいいなと淡い期待を持っていましたが、
単純にJSQMessagesViewControllerからMessageKitに差し替えてもiPad を横画面にすると既存と全く同じ挙動にならなかったのです。
ライブラリリプレイスの本実装の調査前の段階である程度工数 見積をしましたが、
iPad 横画面ではその当時確認していませんでした。できなかったこともありますが。
そのため実際にこれを改修する前にデザインが崩れてしまう現象のパターンを洗い出して再度工数 見積を行いました。
着手前に見積もっていた工数 も残りわずかというか使い切ってしまいましたので、
恐怖に思いながらiPad 横画面でのデグレ 箇所の工数 見積をしていました。
想定外のデグレ の工数 はメンタルに良くないですね。
実際のリプレイス作業
ということで長々と書いてしまいましたが、ここで実際にライブラリをリプレイスしたときに行った手順を復習します。
ライブラリ自体の調査と挙動の調査 (工数 見積まで)
アプリの既存の動きの調査
MessagesKit自体のデザインの調査
MessagesKitがどこまで柔軟に対応できるか
試しimport でどれだけのデグレ が発生しているか
実際にライブラリをimportする (実際に着手開始)
MessageInputBar が使えず、InputBarAccessoryViewが必要
どのバージョンのInputBarAccessoryViewを使えばいいのか情報が少ないのでその調査を行う
そのためcocoapodのPodfile
は下記のようにInputBarAccessoryView
をimportしました。
pod 'MessageKit'
pod 'InputBarAccessoryView', '4.2.2'
ハマリポイントの改修 (想定外の対応)
ChildViewControllerでは初期表示時にInputBarAccessoryViewが表示されない
レッスンルームを一つのViewController で管理できるかの調査 (既存設計を大きく変える方法の調査)
メインのViewController で becomeResponder()を読んでinputBarを意図的に表示させたときの調査 (既存設計を踏襲する場合の調査)
iPad 横画面でのデグレ の対応
上記のような流れになりました。
レガシーコードと向き合った感想と気をつけるべきこと
今回はレガシーコードではなくライブラリのリプレイス作業について解説してみました。
新規事業だとガンガン突き進めて事業にもインパク トを与えられますがレガシーなものを新しいものに書き換えるようなリプレイス作業は見た目が変わらないので作業していてもなかなか辛い部分がありました。
ですがレガシーコードは綺麗にせずにそのままにしておくと将来の負債となったりメンテナンスできなくなって「ゼロから作り直し」になったりする非常にセンシティブな部分でもあったりします。
現場によってはプロジェクトのソースコード を「1から作り直し」になってしまった所もあるのではないでしょうか。
モバイルアプリは最初の1,2年は開発していてとても楽しいですがさらに長く運用していると様々な要因で昔のレガシーコードが影響して開発スピードが著しく遅くなってしまう傾向がありますね。
またApple やGoogle のSDK が年々新しくなって昔のソースコード がいきなり非推奨になったりします。
なので、時間がある時にできる限りソースコード を綺麗にして保守性を上げる開発体制が一番安全かなと思いました。
今回のチャットUIを新しくしたことでレアジョブアプリを使って頂いているユーザー様により快適にレッスンルームをご利用頂けると思うと開発者として報われる気持ちになりますね。
ということで長文になりましたがぜひレッスンルームを使って頂ければと思います。