Swift 3 への移行時に気付いたこと

この記事では既存の iOS アプリを Swift 3 に移行した時に気付いた幾つかの知見について紹介します. 自分自身がまだ iOS 10・Swift 3 について理解が不十分な部分もありますが, 少しでも参考になれば幸いです.

移行作業の前に

Xcode 7.3.1 + iOS 9.3 SDK

移行作業を行う前に Xcode 7.3.1 と iOS 9.3 SDK できちんとアプリがビルドできるようにしておきましょう. ライブラリについてもきちんとアップデートしておくと, 後で修正する部分が少なくて済みます.

Xcode 8

iOS 10 SDK を用いた開発には, Xcode 8 が必要になります. まずは Xcode をアップデートするところから始めましょう.

Swift 2.3 or Swift 3

Xcode 8 + iOS 10 SDK の環境では Swift 2.3 と Swift 3 の2つのバージョンの Swift を利用することが出来ます. Swift 2.3 は Swift 2.2 からのマイナーアップデートで, Swift 2.2 から比較的低いコストで移行することができます. Swift 3 は Swift 2.2 から大きく改善されていますが, 移行にあたっては大きな変更が必要になります.

注意すべき点は Swift 2.3 は Swift 3 は一つのバイナリの中で混在させることはできないという点です. 後述するライブラリの対応状況を含め, Swift 2.3 にアップデートするのか, Swift 3 にアップデートするのかを考えましょう.

将来のことを考えるなら Swift 3 にアップデートするのがベストですが, 開発時間等の都合で一旦 Swift 2.3 にアップデートし, その後 Swift 3 へアップデートすることも可能です.

なお, この記事では基本的に Swift 3 への移行について紹介します.

ライブラリの選定

サードパーティのライブラリを利用しているのであれば, それらのライブラリが iOS 10・Swift 2.3 / 3 に対応しているかを事前に確認しておきましょう. メジャーなライブラリでは Swift 2.3 と Swift 3 のコードが別々のブランチでメンテナンスされているようですが, ライブラリによっては Swift 3 のみの対応となっているものもあり, 注意が必要です.

Deployment Target

対応する iOS のバージョンについても検討する必要があります. Xcode 8.0 と iOS 10 SDK では iOS 8.0 以降のバージョンを設定出来ます. また, サードパーティのライブラリを使用している場合は, そのライブラリが対応している deployment target についても意識する必要があります.

情報収集

iOS 10 や Swift 3 についての情報を事前に収集しておきましょう.

移行作業

この節では実際に iOS 10・Swift 3 に移行する際に行った作業や, 躓いた点を幾つか紹介します. Swift 3 での変更はあまりに多くあるため, 特に気になったところを幾つか紹介します.

Migration Assistant

Swift 2.2 から Swift 2.3 / 3 への移行には Xcode 8.0 の migration assistant を利用することが出来ます. これだけで完全に移行することは出来ませんが, まずは試してみる価値のある機能だと思います. 当然ですが移行の前後で VCS 等できちんとコミットしておき, 修正された箇所がわかるようにすることをおすすめします.

ライブラリのアップデート

ライブラリを iOS 10・Swift 3 対応の前にアップデートします. Migration assistant の実行前にライブラリをアップデートするのが良いか, 実行後にライブラリをアップデートするのが良いかはケースバイケースだと思うので, うまくいく方を試すのが良さそうです.

API 関係の変更

Swift 3 では API のデザインガイドラインが定められています. 標準ライブラリの API にも多くの変更が加えられているため対応が必要です.

また, Apple が提供する GCD などの API も多くの変更が加えられ, より Swift らしくなっています. これらについても対応が必須です. GCD での例:

DispatchQueue.main.async {
    // Code here
}

既存のコードの API も新しいガイドラインに沿ったものにするのが望ましいですが, これも変更に大きなコストがかかるので, 一旦 Swift 3 でアプリをビルドできるようになってから対応しても遅くないと思います.

参考

返り値を利用しない場合の警告

返り値を返す関数を呼び出しているにもかかわらず, その返り値を利用していない場合, Swift 3 のコンパイラは warning を吐きます. Swift 2 では @warn_unused_result をつけることで同様の warning を出すことが出来ました.

この warning を抑制するには, 返り値を _ に代入するか, 関数に @discardableResult をつけます. コードによってはこの warning が大量に出てしまうので, うまく抑制した方が他の警告に集中しやすくなります. 例:

func f(x: Int) -> Int {
    return x * 10
}
_ = f(10)

@discardableResult func g(x: Int) -> Int {
    return x * 10
}
g(10)

参考

Data から String への変換

プッシュ通知のトークンは NSData 型で与えられており, これを String 型に変換するには token.description のようにするのが一般的でした.

Swift 3 ではプッシュ通知のトークンは Data 型で与えられ, これを従来の方法で String 型に変換すると 32 bytes という文字列に変換され使い物になりません.

String(format: "%@", token as CVarArg) とすることで, うまく String 型に変換することが出来ます.

参考

CFBundleShortVersionString

これは Swift 3 とは直接関係ないのですが, Swift 3 に対応したライブラリがβ版として配布されている場合に CFBundleShortVersionString1.0.0-beta.1 のような値が設定されていることがあります. このような -beta などが使われたライブラリを含むアプリを iTunes Connect にアップロードしようとすると, エラーになりました. CFBundleShortVersionString1.0.0 のように修正してビルドすることで無事アップロードできました.

最後に

Swift 3 の対応については, Apple 公式の情報 (swift-evolution を含む) を参照するのが最も確実です. これらの情報は検索エンジンから辿りにくいこともあるので, より詳しく知りたい場合は自分から積極的にアクセスしてみましょう.

更新履歴

  • 2016/10/8 typo を修正