SwiftUIのTextFieldビューでは、状態変数を引数としてバインドさせることで、入力に合わせてリアルタイムでデータの更新処理を行わせることができる。

ただ、この時バインドさせる値のデータ型がオプショナル型であった場合エラーが発生する。

例えばCoreDataのエンティティで、文字列を格納する変数をバインドさせたい場合、特に何もせず通常の流れどおりエンティティを作成するとデータがオプショナル型になってしまうので、エラーが発生してしまうのだ。

struct TaskEditView: View {
  @ObservedObject var task: Task
  
  @Environment(\.managedObjectContext) var viewContext
  @Environment(\.presentationMode) var presentation
  
  var body: some View {
    VStack {
      Form {
        Section(header: Text("タイトル ※必須")) {
          TextField("Edit TaskName", text: $task.name)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .padding(10)
        }

...

上記は一例だが、2行目でバインドさせるためのエンティティを変数宣言し、11行目でTextFieldにバインドさせている。
この時にエラーが発生する。

この問題を解消するには、データ型を変更してあげる必要がある。
今回はその手順を紹介しよう。

非オプショナル型に変更する

CoreDataのエンティティを作成する場合、xcodeの以下の画面から作成する。

その時、画面右のインスペクターパネルでエンティティの属性を細かく設定できる。

デフォルトでOptionalにチェックが入っているので、これをオフにすれば良いかと思うが、これだけでは問題は解消しない。

まず、対象のエンティティを選択状態にしよう。

次にメニューからEditor -> Create NSManagedObject Subclass…を選択する。

すると、画面左のファイルツリーに新たに二つのファイルが生成されるうので「エンティティ名+CoreDataProperties.swift」を選択。

プロパティ名とデータ型の宣言が書かれているので、オプショナル型を表す「?」を削除すればOK。

これで非オプショナル型のプロパティに変更され、TextFieldにバインドできるようになる。