はじめに
こんにちは、コミュニケーションアプリ「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のエンジニアに直接相談できました。
コードベースに変更を加えない状態では、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のバージョン、そしてエラーメッセージをしっかりと添付しています。
まだこの問題は調査中ですが、SwiftFiddleなどを利用すれば、準備した最小限のコードを使ってnightlyで修正されたかを定期的に確認できます。
Swift FoundationにおけるURLComponents
のブリッジングのバグ
こちらは、Xcodeに同梱してあるフレームワークの問題です。リグレッションテストを行った際、iOS 18でLINEアプリにおけるURLが関連する機能がうまく動作しないことで発覚しました。次のコードにおいて、URLComponents
をNSURLComponents
にキャストする際に、%
のエンコードがうまく処理されないという問題が発生しました。
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に問題がないかを探してみました。コードベースを検索すると、NSURLComponents
とURLComponents
のブリッジングの処理があり、その処理の中でエンコードのプロパティの処理があることを発見しました。
このバグについても、giginetさんがIssueとして報告しました。その後すぐにSwiftチームから返答があり、翌日にはパッチが当てられていました。
サードパーティツールの問題と積極的な貢献
他にも、オープンソースになっているサードパーティツールの問題も多く発生していました。毎年、サードパーティツールもXcodeやSwiftのアップデートにかなり影響を受けるので、対応が必要になります 。
たとえば、XcodeGenというプロジェクト生成に利用しているツールでは、Swift 6との互換性やSwiftの後方互換性に関して、https://github.com/yonaskolb/XcodeGen/issues/1462 や https://github.com/yonaskolb/XcodeGen/issues/1483 といった問題が報告されていました。
これらの問題はgiginetさんが迅速に解決しました。
また、fastlaneというデプロイの際に利用しているツールにおいても問題がありました。Xcode 16からビルドコマンドの仕様が変更されたことによる問題により、ログを出力するオプションを指定できなくなる不具合が生じていました。これらも、giginetさんがCore Committerとしてレビューを積極的に行ったこともあり、すぐに解決しました。
- https://github.com/fastlane/fastlane/pull/22157
- https://github.com/fastlane-community/xcresult/pull/6
オープンソースのメリットとしては、このようにPull Requestを通じた修正がすぐにできることです。なにか問題が発生したら、とりあえず修正できないかを考えてみることがおすすめです。また、これらの問題は、LINEアプリだけでなく開発コミュニティすべてに影響するものです。オープンソースへの積極的な貢献が、社内だけでなくコミュニティへの大きな貢献になります。