Xcode11でストーリーボードなしで画面ロードする方法

# 概要
比較して学ぶRxSwift入門という本[^1]がKindle Unlimtedで読めるので読み進めているところです。
[^1]: https://www.amazon.co.jp/dp/4844398792/ この文中で「書籍」と呼ぶ場合はこれを指します。

とてもわかりやすく良い書籍なのですが、最新のXcode11ではつまづく点があるのでその解決方法を書きます。

この書籍のサンプルコードを実行するためには「開発を加速させる設定」なる設定が必要で、それはストーリーボードをプロジェクトから削除した上でxibファイルで作成した画面をアプリ起動時にロードする設定を指すのですが、書籍に書いてある通りに設定してもXcode11ではうまく動きません。[^2]

[^2]: シミュレータでのアプリ起動時に実行時エラーが発生する `Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'Main' in bundle NSBundle <略> (loaded)'`

この原因はどうやらXcode11から導入されたSceneDelegateが関係しているようで、これに関連するファイル・コード・設定を削除することで解決できます。

この、SceneDelegateに関連するファイル・コード・設定を削除する手順を含めた「開発を加速する設定」を以下に示します。

Xcode Version 11.5 (11E608c) で確認しています。

# 手順
おおまかな手順は以下の通りです。
1. Single View App のプロジェクトを作成する
2. `Main.storyboad` 、`SceneDelegate．swift` を削除する 
3. `Info.plist` を編集する
4. `AppDelegate.swift` を編集する
5. `ViewController.xib` を作成する

手順ごとに具体的に見ていきます。

## １.Single View Application のプロジェクトを作成する
1. XCodeを起動し、File>New>Projectをクリックすると出てくるダイアログで `Single View App` を選択し、`Next` をクリックします。
2. 次のダイアログでプロジェクト名などを設定します。この時、 `Language` は`Swift`、`User Interface` は `Storyboard`を選択しておきます。設定したら `Next`をクリックします。
3. ファイルの保存先を指定して `Create` をクリックします。[^3]

[^3]: 普通の手順ですが、書籍と違い、Xcode11では`User Interface` で SwiftUIが選択できてしまうので注意します。

## 2.Main.storyboad、SceneDelegate．swiftを削除する
普通の手順です。画面左端のProject Navigaterから`Main.storyboad` と、`SceneDelegate．swift` を削除します。(Move To Trashを選択します) [^4]
[^4]: `SceneDelegate．swift` も削除するところが書籍と異なります。
<img width="522" alt="スクリーンショット 2020-07-28 14.14.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66940/171fd507-e3d5-ab16-3325-5246102271f7.png">

## 3. Info.plistを編集する
画面左端のProject Navigaterから`Info.plist`を選択し、設定リストを表示します。
次に以下のエントリを選択し、マイナス記号をクリックして削除します。
- Application Scene Manifest [^5]
- Main storyboard file base name
[^5]: Xcode11から追加された項目のようです。書籍には登場しません。
<img width="870" alt="スクリーンショット 2020-07-28 14.19.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66940/e2fe7f71-fee9-8198-eab2-e5999cca93cc.png">

## 4. AppDelegate.swiftを編集する
画面左端のProject Navigaterから`AppDelegate.swift`を開き、コードを全て削除した後、以下の内容をコピー＆ペーストします。

```swift
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.main.bounds)
        let navigationController = UINavigationController(rootViewController: ViewController())
        self.window?.rootViewController = navigationController
        self.window?.makeKeyAndVisible()
        return true
    }
}
```
ちなみに、Xcode11では初期状態ではコードは以下のようになっていますが、ストーリーボードを使用しない場合、赤枠の部分のSceneDelegate関連のメソッドは不要となるため削除します。
<img width="828" alt="スクリーンショット 2020-07-28 14.35.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66940/0a6e91b7-6fc9-d1a4-748a-6ef0b190e9d5.png">

## 5. ViwController.xibを作成する
この手順は書籍と同じです。
画面左端のProject Navigaterを右クリックし、NewFile>ViewでViewを選択し、Nextをクリック、次の画面で ファイル名（Save As:）を `ViewController.xib`として Createをクリックします。
次にビューエディタの左側の`Placeholders>File's Owner`を選択し、Classを`ViewController`に変更します。
<img width="1123" alt="スクリーンショット 2020-07-28 14.49.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66940/374bbaf0-4501-4021-9e23-3f44dc88736f.png">
次にOutletsのviewとViewControllerのViewを接続します。
<img width="1123" alt="スクリーンショット 2020-07-28 14.54.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66940/4eb65300-991d-ebb9-2d22-1573cf88f7d2.png">

## 確認
Build＆Runしてシミュレータに以下の画面が出ればOKです。
<img width="485" alt="スクリーンショット 2020-07-28 15.08.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66940/f6d6ab22-8f5e-d23b-1461-71fbf8e80609.png">

念のため`ViewController.swift`の`ViewDidLoad()`にブレークポイントを設定して狙い通りの画面がロードされていることを確認するのも良い考えだと思います。
<img width="889" alt="スクリーンショット 2020-07-28 15.04.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66940/5bad8c48-fcc6-5277-76e5-8937525eeb5a.png">

## 画面がうまく出てこない場合
上記手順で `ViewController.swift`の中で定義されたクラス名や`ViewController.xib`のファイル名を任意のものに変更した場合、以下のような画面が出てうまくいかないかもしれません。
<img width="485" alt="スクリーンショット 2020-07-28 15.15.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66940/0df1f3a7-05ff-3ef4-2c95-0058247d4b6c.png">
*.xibのファイル名とそれに紐づくViewControlerのクラス名が一致しない場合に上記の現象が起こります。これらは一致させる必要があるようです。


以上