iOSエンジニアのtakecianです。
株式会社メルカリでは YOUR CHOICE という「働く場所・住む場所」を自由に選択できる制度があります。そのため同僚とはリモートワークでコミュニケーションを取りながら仕事を進めることが多いです。(六本木にオフィスはあるので出社して仕事をすることも可能です)
リモートワークで働いている時にアプリのバグを見つけたり、気になる挙動を見つけた時にアプリの画面を録画して共有することがあります。「ここの動作がおかしい気がする」「この順で操作すると画面表示が変になる」など、操作中の画面を録画してもらい、ビデオを受け取って確認してみます。ですが画面にはどこをタッチしたかは表示されないので、「どういう操作をしているか」「どこをタップしたか」が分かりにくいと思った経験が iOS エンジニアだと誰もがあるのではないでしょうか。
このエントリでは、iOSアプリで見つけたバグの再現手順をリモートワーク中にスムーズに共有するために行った取り組みについて紹介します。
例としてメルカリのアプリを操作をした画面を録画してみました。
この例ではマイページからいくつかの項目をタップして別の画面に遷移していますが、どこをタップしたのか分かりにくいですよね。
そこでタップした箇所が表示されるようにしてみたいと思います。iOS のタップイベントは UIWindow
の sendEvent
メソッドで送られてくるので method_exchangeImplementations
を使って sendEvent
メソッドを自前のメソッドに差し替えてみます。
private static func swizzleSendEvent() {
guard let originalMethod = class_getInstanceMethod(UIWindow.self, #selector(sendEvent)),
let swizzledMethod = class_getInstanceMethod(UIWindow.self, #selector(swizzledSendEvent))
else {
return
}
method_exchangeImplementations(originalMethod, swizzledMethod)
}
すると画面をタップした時に差し替えたメソッドが呼ばれるようになるので、そのメソッドの中で元の UIWindow.sendEvent
を呼び出しつつ、画面に触れている場所の座標を取得します。(この処理をおこなわないとタップしたというイベントが伝搬せず止まってしまいます)
@objc
func swizzledSendEvent(_ event: UIEvent) {
// 自身を呼び出すことで差し替え前のメソッド(`UIWindow.sendEvent`)を実行します
swizzledSendEvent(event)
guard case .touches = event.type, let touches = event.allTouches else {
return
}
// UITouch の画面に触れているものを集合に追加する(複数箇所の同時タップを想定)
let beganTouches = touches.filter { $0.phase == .began }
UIWindow.touches.formUnion(beganTouches)
// 画面から離れた分を集合から取り除く
let endedTouches = touches.filter { $0.phase == .cancelled || $0.phase == .ended }
UIWindow.touches = UIWindow.touches.subtracting(endedTouches)
// 座標に変換する
let touchLocations = UIWindow.touches.map { $0.location(in: self) }
// touchLocations に入っている座標が画面に触れている場所なので描画する。
// コードは省略。
}
取得した座標上に UIView を表示することでタッチしている箇所が分かるようにしてみました。先ほどと同じ操作を録画してみたのがこちらです。
どういう操作をしているかが簡単に分かりますね。この機能を実現するために使用した method_exchangeImplementations
はメソッドの呼び出し先を変更してしまうというとても強力なものなので、大人数で開発している環境ではできるだけ使うのは避けたいものです。そこでこの機能は compiler directives (#if DEBUG という書き方で特定の環境でのみコードが動作する仕組み) を使って開発中のアプリでのみ動作するようにしています。
この機能を紹介したところ、特にQAチームの人から喜ばれました。Bug の再現手順を分かりやすく共有できるようになったのではないかと思います。
このようなちょっとした工夫を入れることでリモートで仕事をしていても効率的に仕事を進めることができます。
株式会社メルカリには全国様々な場所から働いている同僚がいて、新たな価値を生みだす世界的なマーケットプレイスを創るために日々楽しみながら開発しています。興味のある方はこちらから募集を見てみてください。