💪

2周年を迎えるNEWT-iOSが、1年で取り組んだチャレンジと変化

2024/05/16に公開

top.png

こんにちは!令和トラベル iOS テックリードの高橋です。

この記事は、NEWT 2nd ANNIVERSARY CALENDAR DAY7として、書かせていただきます。

今回は、この1年でNEWT-iOSがどんな取り組みをおこなってきたかを振り返り、どのように成長してきたかをお伝えできればと思います。昨年にこちらの記事も執筆しているのであわせてご覧ください!

自己紹介

学生時代からiOSアプリ開発を勉強し始めて9年が経ち、前職に新卒でiOSエンジニアとして入社。今年で6年目に突入しました。令和トラベルには中途入社して1年半、PP期間を含めると約3年になります。趣味は野球観戦と麻雀で社内の野球好きの方と野球観戦に行ったりもします ⚾

※ 令和トラベルでは業務委託の方をプロパートナー(PP)と呼んでいます

はじめに

海外旅行予約アプリ『NEWT(ニュート)』はこのたび2周年を迎えました🎉

この1年でさまざまな機能追加を行い、カスタマーのみなさまがさらに「かんたん・おトク」に海外旅行の予約ができるようになったのではないかと感じています。まだNEWTを触ったことがない方は、ぜひインストールしてみてください🙌

NEWT(ニュート)| スマホ1つでかんたんに海外旅行を予約できるアプリ

feature1.png

アプリのレビュー件数も1,000件を超え、さまざまなお声をいただいています!

ぜひ触ってみて、予約してみて、率直な感想をお聞かせください!いただいたご意見は、NEWTチームが目を通して日々の改善に繋げています 💪

feature2.png

そんなNEWTのiOSチームについて、今回はお話ししたいと思います。

チーム体制

昨年のブログで書いたチーム体制の変化は以下でした。

  • FT: 1名 → 2名(+Web兼務1名)
  • PP: 3名 → 1名(+ Android兼務1名)

そして、iOSチームの体制は2024/4/1時点で以下のように変化しました。

  • FT: 2名(+Web兼務1名)→ 2名 / EM1名(+1名)
  • PP: 1名 (+Android兼務1名)→ 1名 (-1名)

昨年はEMやWeb兼務のメンバーもいたので、iOSチームの出力は実質1.5人分くらいになっていました。フルタイムの工数は主に僕が担っていましたが、なんとこの4月から新たに1名がiOSエンジニアとして入社してくださいました!

2名体制になることでアウトプットの最大化と品質のさらなる向上を目指していきたいと思います。

登壇やブログ活動

昨年から、社内で Tech LT会 を開始しました。開始から1年経っていないにも関わらず、社外の方にも参加していただけるようになったり、外部イベントの主催などをさせていただき、令和トラベルとしての社外発信が大きく飛躍したと思っています。

会社としての発信も大切にしている中で、チームとして特に大きかったのは iOSDCでの登壇 だったのではないかと思っています。令和トラベル・iOSチームがまだそこまで大きくない中で、2名が採択され、登壇することができました。おそらく、ほとんどの方が「令和トラベル?」「NEWTってなんだ?」というお気持ちだったと思うのですが、弊社を知ってもらうきっかけにもなったと思っています。

iosdc.png

もちろん「アウトプットが苦手…」「時間がなかなか取れない…」という方もいらっしゃると思うので、DIBの観点から強制はしない前提で、iOSチームとしては**「積極的に発信していこう**」という文化づくりを始めました(とはいえほぼ僕が1人で言っているだけだったのですが…笑)。

まずは自分がやっていき💪という気概でいることが大事だなと思っています。

技術的な取り組み

TCA ~ ComposableAction ~

昨年の記事では、NEWTがswift-composable-architectureを利用していることについて触れました。

TCAもv1.0.0をリリースすると共に、現時点ではv1.9.2がリリースされ変化しています。

NEWTでは、TCAのActionを明確に分離するために以下のようなComposableActionを定義し、原則としてTCAのActionに準拠させるようにしました。

