めもあ

# Xcode9+Swift4への移行
Xcode, Swift初心者がMacOSとXcodeのバージョンアップを行い、
プロジェクトをSwift4へMigrationしたときのメモ。

# 環境
## 使用機器
>Macbook Air

## バージョン変更の内容
>MAC OSX 10.12.6 Sierra
Xcode 8.3.2
Swift 3

　　　↓

>MAC OSX 10.13 High Sierra
Xcode 9.0
Swift 4

# プロジェクトの移行
App StoreよりMAC OSX High SierraとXcode9をそれぞれインストールし、
Xcode上でFile->Openより、古いプロジェクトを開いてみる。

# 警告×2
まず、2つの警告が表示された。
#### recommended settings
1つ目はビルドの推奨設定を自動で行う、というもの。
>warning: Update to recommended settings

警告をクリックすると以下のような確認のポップアップが表示されるため、
（\<Project>はプロジェクト名）
![スクリーンショット 2017-10-09 12.55.10.png](https://qiita-image-store.s3.amazonaws.com/0/129820/8a189ce6-1c66-3cbf-96f5-2e55f748f7dd.png)
そのまま右下の「Perform Changes」を押すと自動的に変更が適用され警告が消えた。

## Swift Conversion
2つ目はプロジェクトをSwift4へ移行できる、というもの。
>Swift Conversion
Conversion to Swift 4 is available

![スクリーンショット 2017-10-09 12.57.50.png](https://qiita-image-store.s3.amazonaws.com/0/129820/801a59b8-f487-bed7-49c1-563b78b29625.png)
自動的にプロジェクトをSwift4対応のものへ移行してくれるらしい。
移行するターゲットを選択し「Next」をクリック。（\<Project>はプロジェクト名）
![スクリーンショット 2017-10-09 14.08.50.png](https://qiita-image-store.s3.amazonaws.com/0/129820/d83f4f5e-c536-d206-39d4-796e2458ae9c.png)

Swift4へ移行する際@objc inferenceに関して、
「Minimize Inference」か「Match Swift 3 Behavior」を選択する。
![スクリーンショット 2017-10-09 12.59.51.png](https://qiita-image-store.s3.amazonaws.com/0/129820/2d90b537-aea0-3b3f-40f0-134fa0d4fc0c.png)
もしくは、
![スクリーンショット 2017-10-09 13.00.05.png](https://qiita-image-store.s3.amazonaws.com/0/129820/4021a412-c634-243a-9fc8-cb37a064620f.png)

[Migrate to Swift 4 @objc inference](https://help.apple.com/xcode/mac/current/#/deve838b19a1?sub=devded6c2001 "Migrate to Swift 4 @objc inference")によると、
>「Minimize Inference」: static inferenceに基づきコード内の必要な場所にだけ@objc attributeを追加する。これを選択した場合、移行を完了するために[Completing a Swift 4 minimize inference migration](https://help.apple.com/xcode/mac/current/#/deve838b19a1?sub=devded6c2001 "Completing a Swift 4 minimize inference migration")に記述されている手順に従う必要がある。
「Match Swift 3 Behavior」: コンパイラにより暗黙的に推論された全てのコードに@objcを追加する。これを選択した場合、Swift3によって暗黙的に追加された全ての場所に明示的な@objcを追加するため、バイナリのサイズは変化しない。

正直意味がわからないので、デフォルトの「Minimize Inference」を選択。
上記の通り手作業による操作が必要みたいなことを言われる。
![スクリーンショット 2017-10-09 14.15.44.png](https://qiita-image-store.s3.amazonaws.com/0/129820/62ad31ce-e604-cbc4-2c3f-93858caa2878.png)
「View Migration Guide」で上記のマニュアルが表示される。

この時点でコンパイルエラーがあると、Migrationできないと怒られる。
![スクリーンショット 2017-10-09 14.17.11.png](https://qiita-image-store.s3.amazonaws.com/0/129820/0edc26dd-d339-e2f3-6dc3-8d3e35dfe80c.png)

うまくいくと左右に移行前のコードと自動的に移行された後のコードがそれぞれ表示され、
右下の「Save」を押すと新しいコードに書き換わる。

# @objc inferenceについて警告
つづいて以下の警告が表示された。
（この時点でビルド・実行可能になっているようなので無視しても問題なさそう？）
>The use of Swift 3 @objc inference in Swift 4 mode is deprecated. ...

![スクリーンショット 2017-10-09 17.04.12.png](https://qiita-image-store.s3.amazonaws.com/0/129820/21b342e6-f09d-2340-9d48-2e31c9c16e02.png)

[Completing a Swift 4 minimize inference migration](https://help.apple.com/xcode/mac/current/#/deve838b19a1?sub=devded6c2001 "Completing a Swift 4 minimize inference migration")に従う。

>1. プロジェクトをビルドする。
2. @objc attributeを追加する必要のある場所を示す警告を修正する。
3. コードをテストして、非推奨な暗黙的@objc参照を示す警告を修正する。警告がなくなるまでテストする。
4. プロジェクトのBuild settingsを開く。
5. 「Swift 3 @objc inference」をDefaultにセットする。

コードの必要な場所に@objcを入れる必要があるそうだが、どこに入れればいいのかが不明。
[Swift and Objective-C in the Same Project](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html "Swift and Objective-C in the Same Project")によると、
>###Importing Swift into Objective-C
...
Swift内でのPrivate宣言は@IBAction, @IBOutlet, @objcが明示的に示されていない限り、Objective-Cからは参照できません。
...

@objcはObjective-CのコードからSwiftを参照するために利用する模様。
Objective-Cを使う予定がなければ特に必要ないのか？

上記警告は「Swift 3 @objc inference」というビルド設定はSwift4では使えない、ということらしい。
そこで、警告が出ているTargetのビルド設定を変更する。
まず、Targetを選択する。左のファイル一覧よりプロジェクト名のところを選択して、

ここをクリックして出て来る
![スクリーンショット 2017-10-09 14.55.51.png](https://qiita-image-store.s3.amazonaws.com/0/129820/8465863a-f0ec-1f61-1c84-1f8cbaa46882.png)

これを
![スクリーンショット 2017-10-09 15.06.19.png](https://qiita-image-store.s3.amazonaws.com/0/129820/73b22d2f-f715-7d37-6fa7-746a3464ebd2.png)

これに変更。
![スクリーンショット 2017-10-09 14.54.23.png](https://qiita-image-store.s3.amazonaws.com/0/129820/3915aa4a-5435-04b2-9463-833d9de0b9d4.png)
（※*\<Project名>Tests.xctest*と*\<Project名>UITests.xctest*はテスト用のTargetらしい。）

「Build Setteings」を選択し、検索ボックスに「inference」と入力。
![スクリーンショット 2017-10-09 14.59.14.png](https://qiita-image-store.s3.amazonaws.com/0/129820/bb335412-c6c5-d09e-94bf-8f2513a1cac7.png)

「Swift 3 @objc Inference」がOnになっているため、Defaultに変更。

利用しているフレームワークについても同様に警告が出ているため同じことを行う。
上の場合Targetの選択の前に「ImageProcTest」ではなくフレームワークである「EasyImagy.xcodeproj」を選択して、同じ手順を踏む。
（Target一覧がOSX, iOS, tvOS, watchOSとなっていたのでOSXを選択）

これで警告が全部消えた。
Target選択のところが分かりにくかった。