LINEヤフー Tech Blog

LINEヤフー株式会社のサービスを支える、技術・開発文化を発信しています。

LINE iOSアプリにおけるXcode 16対応への取り組み

はじめに

こんにちは、コミュニケーションアプリ「LINE」のiOSクライアントアプリ開発を担当している、モバイル・ディベロッパーエクスペリエンスチーム(以下MDX)所属のfreddiです。

この記事では、2024年にLINEアプリをXcode 16に対応させるために、チームとして取り組んだことを紹介します。まず、Xcode 16対応を集中的に行うための取り組みやWWDCでの活動について紹介します。そして、β版のXcodeを利用した際に遭遇した問題とどうやって克服したかについて、AppleへのFeedbackやGitHub Issue、オープンソースへの貢献の例をもとに書いています。これらの取り組みを通じて、AppleプラットフォームやSwift関連の開発コミュニティで問題を解決するために、どのような行動をしたかについても触れています。

WWDCとβ期間におけるチームとしての取り組み

毎年6月にWWDCが開催されると同時に最新版のXcodeのβ版がリリースされ、9月中旬に正式版がリリースされます。毎年、その時期にLINEアプリを試験的にビルドしますが、β版に同梱されているコンパイラやSDKにはバグが存在し、スムーズにビルドができないといった問題が発生しています。

LINEアプリの開発チームでは、この問題を解決するために多くの取り組みを行っています。たとえば、「Early Bird TF」と呼ばれる、β対応専用のタスクフォースの発足です。このTFでは、各エンジニアが知見や知識をフル活用して、AppleプラットフォームやSwift関連の開発コミュニティに問題を報告したり、既存のバグをPull Requestで修正し、問題解決を図っています。他にも、新しいOS機能の活用なども目的としています。この取り組みについては以下の記事をご覧ください。

特に、LINEアプリは数百のモジュールと200万行以上のコードから構成されており、複雑なビルドシステムを使用しているため、先程述べたバグによって、多くのモジュールやソースでさまざまな問題が発生するのは避けられません。MDXチームのメンバーには、これらの問題を的確に把握し適切に対処できるコンパイラやビルドシステムに特化したエンジニアが所属しており、TFの中で新しいXcodeバージョンへの適応やバグ修正を行っています。

このように、LINEアプリを最新の環境に適応し続けることで、開発者体験を向上させるのみならず、ユーザーに安定したサービスを提供できます。

WWDC24現地でのXcodeへの対応

毎年、新しいiOSやXcodeのβはWWDCで発表されます。β版での開発を高速に進めるため、LINEアプリの開発チームから、giginet(@giginet)、Ooka(@yutaooka)、freddi(@___freddi___)の3人が現地参加し、Keynote終了後に公開されたばかりのXcodeをインストールして、LINEアプリのビルドを行いました。

さらに今年のWWDC24から、数年間休止していた対面でのデベロッパーラボが再開されました。これにより、現地に行くことで、出たばかりのβ版について、Appleのエンジニアに直接相談できました。

discussion
ホワイトボードや手元のコードを見せながら、ディスカッションをしている様子

コードベースに変更を加えない状態では、SDKの変更や、後ほど説明するようなコンパイラの仕様変更とバグなどにより、たくさんのエラーが発生しました。そのため、修正には時間を要しましたが、最終的に初日のうちにLINEアプリのビルドを通すことに成功しました。それだけではなく、LINEのコードベースで発生した問題を、デベロッパーラボでAppleのコンパイラチームに速やかにフィードバックすることもできました。

ビルドが通り喜びはしゃぐ様子。ぜひLGTMなどにどうぞ

今年はWWDCに現地参加したエンジニアが多かったことや、デベロッパーラボでAppleのエンジニアに直接確認できたことが大きな助けとなりました。また、長年新しいXcodeへの対応をしてきた知見や経験が蓄積されていたこともあり、これまでにないほど迅速に、新しいXcodeへの対応を完了できました。

Swift 6の登場の影響

今年リリースされたXcode 16では、Swift 6へのメジャーアップデートがあり、Actor isolationまわりやtyped throwなどといった言語機能の追加や変更がありました。Swiftコンパイラは後方互換を意識して設計されており、かつメジャーアップデートのバージョンはオプトインなので、最新のXcodeでもSwift 5モードでビルドできるようになっています。

しかし、リリース当初のβ版では、その後方互換が壊れており、Swift 6の最新機能に関連する言語機能の問題によって、LINEアプリではさまざまなエラーやクラッシュが発生し、ビルドができなくなる問題が発生しました。

これらの問題を修正するためには、AppleやSwiftの開発チームへの報告が欠かせません。

問題を報告するためのTips

β版のXcodeの問題は、見つけたらすぐにFeedback Assistantや、GitHub上にあるそれぞれのレポジトリに報告することが大事です。これらを行うことで、AppleやSwiftコミュニティに認知され、素早い修正につながります。

