この記事の要点
- Swift 6.3 がリリースされ、ソフトウェアスタックのあらゆる層で Swift を使いやすくする改善が入りました。柱は より柔軟な C 相互運用、クロスプラットフォームなビルドツールの改善、Embedded Swift の強化、そして 公式の Swift SDK for Android です。
- 言語面では、Swift の関数や
enumを C へ公開する@c属性、名前解決を明示する module selector(::)、ライブラリ作者向けに最適化を制御する新属性(@specialize/@inline(always)/@export(implementation))が加わりました。 - ツール面では Swift Package Manager に統合された Swift Build のプレビューが始まり、Swift Testing・DocC も機能拡張されました。
- 最大の節目は Swift SDK for Android の初の公式リリース で、Swift によるネイティブ Android 開発が現実的になりました。
主な変更点
言語と標準ライブラリ
C 相互運用: @c 属性
Swift 6.3 では、Swift の関数や enum を C のコードへ公開する @c 属性が導入されました。関数に @c を付けると、生成される C ヘッダ(compatibility header)に対応する宣言が含まれ、C / C++ のコードからそのまま呼び出せます。
@c
func callFromC() { ... }
// 生成される C ヘッダ
void callFromC(void);
C 側で使う名前を明示的に指定することもできます。
@c(MyLibrary_callFromC)
func callFromC() { ... }
さらに @c は @implementation と組み合わせられます。C ヘッダ側に宣言した関数の実装を Swift で書く、という使い方です。この場合 Swift はヘッダに新しい宣言を生成するのではなく、Swift の関数が既存の C 宣言と一致しているかを検証します。
// C ヘッダ
void callFromC(void);
// 実装は Swift で記述
@c @implementation
func callFromC() { ... }
module selector による名前解決の明示
同名の API を提供する複数のモジュールを import していると、どちらの API なのか曖昧になることがあります。Swift 6.3 では、どのモジュールの API を使うかを明示する module selector(モジュール名::名前)が導入されました。
import ModuleA
import ModuleB
let x = ModuleA::getValue() // ModuleA の getValue を呼ぶ
let y = ModuleB::getValue() // ModuleB の getValue を呼ぶ
Swift というモジュール名を使って、並行処理や文字列処理ライブラリの API を明示的に参照することもできます。
let task = Swift::Task {
// 非同期処理
}
ライブラリ API 向けの最適化コントロール
ライブラリ作者が、利用側に対するコンパイラ最適化をより細かく制御できる属性が追加されました。
- 関数の特殊化(
@specialize): ジェネリックな API について、よく使われる具体的な型向けにあらかじめ特殊化した実装を提供します。 - インライン化(
@inline(always)): 関数への直接呼び出しに対してインライン化(呼び出し箇所に関数本体を展開する最適化)を保証します。コードサイズの増加を上回る利点があると判断できる場合にのみ使います。 - 関数実装の可視性(
@export(implementation)): ABI が安定したライブラリの関数実装を利用側に公開し、より多くのコンパイラ最適化の対象にします。
パッケージとビルドの改善
Swift 6.3 には、Swift Package Manager に統合された Swift Build のプレビュー が含まれます。全対応プラットフォームで統一されたビルドエンジンを使えるようになり、クロスプラットフォーム開発の一貫性が高まります。自分のパッケージで試して、問題があれば報告することが推奨されています。
そのほかの Swift Package Manager の改善は次のとおりです。
- マクロ向け swift-syntax のプリビルド: マクロからのみ利用されるライブラリで swift-syntax のプリビルドバイナリを使えるようになり、共有マクロ実装を別ライブラリに切り出せます。
- 継承ドキュメントの制御: シンボルグラフを生成するコマンドプラグインで、継承されたドキュメントを含めるかどうかを制御できます。
- パッケージtrait の確認:
swift package show-traitsコマンドで、パッケージが対応する trait を確認できます。
コアライブラリ
Swift Testing
Swift Testing には次の改善が入りました。いずれも対応するProposalダイジェストがあります。
- 警告レベルの issue:
Issue.recordの新しいseverity引数で issue の深刻度を指定できます。Issue.record("Something suspicious happened", severity: .warning)のように記録すると、結果には反映されますがテストの失敗にはなりません(ST-0013)。 - テストのキャンセル:
try Test.cancel()で、開始済みのテスト(とそのタスク階層)をキャンセルできます。パラメータ化テストの一部の引数だけをスキップしたいときなどに便利です(ST-0016)。 - 画像の添付: Apple および Windows プラットフォームで、一般的な画像形式をテスト中に添付できます。UIKit など UI フレームワークとの cross-import overlay モジュール経由で提供されます(ST-0014 / ST-0015 / ST-0017)。
DocC
DocC には 3 つの実験的機能が追加されました。
- Markdown 出力: 通常のレンダリング用 JSON に加えて、ドキュメントページの Markdown 版を生成します(
docc convertに--enable-experimental-markdown-output)。 - ページごとの静的 HTML: 各ページのタイトル・説明・宣言などの軽量な HTML サマリを
index.html内の<noscript>タグに埋め込み、検索エンジンやスクリーンリーダーからの発見性を高めます。 - コードブロックの注釈:
nocopy(コピー無効化)、highlight(行のハイライト)、showLineNumbers(行番号表示)、wrap(折り返し)といった注釈を、開始フェンス行の言語名のあとにカンマ区切りで指定できます(--enable-experimental-code-block-annotations)。
プラットフォームと実行環境
Embedded Swift
Embedded Swift は、C 相互運用の強化やデバッグ支援の改善から、完全なリンクモデルに向けた前進まで、幅広く改善されました。詳細は元記事からリンクされている「Embedded Swift Improvements coming in Swift 6.3」を参照してください。
Android
Swift 6.3 には、Swift SDK for Android の初の公式リリース が含まれます。この SDK を使うと、Swift でネイティブの Android プログラムを開発したり、自分の Swift パッケージを Android 向けビルドに対応させたりできます。また Swift Java / Swift Java JNI Core を使って、Kotlin / Java で書かれた既存の Android アプリへ Swift コードを組み込むこともできます。長年の草の根のコミュニティ活動の上に Android Workgroup が積み重ねた成果であり、Swift のクロスプラットフォーム開発に新たな可能性を開く大きな節目です。
Swift 利用者への影響
- C / C++ との連携が書きやすくなります。 これまで Objective-C を介したり手作業でブリッジしたりしていた場面でも、
@cで Swift の関数・enumを直接 C へ公開できます。@implementationと組み合わせれば、C のインターフェイスに対する実装を Swift 側に置けます。 - 名前の衝突に悩まされにくくなります。 同名 API を提供する複数モジュールを併用する際、module selector で呼び先を明示でき、曖昧さによるコンパイルエラーを避けられます。
- ライブラリ作者は性能特性を設計できます。
@specialize/@inline(always)/@export(implementation)により、利用側に効く最適化を意図的に提供できます。いずれも効果と引き換えにコードサイズなどのコストがあるため、計測のうえで使うのが前提です。 - 新しいターゲットへ広がります。 Android SDK の公式化と Swift Build プレビューにより、1 つのコードベースをより多くのプラットフォームへ展開しやすくなります。Embedded Swift の改善も組み込み領域での採用を後押しします。