Xcode10.2への適応で発生したエラー


Xcode10.2になり、Xcodeのアップデートをかけると大きなエラーが発生する。
もともと、Swift3で対応していたので、大幅なジャンプが必要になった。

まずはXcode10.1を平行して使用し、10.1でSwift4.2にアプリ自体をアップデートした。
方法はConvertしただけ。
さらに、使用しているライブラリーを全てアップデートした。

- Action 3.2.0 -> 3.2.0 (latest version 3.11.0)
- APIKit 3.2.1 -> 3.2.1 (latest version 4.0.0)
- Cache 2.2.2 -> 2.2.2 (latest version 5.2.0)
- CryptoSwift 0.12.0 -> 0.12.0 (latest version 1.0.0)
- Differentiator 2.0.2 -> 2.0.2 (latest version 3.1.0)
- Google-Mobile-Ads-SDK 7.38.0 -> 7.38.0 (latest version 7.42.1)
- KeyboardObserver 2.0.0 -> 2.0.0 (latest version 2.1.0)
- Nimble 7.3.1 -> 8.0.1 (latest version 8.0.1)
- NVActivityIndicatorView 4.4.0 -> 4.6.1 (latest version 4.6.1)
- Quick 1.3.2 -> 2.0.0 (latest version 2.0.0)
- ReachabilitySwift 4.3.0 -> 4.3.1 (latest version 4.3.1)
- Result 3.2.4 -> 3.2.4 (latest version 4.1.0)
- RxCocoa 3.6.1 -> 3.6.1 (latest version 4.4.2)
- RxDataSources 2.0.2 -> 2.0.2 (latest version 3.1.0)
- RxOptional 3.2.0 -> 3.2.0 (latest version 3.6.2)
- RxSwift 3.6.1 -> 3.6.1 (latest version 4.4.2)
- RxTest 3.6.1 -> 3.6.1 (latest version 4.4.2)
- SnapKit 3.2.0 -> 3.2.0 (latest version 4.2.0)
- SwiftLint 0.27.0 -> 0.31.0 (latest version 0.31.0)
- SwiftyJSON 3.1.4 -> 3.1.4 (latest version 4.2.0)
- SwiftyStoreKit 0.13.1 -> 0.13.1 (latest version 0.14.2)
- Willow 3.0.0 -> 3.0.0 (latest version 5.1.0)

げんなりするくらいのライブラリーの多さだが仕方がない。


