web-dev-qa-db-ja.com

SwiftUIプレビューキャンバスとコアデータ

プレビューキャンバスがクラッシュしていますが、シミュレータではすべて正常に動作しています。 @ObservedObjectと@Fetchrequestに関連していると思います...

ここで解決策を試しました CoreDataでContentViewをプレビュー

動かない

 import SwiftUI
 import CoreData

struct TemplateEditor: View {

@Environment(\.managedObjectContext) var managedObjectContext

@FetchRequest(
    entity: GlobalPlaceholders.entity(),
    sortDescriptors: [
        NSSortDescriptor(keyPath: \GlobalPlaceholders.category, ascending: false),
    ]
) var placeholders: FetchedResults<GlobalPlaceholders>


@ObservedObject var documentTemplate: Templates
@State private var documentTemplateDraft = DocumentTemplateDraft()
@Binding var editing: Bool


var body: some View {

    VStack(){
        HStack(){
            cancelButton
            Spacer()
            saveButton
        }.padding()
        addButton
        ForEach(placeholders)  {placeholder in
            Text(placeholder.name)
        }
        TextField("Title", text: $documentTemplateDraft.title)

        TextField("Body", text: $documentTemplateDraft.body)
            .padding()
            .frame(width: 100, height:400)
        Spacer()
    }

...




}
struct TemplateEditor_Previews: PreviewProvider {
    static var previews: some View {

    let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Templates")
    request.sortDescriptors = [NSSortDescriptor(keyPath: \Templates.created, ascending: false)]
    let documentTemplate = try! managedObjectContext.fetch(request).first as! Templates


    return TemplateEditor(documentTemplate: documentTemplate, editing: .constant(true)).environment(\.managedObjectContext, managedObjectContext).environmentObject(documentTemplate)

    }
}

プレビューを生成する必要があります

7
Victor Sea

1つのオプションは、プレビューでコアデータを使用しないことです。これは、私が作成しているもののUIを表示するのに十分役立ちますが、機能をテストするにはシミュレータを使用する必要があります。

#if !DEBUG
// Core Data related code e.g. @FetchRequest
#endif

CoreDataを使用したContentViewのプレビュー で提案されたことは、Xcodeバージョン11.0(11A419c)Mac OS 10.15 Beta(19A558d)で機能しました。クラッシュログにインデックスエラーが表示された

***キャッチされない例外 'NSRangeException'が原因でアプリを終了しています、理由: '***-[__ NSArray0 objectAtIndex:]:インデックス0が空のNSArrayの境界を超えています'

そこにデータがなかったので、私はこのユニークな「プレビュー」のケースを処理しなければならず、それで物事はうまくいきました。

1
Keoni

そのため、プレビューのonAppearハンドラーにコードを配置すると、ブート時に実行されます。入力と同時にライブ更新も行われます!

struct TemplateEditor_Previews: PreviewProvider {
  static var previews: some View {
    TemplateEditor().environment(\.managedObjectContext, AppDelegate.viewContext).onAppear {
      let entity = GlobalPlaceholders(context: AppDelegate.viewContext)
      entity.name = "abc123"

      // Or create more, if you need more example data

      try! AppDelegate.viewContext.save()
    }
  }
}

viewContextの静的メソッドでAppDelegateをラップして、アクセスを少し冗長でなく覚えやすくしていることに注意してください。

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  static var persistentContainer: NSPersistentContainer {
    return (UIApplication.shared.delegate as! AppDelegate).persistentContainer
  }

  static var viewContext: NSManagedObjectContext {
    return persistentContainer.viewContext
  }
0
Tim Dorr