web-dev-qa-db-ja.com

CoreDataを使用したContentViewのプレビュー

CoreDataフェッチ要求を含むSwiftUI ContentViewを実行しようとすると、プレビューがクラッシュします。プレビューがコアデータスタックにアクセスできるように@environmentを設定する正しい方法を知りたい。これはシミュレーターへのビルド時にうまく機能しますが、PreviewProviderでは機能しません

import SwiftUI

struct ContentView: View {
    @Environment(\.managedObjectContext) var managedObjectContext

    @FetchRequest(entity: ProgrammingLanguage.entity(), sortDescriptors: [
            NSSortDescriptor(keyPath: \ProgrammingLanguage.name, ascending: true),
            NSSortDescriptor(keyPath: \ProgrammingLanguage.creator, ascending: false)
        ]) var languages: FetchedResults<ProgrammingLanguage>

    var body: some View {
        NavigationView {
            List {
                ForEach(languages, id: \.self) { language in
                    Text("Language: \(language.name ?? "Anonymous")")
                }
            }
            .navigationBarTitle("My Languages")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

ContentView_PreviewsのようにContentViewに引数を渡そうとすると、次のコンパイラエラーが発生します。

ContentView(managedObjectContext: managedObjectContext)

エラー:インスタンスメンバー 'managedObjectContext'はタイプ 'ContentView_Previews'では使用できません

たぶん、これはまだSwiftUIプレビューでサポートされていませんか?またはこれを修正できるものはありますか?

Xcode 11 Beta 7を実行しています。

10
keydogg

クレジットは@ShadowDESに送られます-Xcode Beta 7のマスター/詳細テンプレートプロジェクトには、コアデータを使用するプレビューがあります。

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        return ContentView().environment(\.managedObjectContext, context)
    }
}
#endif

これは私にとってXcode Beta 5で機能します(Beta 7がクラッシュします)

14
bjnortier

受け入れられた答えは私にとってはうまくいきません。

この問題の本質は、プレビューが独自の(空の)永続ストアから始まるように見えるため、すべてのプレビューが機能するのに十分なオブジェクトを何らかの方法でそのストアに追加する必要があることです。データベースが空の場合、データベースにサンプルオブジェクトを入力するクラス関数を作成しました。また、モデルの各エンティティに対して、プレビューする特定のビューに必要な場合は、パラメーターとして渡すサンプルオブジェクトの1つを返す静的プロパティを作成しました。

これにより、プレビューコードが簡単になります。

struct StringAttributeView_Previews: PreviewProvider {  
    static var previews: some View {
        Preview.database()
        return NavigationView {
            StringAttributeView(attribute: Preview.attribute)
        }
    }
}
1
Chuck H