$30 off During Our Annual Pro Sale. View Details »

チュートリアル実装の『そこどうしてる?』 Poiboyではこうしてる!

チュートリアル実装の『そこどうしてる?』 Poiboyではこうしてる!

2018年9月28日に株式会社Diverseにて行われた「マッチングサービス開発の裏側Night」での登壇資料になります。
https://diverse.connpass.com/event/100488/

Tomohiro Imaizumi

September 28, 2018
Tweet

More Decks by Tomohiro Imaizumi

Other Decks in Technology

Transcript

  1. チュートリアル実装の
    『そこどうしてる?』
    Poiboyではこうしてる!
    マッチングの裏側Night #1
    2018/09/28
    @imaizume

    View Slide

  2. <2
    INDEX
    • 自己紹介
    • Poiboyについて
    • Poiboyのチュートリアルと実装解説
    1.男女で画面のViewController分けるか問題
    2.実装をライブラリでやるか自前でやるか問題
    3.デバッグどう/どこまでやるか問題

    View Slide

  3. <3
    INDEX
    • 自己紹介
    • Poiboyについて
    • Poiboyのチュートリアルと実装解説
    1.男女で画面のViewController分けるか問題
    2.実装をライブラリでやるか自前でやるか問題
    3.デバッグどう/どこまでやるか問題

    View Slide

  4. ‣ 今泉 智博 @imaizume
    ‣ 2017年株式会社ミクシィ新卒入社
    ‣ 現在株式会社 所属
    ‣ iOS利用経験0から iOS版開発担当に
    ‣ (ほぼ)毎日健康COMP生活はもうすぐ1周年

    View Slide

  5. <5
    INDEX
    • 自己紹介
    • Poiboyについて
    • Poiboyのチュートリアルと実装解説
    1.男女で画面のViewController分けるか問題
    2.実装をライブラリでやるか自前でやるか問題
    3.デバッグどう/どこまでやるか問題

    View Slide

  6. とは❓

    View Slide

  7. Diverseが運営する
    カジュアルマッチングアプリ❤

    View Slide

  8. 最⼤の特徴 = ⼥性主導
    女性からの「いいね = ポイ」でマッチング成立
    男性はポイされた後に初めて返信できる
    ねらい
    マッチングアプリを初めて使う女性にも
    安心して使ってほしい
    ポイ
    メッセージ

    View Slide

  9. 今⽇の内容: Poiboyチュートリアルの実装⽅針
    実装で直面する疑問・課題とPoiboyでの実装例を紹介
    3つのテーマで実装の「そこどうしてるの?」を解説
    ウォークスルー
    登録前/登録後
    チュートリアル
    プロフィール
    登録
    今日話すところ
    Poiboyのチュートリアル構成
    SNS認証
    登録前チュートリアル
    プロフィール登録
    登録後チュートリアル
    ウォークスルー
    本使用

    View Slide

  10. <10
    INDEX
    • 自己紹介
    • Poiboyについて
    • Poiboyのチュートリアルと実装解説
    1.男女で画面のViewController分けるか問題
    2.実装をライブラリでやるか自前でやるか問題
    3.デバッグどう/どこまでやるか問題

    View Slide

  11. テーマ1: チュートリアルの画⾯
    (ViewController)を男⼥で分けるか問題

    View Slide

  12. 男⼥の画⾯どうやって分けてる??
    • 男女でUI/ロジックが似ている画面をどうするか問題
    • 男女ではなく登録経路で分かれることも…
    • プラットフォームで仕様が異なるケース(今回は割愛)
    ⽅針: A.共通化 / B.分離
    Facebook (左) と Twitter (右)
    男性 (左) と ⼥性 (右)

    View Slide

  13. A. なるべく共通化する
    • 男女/登録経路で共通のVCを使用
    • 内部Viewの表示切替え
    • 共通化が有効そうな場所
    • ログイン画面
    • プロフィール登録画面
    • 見た目が似ているUI
    // 画像切り替え
    self.banner.image = isMale ? maleBannerImg : femaleBannerImg
    self.user.image = isMale ? maleUserImg : femaleUserImg
    self.example.image = isMale ? maleExampleImg : femaleExampleImg
    // 制約切り替え
    self.maleContraint.priority = isMale ? .defaultHigh : .defaultLow
    self.femaleContraint.priority = !isMale ? .defaultHigh : .defaultLow
    男⼥共通のVC

    View Slide

  14. B. なるべく分離する
    // MARK: ViewController出し分け
    if isMale { // 男性
    let vc = MaleRegisterViewController()
    self.present(vc, animated: true)
    } else { // 女性
    let vc = FemaleRegisterViewController()
    self.present(vc, animated: true)
    }
    • 男女/登録経路毎のVCを定義
    • VC自体を表示制御
    • 完全分離が有効そうな場所
    • 性別に固有の体験
    • Viewや状態数が多い
    • UIや仕様変更が見込まれる
    男性VC ⼥性VC

    View Slide

  15. 共通化 VS 分離メリデメ
    A. 共通化 B. 分離 ✂
    メリット • DRYな実装がしやすい
    • Viewの構築時間を短縮可
    • ロジックの可読性が向上
    • 画面単位の仕様変更に強い
    デメリット
    • VC内のロジックが複雑化
    • コードでの状態変更
    • UIのバグ発見・再現が困難
    • WETな実装になることがある
    • ファイル数が増える
    • 同一変更でも複数箇所修正
    場面毎に考えて方針を選んでも良いが
    原則の方針は決めておきたい

    View Slide

  16. Poiboyではこうしている!
    VC内ロジックの簡素化を重視
    (以前は共通化したVCで条件分岐が増え
    男女間の表示バグが多発していた)
    VC単位で分離するケースが増加
    self.view1.hidden = false
    if isMale { // 男性
    self.view2.hidden = false
    self.view.text = " "
    } else { // 女性
    self.view2.hidden = true
    self.view.text = " "
    if isOk {
    self.view3.height = 80
    }
    }
    男⼥共通VC
    self.view1.hidden = false
    self.view2.hidden = false
    self.view.text = " "
    男性⽤VC
    self.view1.hidden = false
    self.view2.hidden = true
    self.view.text = " "
    if isOk {
    self.view3.height = 80
    }
    ⼥性⽤VC

    View Slide

  17. UI上のバグの発⾒/再現性
    片方に実装を忘れる → バグの発見・再現が容易
    コードでの状態変更 → バグの発見・再現が困難
    現在の課題: VCの名前に統一性がないため、新メンバーが把握に時間がかかる
    画⾯遷移テストの書きやすさ
    /// 性別選択で女性を選択後に女性用ウォークスルー画面が表示される
    func testNavigationToFemaleWalkThrough() {
    let navigator = NavigatorMock()
    let isBetaUser = false
    let vc = GenderRegisterViewController(
    navigator: navigator,
    genderStore: GenderStoreStub(isFemale: true)
    )
    )
    vc.tapFemaleViewAction()
    XCTAssertTrue(navigator.viewControllerStack.first is FemaleWalkThroughViewController)
    }

    View Slide

  18. 具体例 (プロフィール登録画⾯)
    男女共通に見えるが実は完全に別のVC
    • 画面上部のバナーパターンが増えても大丈夫だった
    • 前後のVCを増減しても影響が少なかった
    男性登録画⾯ ⼥性登録画⾯
    バナーが増えて
    もバグは出ない
    女性側よりも
    遅れて実装
    制約の付け替え
    が不要に
    細かい文言等の
    違いも一目瞭然

    View Slide

  19. <19
    INDEX
    • 自己紹介
    • Poiboyについて
    • Poiboyのチュートリアルと実装解説
    1.男女で画面のViewController分けるか問題
    2.実装をライブラリでやるか自前でやるか問題
    3.デバッグどう/どこまでやるか問題

    View Slide

  20. テーマ2: チュートリアルの実装
    ライブラリを使うか⾃前で頑張るか問題

    View Slide

  21. チュートリアル画⾯をどう作るか ??
    • 登録後ユーザーが必ず表示する画面
    • Poiboyではウォークスルーとコーチングの組合せ
    • 特にコーチングは自前実装そこそこ面倒
    ウォークスルー コーチング
    ⽅針: A. ライブラリ / B. ⾃前

    View Slide

  22. チュートリアル⽤ライブラリ
    • ライブラリもかなり充実 (調べて初めて知った)
    • 複雑なウォークスルーはRazzleDazzleがよさそう
    • UIがテンプレベースのため既視感が強い
    • 比較/詳解はtakatattaさんのスライドもご参考に
    • ephread/Instructions
    • aleksandrshoshiashvili/
    AwesomeSpotlightView
    • ruipfcosta/SwiftyWalkthrough
    • teodorpatras/EasyTipView
    • ariok/BWWalkthrough
    • hyperoslo/Presentation
    • ealeksandrov/EAIntroView
    • MatthewYork/MYBlurIntroductionView
    • IFTTT/RazzleDazzle
    ウォークスルー コーチマーク

    View Slide

  23. ライブラリ VS ⾃前メリデメ
    ライブラリへ完全依存したくないが完全自前も厳しい…
    A. ライブラリ B. 自前
    メリット • 導入・メンテの工数少ない
    • OS/端末ごとの動作保証あり
    • 複雑な仕様やUIにも対応可
    • アクション制御も自在
    デメリット • アプリへの最適化に限度
    • テンプレ的なUI/UX
    • デザイン次第で工数大
    • メンテコストも大

    View Slide

  24. Poiboyではこうしている!
    ライブラリ:自前 = 2:8 くらいのハイブリッド
    • ウォークスルー: 完全自前実装
    • 仕様変更が多い
    • ボタン配置やUIも最適化したい
    • チュートリアル: 自前 + 一部吹出しにCMPopTipView
    • 指定の矩形をくり抜くカスタムViewで実装
    • CMPopTipViewの吹出しを加えてコーチング
    • CMPopTipViewは画像等を含むことができない
    CMPopTipViewの吹き出し 画像の吹き出し

    View Slide

  25. 単純なコーチングの実装例
    • コーチマークVCを定義、各ステップでpresent
    • UIBezierPathでマスクを切り抜き
    ベースのVC コーチングのVC チュートリアル
    var rects: [CGRect] = [self.rect1, self.rect2, self.rect3]
    self.setupMaskView(rects: &rects, isCircle: true)
    // 複数矩形の切り抜きにも対応できるよう配列で定義
    let paths: [UIBezierPath] = rects.map { Helper.rectToSquarePath($0) }
    let maskLayer: CALayer = self.maskView.generateLayer(paths)
    self.maskView.layer.addSublayer(maskLayer)
    CGRect

    UIBezierPath
    この3つの合計で
    スコアが変動するよ
    タップして次へ
    self.present

    View Slide

  26. 複雑なコーチング (連続した動作制御)
    ステップ数少
    →UIView.animateまたは
    Promiseをチェーン
    ステップ数多
    →closureのスタックを用意
    stack.popで実行する

    View Slide

  27. 複雑なコーチング (カードフリック)
    • チュートリアル用のViewにカードを重ねる
    • DataSourceから上2枚分のカードをコピーしDI
    • カードUIはカスタムView実装
    • 動きも忠実で実際のデータなので使用感が出る
    DataSource
    CardView x2
    CardContainerView
    view.animate
    self.showPopTip
    上に重ねる アニメーション

    View Slide

  28. 本当はもっとこうしたい
    • VCの名称に一貫性がない(新人が覚えるの大変)
    • メンテ大変なので実装やステップを簡略化したい
    • 男女やプラットフォーム間の差をなくしたい
    • アニメーションを滑らかに (lottieの活用とか)
    • 現在CMPopTipViewはノーメンテ→EasyTipViewを推奨

    View Slide

  29. <29
    INDEX
    • 自己紹介
    • Poiboyについて
    • Poiboyのチュートリアルと実装解説
    1.男女で画面のViewController分けるか問題
    2.実装をライブラリでやるか自前でやるか問題
    3.デバッグどう/どこまでやるか問題

    View Slide

  30. テーマ3: デバッグどう/どこまでやるか問題

    View Slide

  31. チュートリアルのデバッグ⼤変問題
    • 初日体験は大切なので重点的にデバッグしたい
    • でも全ての動作/表示のチェックは大変
    • 特に登録条件(状態)が多いと大変
    • (Poiboyは男女 x 登録導線で4パターン)
    ⽅針: A.⾃動(UI/Unitテスト) VS B. ⼿動(Beta)

    View Slide

  32. Poiboyではこうしている!
    • XCUITestで登録完了までの一連スクショを自動撮影
    • Firebase AuthのSMS認証にデバッグアカウントを作成
    手動デバッグ中心だが作業負荷の軽減にチャレンジ中

    View Slide

  33. XCUITestでの起動から登録までのスクショ撮影
    XCUITestのスクショ自動撮影を利用
    • エンジニアが全ケースを網羅できず
    • QAまで表示崩れを把握不可
    これまで
    改善後
    XCUITestでの
    Facebookログイン
    • 正常系の表示確認を簡略化
    • 対象端末を絞り手動確認も継続

    View Slide

  34. Firebase Auth でSMS認証にデバッグ⽤
    FacebookやTwitter認証はログインが面倒
    • PoiboyではSMS認証に
    Firebase Authを使用
    • 任意の電話/PIN番号を
    登録可能
    • 最大10件まで登録可能
    • なので番号を専有して
    も大丈夫
    • 入力がかなり楽になる

    View Slide

  35. (おまけ) 電話番号の⾖知識
    実在しないけど入力が簡単な電話番号は?
    携帯電話番号の規格では
    “0X0-0000-XXXX”等の形式なら任意の番号で実在しない❗
    番号を追加する際はご注意を
    http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/number_shitei.html

    View Slide

  36. 本当はこうしたい
    • XCUITestが認証でコケる問題
    • 他の正常系でのスクショ撮影
    • XCUITestよりもFastlane?
    • レポートの定期的な書き出し
    • iOSSnapshotTestCaseで画像比較
    できたらなお良し
    性別選択で落ちた
    認証が問題だった

    View Slide

  37. まとめ: Poiboyではこうしてる!
    テーマ1: チュートリアルの画面分け
    なるべくVC単位で分離しバグを減らしている!
    テーマ2: チュートリアルの実装どうやるか
    自前実装メインで最適なUIを実装している!
    テーマ3: デバッグどう/どこまでやるか問題
    手動デバッグの負荷軽減にチャレンジ中!

    View Slide

  38. 参考資料
    Poiboy iOS
    https://itunes.apple.com/jp/app/poiboy-ポイボーイ/id1028982003
    導入画面を実装したよ @takattata
    https://speakerdeck.com/takattata/dao-ru-hua-mian-woshi-zhuang-sitayo
    総務省|電気通信番号の利用・指定|電気通信番号指定状況
    http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/
    number_shitei.html

    View Slide