public protocol ComposableAction: Equatable {
  associatedtype ViewAction: Equatable
  associatedtype ReducerAction: Equatable
  associatedtype DelegateAction: Equatable

  static func view(_ action: ViewAction) -> Self
  static func reducer(_ action: ReducerAction) -> Self
  static func delegate(_ action: DelegateAction) -> Self
}

enum Action: ComposableAction {
  // - Required Actions
  enum ViewAction: Equtable { ... }
  enum ReducerAction: Equatable { ... }
  enum DelegateAction: Equatable { ... }

  case view(ViewAction)
  case reducer(ReducerAction)
  case delegate(DelegateAction)

  // - Feature Actions
  case otherFeature(OtherFeature.Action)
}
  • ViewAction … ViewからsendされるAction
  • ReducerAction … Reducer内で扱われるAction
  • DelegateAction … 他のFeatureへコールバックするAction

このようにスコープを分けることで、Action自体の整理やパフォーマンス観点で不必要なActionをsharedEffectに変更したり、リファクタリングを少しずつ進めることができています。より視覚的になったことで、レビューもかなりしやすくなったと考えています。

TCA ~ invoke reducer directly ~

pointfreeが示すTCAのドキュメントにPerformanceというセクションがあり、Childのシェアロジックを呼ぶ場合に、sendではなくreducerを直接呼び出す方が良いとの記載があります。sendは非常にコストが高い処理なので避けるべきであるからです。

Child Featureは配列の場合があるので以下のExtensionを追加し、呼び出し時の冗長さを軽減しています。

public extension Reducer where State: Identifiable {
  func reduce(
    into arrayState: inout IdentifiedArrayOf<State>,
    id: State.ID,
    action: Action
  ) -> Effect<Action> {
    if var state = arrayState[id: id] {
      let effect = reduce(into: &state, action: action)
      arrayState[id: id] = state
      return effect
    }
    return .none
  }
}

// Child()
//   .reduce(
//     into: &state.childArray,
//     id: child.id,
//     action: .reducer(.invokeMethod)
//    )
//    .map { Action.child(id: child.id, action: $0) }

XcodeCloud

弊社では、ネイティブアプリのCIとしてUIが直感的で扱いやすいことやネイティブアプリ用のflowが多く、CIが組みやすいなどの理由でBitriseを利用していましたが、Bitriseのプラン変更(Credit消費制 + 超過課金)などでコストが爆増しました。そしてXcodeCloudと比較しながら試算した内容が以下になります。

現状

  • iOS/Android 1名ずつ
    $450 * 12 = $5400/year → 12821 credit + 従量課金
  • Appチームの人数が増えたら
    $652.5 * 12 = $7830/year → 18590credit
    もしくは
    $832.5 * 12 = $9990/year → 23718 credit

想定

  • iOS: XcodeCloud 「$1199.88/year($99.99/month) → 250h」
  • Android: Bitrise「 $2970/year → 7051credit 」 or 「$4320/year → 10256credit」

合計 $5519.88(Max)
※ 現状の実績からiOSの人数が増えても250hである程度耐えうる

現状の利用状況とコストを考えると、iOSがXcodeCloudに移行することでチームがスケールした時に、プラン変更をしなければならない状況を避けることができると想定しています。

また、弊社では開発初期からSwiftPackageManagerにパッケージ管理を寄せていたことから、XcodeCloudとの相性も良かったのはメリットでした。

移行作業は現在も絶賛作業中なので、今後XcodeCloudに変えて良かったことやデメリットなども発信していけたらなと考えています!

おわりに

いかがでしたでしょうか。

1年を通じて機能拡充とともに、技術的な改善は昨年度よりもジワジワと増えてきていると思っています。さらに技術的な改善をするだけでなく、社内外へのアウトプットもしていこうというフェーズに変わった1年でした。

さまざまな開発を行うなかですが、一番優先されるのが「カスタマーファースト」であることを忘れずに、今年度もさらに飛躍する1年にしたいと思います!

令和トラベル Tech Blog

Discussion