Swift 3から4へ変更してみた

samekard編

Xcode 8.3.3 & Swift 3で作られたプロジェクトをXcode 9 & Swift 4へ変更する作業のレポートです。

Xcode 9でプロジェクトを開く

警告が2つ発生。警告というかおすすめというか。

  • Swift ConversionのConversion to Swift 4 is available
    3から4へソース変更のおすすめ
  • Validate Project SettingsのUpdate to recommended setting
    プロジェクト設定変更のおすすめ

Update to recommended setting

では実行してみます。まずは簡単に終わりそうなUpdate to recommended settingから。ビルド設定にあるワーニング発生の条件が増えるようです。

押すだけでした。チェックボックスが2つありますが連動しているので実質1つです。変更の中身に興味がある人は項目のリストを見て下さい。

Conversion to Swift 4 is available

続いてSwift4にソースを変更する方をクリックします。こんな画面が出てきます。

Nextを押すとこうなります。

初めての難関です。

  • Minimize Inference (recommended)
  • Match Swift 3 Behavior

の2つの選択肢があります。

これは@objcの付け方の選択です。この@objcを付ける作業ですがSwift 3までは暗黙に行われていたそうです。

  • Minimize Inferenceの方は必要なところのみ@objcを付けます。これを選択するとマニュアル操作が必要になります。こっちの方がバイナリサイズが少ないそうです。
  • Match Swift 3 Behaviorの方はSwift 3で暗黙に行われていたのと同じ箇所に@objcを付けます。やってみたらUIViewのサブクラスは全てのインスタンスに@objcが付きます。

Minimize Inferenceの方にrecommended(おすすめ)が付いています。じゃぁおすすめの方で。

Minimize Inferenceを選択すると

このようにマニュアル作業が必要なことが警告されます。View Migration Guideを押すと移行に関する英語の資料が表示されます。この警告を消すだけならOKを選択、警告を消して資料を表示するならView Migration Guideを選択します。一括変更しようとしますが、漏れがあることが多いですよ、という警告かと推測します。

解析が終わると変更箇所のリストが出てきます。リストされているのはSwift3からSwift4への変更なので@objc以外の項目も出てきます。

この変更箇所のリストの作成は成功したり失敗したり、成功して変換しても、その後にわらわらと追加の変更箇所が出てきたので、ここから先のスクリーンショットなどは、失敗したときに行うような個別に手動で変更をすることをベースにして紹介します。

私のプロジェクトで発生した具体的な変更箇所の紹介です。

属性@objc関連

#selectorのところです。そのメソッドを見に行くと@objcが付いていませんでした。付けたら警告が消えました。

Fixボタンがあるときはそのボタンで@objcが付けられます。たくさんあったのでひたすらFixしました。信用できない場合は@objcが付くか確認しながらもよいでしょう。

気づいた点は、Fixしてから警告が消えるまで少し時間がかかるので、手当たりしだいFixすると一箇所に2つ@objcを入れてしまうことがある点と、親クラスのメソッドを指してるときはFixボタンが出ない点でした。

NSAttributedString

NSAttributedStringの仕様が変わったところです。

旧:NSFontAttributeName
新:NSAttributedStringKey.font

旧:NSParagraphStyleAttributeName
新:NSAttributedStringKey.paragraphStyle

旧:NSForegroundColorAttributeName
新:NSAttributedStringKey.foregroundColor

それぞれStringからNSAttributedStringKeyになりました。

私の場合、下のように変えます。

//Swift 3
let showAnswerAttributes: [String : AnyObject] = [
NSFontAttributeName: mainButtonFont,
NSParagraphStyleAttributeName: paragraph,
NSForegroundColorAttributeName: FSColor.showAnswer
]
//Swift 4
let showAnswerAttributes: [NSAttributedStringKey : AnyObject] = [
.font: mainButtonFont,
.paragraphStyle: paragraph,
.foregroundColor: FSColor.showAnswer
]

ただ、Swift 3の状態から一括変換(または個別で行うFix変換)すると、辞書の型の[String : AnyObject]につられてNSAttributedStringKey.font.rawValueになってしまいます。rawValueがStringなのでこれが候補に出てくる現象です。ここはrawValueなしがいいですね。なので先に辞書の型を[NSAttributedStringKey : AnyObject]にするとうまく変換できました。

次の2つの画像は、上が間違って誘導されているところ、下が正しく誘導されているところです。

M_PIが惜しまれつつ引退

円周率のM_PIはdeprecatedになりました(deprecatedになったのは正確には3.0のとき)。 Double.pi をお使いください。

最後に残った黄色警告

最後にこれが残りました。

Dependency Analysis Warning
The use of Swift 3 objc inference in Swift 4 mode is deprecated. Please address deprecated objc inference warnings, test your code with “Use of deprecated Swift 3 objc inference” logging enabled, and then disable inference by changing the “Swift 3 objc inference” build setting to “Default” for the “****” target.

Swift 3 InferenceをDefaultにするように書いてあります。言われた通りにビルドセッティングのSwift3@objcInterfaceをdefaultに変更します。

Swift 3で検索し、OnをDefaultに変更します

Defaultに変更すると警告が消えます。

このSwift3@objcInterfaceは、自動変換の際にMinimize Inference(必要なところのみ@objcを付ける)を選択してソース変換すると、Onになるようです。最後にDefaultにすることを要求されているので、つまりOnの状態でソース変更作業を行い、終わったらDefaultに切り替えます。

変更が必要なところは、Swift4の解釈だと赤のエラーになりますが、Swift3の解釈だと黄色の警告になります。変更作業時はSwift3の解釈で黄色に塗られているので精神的な負担を軽減(?)しながら作業を行えるメリットがあります。

Migration Guide

実行時に警告が出る場合もあるようで、その原因が、マニュアル作業警告のところで出てきたView Migration Guideに書いてありました。

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.