Как показать образец данных в PreviewProvider при использовании FetchRequest
У меня есть такой вид SwiftUI:
import SwiftUI
struct ReView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(
entity: Re.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Re.name, ascending: false)
]
) var entities: FetchedResults<Re>
var body: some View {
NavigationView {
List(entities, id: \.self) { entity in
Text(entity.name ?? "Unknown")
}
}
}
}
struct ReView_Previews: PreviewProvider {
static var previews: some View {
Group {
ReView()
.environment(\.managedObjectContext, PersistentCloudKitContainer.persistentContainer.viewContext)
}
}
}
Что я могу сделать, чтобы показать образцы данных в моем предварительном просмотре?
3 ответа
Вот адаптированный подход (ранее предложенный в /questions/52527490/peredacha-osnovnyih-dannyih-fetchedresults-and-ltt-and-gt-dlya-predvaritelnogo-p/52527497#52527497), протестированный с Xcode 12 / iOS 14
Идея состоит в том, чтобы отделить явное представление + модель от поставщика модели (в данном случае облачной базы данных), чтобы представление можно было спроектировать и протестировать (предварительно просмотреть) с использованием локальной или динамически созданной макетной модели (без использования тяжелого облачного соединения)
truct ReView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(
entity: Re.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Re.name, ascending: false)
]
) var entities: FetchedResults<Re>
var body: some View {
ReEntitiesView(entities: entities)
}
}
struct ReEntitiesView<Results:RandomAccessCollection>: View where Results.Element == Re {
let entities: Results
var body: some View {
NavigationView {
List(entities, id: \.self) { entity in
Text(entity.name ?? "Unknown")
}
}
}
}
struct ReView_Previews: PreviewProvider {
static let entity = NSManagedObjectModel.mergedModel(from: nil)?.entitiesByName["Re"]
static var previews: some View {
let object = Re(entity: entity!, insertInto: nil)
object.name = "Test Name"
return ReEntitiesView(entities: [object])
}
}
Мне удалось создать статический moc для структуры предварительного просмотра, а затем добавить к нему данные по мере необходимости.
Что-то вроде этого:
struct ReView_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
_ = Re(context: moc, mandatoryParam1: "foo" ...)
_ = Re(context: moc, mandatoryParam1: "bah" ...)
static var previews: some View {
Group {
ReView()
.environment(\.managedObjectContext, moc)
}
}
}
Я все еще на первых этапах работы со SwiftUI, поэтому почти наверняка более элегантные способы достижения. Но, по сути, создание тестовых данных - это просто программирование последовательности, которая будет происходить в симуляторе для их создания, поскольку в режиме реального времени это и есть предварительный просмотр.
Обратной стороной является то, что очистка поврежденных тестовых данных также может потребовать некоторых усилий по программированию.
Удачи.
Я просмотрел это руководство сегодня и нашел решение, которым я доволен.
https://www.russellgordon.ca/tutorials/core-data-and-xcode-previews/
Xcode теперь частично решает эту проблему с помощью своего шаблона проекта, когда вы решите включить CoreData. Создан файл Persistence.swift. Если заглянуть внутрь, там
static var preview
где вы можете сделать некоторые образцы данных, которые фиксируются в «контексте предварительного просмотра».
В вашем PreviewProvider для представления, которое вы хотите просмотреть, добавьте модификатор к экземпляру представления, который переопределяет manageObjectContext, вместо этого указывая на «контекст предварительного просмотра».
struct ProductsList_Previews: PreviewProvider {
static var previews: some View {
ProductsList()
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
Теперь, когда запускается FetchRequest в моем представлении ProductsList(), он использует «контекст предварительного просмотра», который я использовал в своем переопределении.
Я узнал, как сделать все это, прежде чем найти эту статью сегодня. Препятствие, с которым я столкнулся после, привело меня к статье — как предоставить отдельные примеры моих сущностей для моих предварительных просмотров. Я бы порекомендовал эту статью, если у вас тоже возникли трудности с этим (что в большинстве случаев кажется естественным следующим шагом).