プレビューキャンバスがクラッシュしていますが、シミュレータではすべて正常に動作しています。 @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)
}
}
プレビューを生成する必要があります
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の境界を超えています'
そこにデータがなかったので、私はこのユニークな「プレビュー」のケースを処理しなければならず、それで物事はうまくいきました。
そのため、プレビューの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
}