##ビルドの方法によってエラーの種類が違う
エラー出現には２種類のパターンがあることがわかった
ビルド方法の変更は、下記のターゲットに表示される Edit Scheme で変更できる。
![Kobito.FmUBnJ.png](https://qiita-image-store.s3.amazonaws.com/0/23659/5695f0ea-282f-ded3-529d-6221e4721dbb.png "Kobito.FmUBnJ.png")

表示されたウィンドウの Build Configuration と Debug executable を変更すると、エラー内容が変わる。
このビルド設定はiphoneをつないだ状態でビルドするときに変更していた。対処療法的で理由を明確にしていないのでなんとも根拠にかける。
![Kobito.h2teTZ.png](https://qiita-image-store.s3.amazonaws.com/0/23659/b5571741-2a4a-ff45-db3a-9dc1426312ad.png "Kobito.h2teTZ.png")

この部分を解説している記事を見つけた。
https://qiita.com/uasi/items/79aecac40f1b2a5f929b

つまり、状況に応じてビルドの設定を変更できるってことらしい。
となると、前任がビルド設定を出し分けていたのかもしれない。

### Build Settingの確認
Debug と Relese で違っているのは。Search Path の Framework Search Path と User_Defined が違っている。
そして、Frameworkの方がAPIKitに向いている。
これで
https://stackoverflow.com/questions/55351736/xcode-10-2-swift-5-command-compileswift-failed-while-build-the-program-with-re


##Build Configuration が Release で Debug executable のチェックを外した場合
この設定は Archive にする場合に使用していた。
この場合、エラー数は5つでエラーの種類は２種類
どれもライブラリーに対してのエラーである。

### Command CompileSwift failed with a nonzero exit code
エラーが出現しているライブラリーは次の通り
- APIKit
- RxSwift
- Cache
- CyptoSwift

※ Debug executable のチェックを入れた状態だとAPIKitのエラーが消える

このエラーはビルドするたびに表示されるライブラリーが増減する。
基本的には上記のライブラリーに表示されるが、、、、
よくよく考えると、このタイミングでライブラリーの修正を個人で行うのは得策ではない。
各ライブラリーが10.2に適応されるのを待つ方が良いかもしれない。

### Illegal instruction: 4
- Cache

## Build Configuration が Debug で Debug executable のチェックを入れた場合
この場合は、iphone とつなげて、実機で検証する場合に使用しているビルドモード
エラーの数は19箇所で、種類は４種類
どれもアプリ自体に発生している。

### Missing argument for parameter 'configureCell' in call
これは、「RxTableViewSectionedReloadDataSource」のイニシャライズ方法に不備があるようだ。「configureCell」の記述がないことが原因
記述の問題で、こちらの方法を設定しなくてはいけないのかもしれない。
[RxDataSourcesライブラリ＋UITableViewを使ってMVVMサンプルiOSアプリを作る](https://qiita.com/k0uhashi/items/d4a6bdcd6fca014a37dd)

この方法だと、Modelを作成しなくてはいけない。
問題はすでにあるHomeViewModelとマージさせる必要があるのかもしれない。

こちらの質問も同じようなことを言っている。
しかし、すでに2017年の話だから、最新バージョンではある程度直っている思うが。
https://github.com/RxSwiftCommunity/RxDataSources/issues/175

こちらが今回エラーが起きている箇所

```HomeViewController.swift

fileprivate let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Book>>()

```

この括弧内に「configureCell」を設定しなくてはいけない。
しかし、なんで、ビルドモードを変更するとこのエラーが消えるのか。

こちらのページの「[★4-2. 各々のファイルの役割と処理のポイントに関して](https://qiita.com/fumiyasac@github/items/90d1ebaa0cd8c4558d96#4-2-%E5%90%84%E3%80%85%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%BD%B9%E5%89%B2%E3%81%A8%E5%87%A6%E7%90%86%E3%81%AE%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AB%E9%96%A2%E3%81%97%E3%81%A6)」に記載されている状態と同じ状態だがエラーが発生している。

この記事の下に追記されているように記述の順番を変えれば良いんだ。
configureCell の記述を「RxTableViewSectionedReloadDataSource」内に

```HomeViewController.swift

//データソースの定義
        configureCell: { (_, tableView, indexPath, item) in
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SoundListTableViewCell // swiftlint:disable:this force_cast
            cell.configure(with: item)
            return cell
            }
```

こちらのエラーはこれで解決した。

### Use of unresolved identifier 'HybridCache'
こちらはキャッシュ関連。
これが一番厄介だ。

HybridCache自体すでに4.0バージョンで使われていない関数らしい。
[HybridCache no longer accessible?](https://github.com/hyperoslo/Cache/issues/150)

[4.0.0](https://github.com/hyperoslo/Cache/releases/tag/4.0.0)
>HybridCache was removed. Storage can be configured with DiskConfig and MemoryConfig. If you don't specify MemoryConfig, then only disk cache is used.

これを読むと、Storageを使えって読み取れる。「DiskConfig」と「MemoryConfig」を使う必要がある。

この内容をそのまま今のところに記述し直す。

```CacheService.swift
    fileprivate let cache = try? Storage(
        diskConfig: DiskConfig(name: "ReadGirl.JSONCache"),
        memoryConfig: MemoryConfig(expiry: .never, countLimit: 10, totalCostLimit: 10),
        transformer: TransformerFactory.forCodable(ofType: Data.self)
    )
```
4.0のバージョンの場合、「DiskConfig」と「MemoryConfig」だけで良かったのかもしれないが、5.2.0の場合「transformer」も設定しないといけないぽい。
これでなんとか「Use of unresolved identifier 'HybridCache'」のエラーは解消することができた。

しかし、このことで別のところ2箇所にエラーが発生する

```CacheService.swift
    func set(_ object: SwiftyJSON.JSON, for key: String) {
        guard let data = try? object.rawData() else { return }
        cache.add(key, object: data)
    }
```
この`cache.add`の部分で、addはメンバーじゃないよってエラーがでる。
Storageにaddがなくなったらしい。

なので、この部分を`setObject`に変更する。

```CacheService.swift
    func set(_ object: SwiftyJSON.JSON, for key: String) {
        guard let data = try? object.rawData() else { return }
        cache?.async.setObject(data, forKey: key, completion: { result in })
    }
```

####Extra argument in call

`self?.cache.object(key)`のkeyの部分で「Extra argument in call」が表示される。googleで翻訳すると「呼び出し中の追加の引数」らしい。


```CacheService.swift
self?.cache.object(key) { (data: Data?) in
                guard let data = data else {
                    observer.onNext(nil)
                    observer.onCompleted()
                    return
                }

                Async.userInteractive {
                    let json = SwiftyJSON.JSON(data: data)

                    Async.main {
                        if let error = json.error {
                            observer.onError(error)
                        } else {
                            observer.onNext(json)
                        }
                        observer.onCompleted()
                    }
                }
            }
```

微力な英語力で質問して帰ってきたのが、[ここ](https://github.com/hyperoslo/Cache#async-apis)を見ろとのこと。

[stackOverflow:I got ERROR about “Extra argument 'forKey' in call” for cache](https://stackoverflow.com/questions/55890666/i-got-error-about-extra-argument-forkey-in-call-for-cache/55898377#55898377)

恥のかき捨て、やれることはやっていこうと思う。
ここでなんとかヒントを得て修正。

```CacheService.swift
self?.cache?.async.object(forKey: key) { result in
                switch result {
                case .value(let data):
                    Async.userInteractive {
                        let json = try? SwiftyJSON.JSON(data: data)
                        Async.main {
                        observer.onNext(json)
                        observer.onCompleted()
                        }
                    }
                case .error( _):
                        observer.onNext(nil)
                        observer.onCompleted()
                    }
                }
```

これでなんとかエラーを解消。

### Use of undeclared type 'LogMessageWriter'
これは Willow というライブラリーと密接に繋がっているログを表示するためのファイル。
これ以降のエラーは全て同じファイルで発生している。

そもそも、Willowって言うライブラリーは何をしているんだ

#### Willow とは
このライブラリーの記事自体非常に少ない。
特に日本語の記事は引っかからなかった。マジで前任の奴が変態すぎる。
唯一見つけたのがこちらの記事
https://medium.com/joshtastic-blog/convenient-logging-in-swift-75e1adf6ba7c

冒頭を要約すると、単純にログを便利に取れるって書いてある。
単純にprintで記述すると混乱を生じてしまうから、このライブラリーは便利ぽい。
逆に、そこまで情報が少ないと言うことはこれを使い続ける必要はないだろう。

これをpodから抜き出して関連するファイルを洗い出す。


### Use of unresolved identifier 'configuration'

### Static member 'AAAA' cannot be used on instance of type 'Logger'
これ以降は同じ内容で、示している部分が違うようだ。
多分、インスタンスの設定が違っているようだ。

なんと発見した！
Willow4にアップデートするための適応ガイドが公式から発表されていた。
https://github.com/Nike-Inc/Willow/blob/master/Documentation/Willow%204.0%20Migration%20Guide.md

なんと素晴らしい。
まずは下記の２つの名称変更

- LogMessageModifier → LogModifier
- LogMessageWriter → LogWriter


- Static member 'debug' cannot be used on instance of type 'Logger'
- Static member 'info' cannot be used on instance of type 'Logger'
- Static member 'event' cannot be used on instance of type 'Logger'
- Static member 'warn' cannot be used on instance of type 'Logger'
- Static member 'error' cannot be used on instance of type 'Logger'

##ビルドしたが、、、
これでなんとか解消と思ったてビルドしたが、起動画面でフリーズ。
ログにも何も表示されない状態。
完全に何が起きているのか全くわからない状態。

また、最初っから細かくみていこう、、、、、