また、添付する情報や書き方は、相手に伝わるように工夫することが非常に重要です。チームでは、以下の点を意識して書いています。

  • 最小限の再現コードを作成して添付する
    • いらないコードや依存を消す
  • 問題に関係ないコンテキストやドメイン知識を消す
    • ビジネス的なコンテキストをなくす
  • バージョン情報やどういった操作をしたか記述する
    • Xcodeのバージョン、SDKのバージョン、コンパイラのバージョンなど
  • エラーメッセージやスクリーンショットや動画を添付する
    • コンパイルエラー、クラッシュ、レイアウトやアニメーションの乱れ

総じて、なるべく担当者が修正しやすくなるような工夫をすることが肝要です。また、このような最小コードがあることで、のちのバージョンで正しく問題が修正されたことも確認しやすくなります。

実際におきた問題と対処例

実際にβ版のXcodeに対応する際に遭遇した問題や、先程書いた対処法を実践した例について紹介します。

Swiftコンパイラのパーサーのバグ

例として、Xcode 16 Beta 4では、次のようなコードがコンパイルできなくなっていました。

import Foundation

struct Object {
    init() throws {}
}

infix operator | : RangeFormationPrecedence
func | (lhs: Object, rhs: Object) throws -> Object {
    fatalError()
}

var closure: (() -> Void) = { () -> Void in
    var a: Object?
    a = try! Object() | Object()
}

Beta 4に同梱されたSwiftコンパイラを利用すると、以下の誤ったコンパイルエラーが発生してしまいます。

var closure: (() -> Void) = { () -> Void in
     var a: Object?
     a = try! Object() | Object()
                         `- error: thrown expression type 'any Error' cannot be converted to error type 'Never'

こちらはSwift 6から入ったtyped throwという機能の変更によって、既存のthrowと演算子を組み合わせたコードのパースや型推論が壊れることが原因だと推測しました。

この問題は、チームメンバーのJung(@asahiJung)さんが以下のようなFeedbackを送信しました。ここでは、問題が再現する最小限のコードやXcodeのバージョン、そしてエラーメッセージをしっかりと添付しています。

実際にAppleへ送信したFeedback

まだこの問題は調査中ですが、SwiftFiddleなどを利用すれば、準備した最小限のコードを使ってnightlyで修正されたかを定期的に確認できます。

Swift FoundationにおけるURLComponentsのブリッジングのバグ

こちらは、Xcodeに同梱してあるフレームワークの問題です。リグレッションテストを行った際、iOS 18でLINEアプリにおけるURLが関連する機能がうまく動作しないことで発覚しました。次のコードにおいて、URLComponentsNSURLComponentsにキャストする際に、%のエンコードがうまく処理されないという問題が発生しました。

let nsURLComponents = NSURLComponents(
    string: "https://example.com?url=https%3A%2F%2Fapple.com"
)!
let urlComponents = nsURLComponents as URLComponents
// iOS 18だとfalse、それ以前のバージョンではtrueになる
#expect(urlComponents.string == nsURLComponents.string)

URLの機能はSwiftのFoundationというFrameworkが提供しています。また、AppleはこのFoundation Frameworkの実装を段階的にオープンソース版のswift-foundation に切り替えています。そこで、私たちはまず、このオープンソースのFoundationに問題がないかを探してみました。コードベースを検索すると、NSURLComponentsURLComponentsのブリッジングの処理があり、その処理の中でエンコードのプロパティの処理があることを発見しました。

このバグについても、giginetさんがIssueとして報告しました。その後すぐにSwiftチームから返答があり、翌日にはパッチが当てられていました

サードパーティツールの問題と積極的な貢献

他にも、オープンソースになっているサードパーティツールの問題も多く発生していました。毎年、サードパーティツールもXcodeやSwiftのアップデートにかなり影響を受けるので、対応が必要になります。

たとえば、XcodeGenというプロジェクト生成に利用しているツールでは、Swift 6との互換性やSwiftの後方互換性に関して、https://github.com/yonaskolb/XcodeGen/issues/1462https://github.com/yonaskolb/XcodeGen/issues/1483 といった問題が報告されていました。

これらの問題はgiginetさんが迅速に解決しました。

また、fastlaneというデプロイの際に利用しているツールにおいても問題がありました。Xcode 16からビルドコマンドの仕様が変更されたことによる問題により、ログを出力するオプションを指定できなくなる不具合が生じていました。これらも、giginetさんがCore Committerとしてレビューを積極的に行ったこともあり、すぐに解決しました。

オープンソースのメリットとしては、このようにPull Requestを通じた修正がすぐにできることです。なにか問題が発生したら、とりあえず修正できないかを考えてみることがおすすめです。また、これらの問題は、LINEアプリだけでなく開発コミュニティすべてに影響するものです。オープンソースへの積極的な貢献が、社内だけでなくコミュニティへの大きな貢献になります。

まとめ:問題の報告や、貢献がXcode対応の大きなカギ

MDXチームやEarlyBird TFでは、毎年このようにβ版のXcodeへの対応をすぐに行い、問題の報告、オープンソースへのPull Requestなどといったプラットフォームへの貢献を行っています。こうした取り組みは、単に自社のプロジェクトを改善するだけでなく、Appleプラットフォームやさまざまな開発コミュニティ全体にとっても大きなプラスとなります。みなさんが貢献にチャレンジする際に、この記事が助けになると嬉しいです。