SwiftUIで . を付け忘れて解決に時間がかかった話

SwiftUIを使用してアプリケーションを開発していた際、ふとしたミスによって非常にわかりにくいクラッシュを引き起こしてしまいました。

ひとつのタイプミスによって私の時間が無駄に消費される事になってしまいました...

以下、その顛末を説明します。

まずは正常に動作するコードを示します。このようなViewを作成したかったのです(わかりやすさのために超簡略化)。

struct Sample: View {
    var body: some View {
        VStack {
            Spacer()
            Text("Contents")
            Spacer()
        }
        .safeAreaInset(edge: .bottom) { 
            Text("Bottom")
        }
    }
}

結果表示される画面。

表示結果

次に、問題となったコードを示します。どこが問題なのか一見するとわかりませんよね?このコードを実行すると、アプリが固まった後にクラッシュしてしまいます。また、プレビューを行ってもエラーが発生しました。

struct Sample: View {
    var body: some View {
        VStack {
            Spacer()
            Text("Contents")
            Spacer()
        }
        safeAreaInset(edge: .bottom) { 
            Text("Bottom")
        }
    }
}

この際に表示されたエラーも非常にわかりにくく、解決までに多くの時間を要しました。

わかりにくいエラー表示のスクリーンショット

問題は、safeAreaInsetの前にあるべき.が抜けていたことでした。その結果、safeAreaInsetメソッドがVStackのメソッドとして呼び出されるべき場面で、自分自身のViewに対して呼び出されてしまいました。

まとめ

  • ちょっとしたミスでわかりにくいクラッシュの原因を作ってしまい、解決に時間がかかる事態となりました。
  • コンパイラがエラーを検出してくれればよかったのですが、確かにこのようなコードも一定の解釈が可能なため、エラーチェックが難しい場面である
  • 気をつけよう

実際にはこのぐらいのサイズのViewだったからまじで発見に手間取りました。

実際のView