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に変更します。
Defaultに変更すると警告が消えます。
このSwift3@objcInterfaceは、自動変換の際にMinimize Inference(必要なところのみ@objcを付ける)を選択してソース変換すると、Onになるようです。最後にDefaultにすることを要求されているので、つまりOnの状態でソース変更作業を行い、終わったらDefaultに切り替えます。
変更が必要なところは、Swift4の解釈だと赤のエラーになりますが、Swift3の解釈だと黄色の警告になります。変更作業時はSwift3の解釈で黄色に塗られているので精神的な負担を軽減(?)しながら作業を行えるメリットがあります。
Migration Guide
実行時に警告が出る場合もあるようで、その原因が、マニュアル作業警告のところで出てきたView Migration Guideに書いてありました。