Swiftのバージョンアップ手順(Swift 4.2→5.0)

## はじめに

個人アプリでSwiftを4.2から5.0にバージョンアップし、そのときの手順をまとめました。

## Xcodeの更新

SwiftはXcodeのバージョンと紐付いているため、App StoreからXcodeをアップデートすることで、Swiftをバージョンアップします。
<img width="445" alt="スクリーンショット 2019-05-27 22.06.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/28279326-e17b-8ac6-7766-9db7bcef37fe.png">

## ライブラリの更新

ライブラリ管理ツールと、そのツールで管理しているライブラリを更新します。

エラーや警告が発生しない限り、更新しなくても問題ないことが多いですが、私はSwiftのバージョンアップと同時に更新しています。
ただ、Swiftの新バージョンのリリース直後はライブラリが対応していないこともあります。

私はCocoaPodsとCarthageを使っているので、その更新のみ紹介します。
この記事では省略していますが、必要に応じて「Podsfile」や「Cartfile」を書き換えたり、全ライブラリでなく必要なライブラリのみ更新したりしてください。

```bash
# CocoaPodsの更新
# 「/usr/local/bin」にインストールしている場合
$ sudo gem update -n /usr/local/bin cocoapods

# CocoaPodsで管理している全ライブラリの更新
$ pod update

# Carthageの更新
# Homebrewでインストールしている場合
$ brew upgrade carthage

# Carthageで管理している全ライブラリの更新
$ carthage update --platform iOS
```

## 警告の解消

Xcodeで発生している警告を解消します。
基本的には警告をダブルクリック→自動修正でOKです。

### プロジェクトファイルの更新

以下の警告は、プロジェクトファイルを更新することで解消します。

```
Swift Conversion
Conversion to Swift 5 is available
```

警告をダブルクリックします。
<img width="286" alt="スクリーンショット 2019-05-26 23.04.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/f39d9f3d-6f26-58c4-00cc-ceada8c0eab5.png">

全ターゲットのチェックがONになっていることを確認し、[Next]ボタンをクリックします。
<img width="736" alt="スクリーンショット_2019-05-26_23_05_16.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/99ed9476-439f-bfdf-816d-d9d6b5c6a902.jpeg">

[Update]ボタンをクリックします。
<img width="428" alt="スクリーンショット 2019-05-26 23.08.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/39af7e51-f376-7f63-c5ab-a01df3df1859.png">

これで修正が完了です。

自動修正の適用後、プロジェクトファイルは以下のように更新されます。(一部のみ抜粋)

```diff:project.pbxproj
…
- objectVersion = 50;
+ objectVersion = 51;
…
+ LastSwiftMigration = 1020;
…
- SWIFT_VERSION = 4.2;
+ SWIFT_VERSION = 5.0;
…
```

### スキーマの更新

以下の警告は、スキーマを更新することで解消します。

```
Validate Project Settings
Update to recommended settings
```

警告をダブルクリックします。
<img width="283" alt="スクリーンショット 2019-05-27 22.25.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/23da90b9-e7d7-ba0c-cf03-a9fc05ae9aa0.png">

自動修正の適用後、スキーマは以下のように更新されます。(一部のみ抜粋)

```diff:{プロジェクト名}.xcscheme
…
- LastUpgradeVersion = "1010"
+ LastUpgradeVersion = "1020"
…
```

### Migrate “English.lproj”

```
Migrate “English.lproj” (Deprecated)
Pods.xcodeproj
```

警告をダブルクリックします。
<img width="253" alt="スクリーンショット 2019-05-27 22.38.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/692c8325-1560-566b-8a20-20c0f14cb7c4.png">

[Perform Changes]ボタンをクリックします。
<img width="587" alt="スクリーンショット 2019-05-27 20.22.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/0ad7c252-4112-42d6-d41f-4184cad0d20c.png">

[Migrate]ボタンをクリックします。
<img width="426" alt="スクリーンショット 2019-05-27 20.25.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/dce6f887-ae97-f0d0-aaf2-4b73d57c914b.png">

これで修正が完了です。

自動修正の適用後、Git上では更新が確認できませんでした。
私がバージョン管理していないファイルが更新されたようです。

### Enable Base Internationalization

```
Enable Base Internationalization
Pods.xcodeproj
```

警告をダブルクリックします。
<img width="254" alt="スクリーンショット 2019-05-27 22.42.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/d2e1056e-f45a-9d73-9598-819d296dc2cb.png">

[Enable]ボタンをクリックします。
<img width="427" alt="スクリーンショット 2019-05-27 20.26.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/09f31e94-7b91-dfc5-7214-28381d6f0782.png">

これで修正が完了です。

自動修正の適用後、こちらもGit上では更新が確認できませんでした。

### ACL(アクセス制御レベル)の省略

親と同等のACLを明記しているメソッドは警告が表示されるようになったようです。

```
'public' modifier is redundant for instance method declared in a public extension
Replace 'public ' with ''
```

[Fix]ボタンをクリックして自動修正を適用します。
<img width="634" alt="スクリーンショット 2019-05-26 23.22.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/d7e6164c-a41d-370e-38b0-f12cf6102651.png">

```diff_swift
public extension UIViewController {
-   public func showAlert(title: String, message: String, actions: [UIAlertAction]) {
+   func showAlert(title: String, message: String, actions: [UIAlertAction]) {
}
```

メソッドから `public` が削除されました。

## おわりに

小規模の個人アプリなので、エラーや警告が少なく、自動修正のみで対応が完了しました。