在通常通过调用数据库获取处理的 SwiftUI 中设置预览数据的最佳方法是什么?
What's the best way to set preview data in SwiftUI which is normally handled by calling a database fetch?
我的应用程序在视图的 .onAppear 方法中调用了数据库,但我想使用 SwiftUI 的预览功能。有没有办法在预览中模拟或禁用此功能 window?
struct MyView: View {
@State var dataArray: [Data] = [Data]()
var body: some View {
VStack {
ForEach(dataArray) { data in
Text(data.text)
}
.onAppear {
getData()
}
}
private func getData() {
someCallToDatabase() { returnedData in
self.dataArray = returnedData
}
}
struct MyView_Previews: PreviewProvider {
static var previews: some View {
MyView()
}
}
基本上我想手动传递数据而不被覆盖,或者以某种方式向我的数据库调用者添加一个扩展 class 当它知道它只是为了预览.
非常感谢,仰卧起坐!
通过使用某种依赖注入,您可以确保有一个 class/object 负责执行可以模拟的数据库调用。其中一个版本可能是使用 @Envrionment
发送一个对象来处理数据库调用:
struct ApiData : Identifiable {
var id = UUID()
var text : String
}
protocol DatabaseManager {
func someCallToDatabase(_ callback : ([ApiData]) -> Void)
}
class RealDatabaseManager : DatabaseManager {
func someCallToDatabase(_ callback: ([ApiData]) -> Void) {
callback([]) //do real database call here
}
}
class MockDatabaseManager : DatabaseManager {
func someCallToDatabase(_ callback: ([ApiData]) -> Void) {
callback([])
}
}
private struct DatabaseEnvironmentKey: EnvironmentKey {
static let defaultValue : DatabaseManager = RealDatabaseManager()
}
extension EnvironmentValues {
var databaseManager : DatabaseManager {
get { self[DatabaseEnvironmentKey.self] }
set { self[DatabaseEnvironmentKey.self] = newValue }
}
}
struct MyView: View {
@State var dataArray: [ApiData] = [ApiData]()
@Environment(\.databaseManager) private var databaseManager : DatabaseManager
var body: some View {
VStack {
ForEach(dataArray) { data in
Text(data.text)
}
}
.onAppear {
getData()
}
}
func getData() {
databaseManager.someCallToDatabase { returnedData in
self.dataArray = returnedData
}
}
}
struct MyView_Previews: PreviewProvider {
static var previews: some View {
MyView().environment(\.databaseManager, MockDatabaseManager())
}
}
当然,您需要确保在非预览视图中,您还使用 [=12] 将 真实 数据库管理器向下传递到视图层次结构=] 在父视图中,因此它会涉及对现有代码的一些细微修改。
我的应用程序在视图的 .onAppear 方法中调用了数据库,但我想使用 SwiftUI 的预览功能。有没有办法在预览中模拟或禁用此功能 window?
struct MyView: View {
@State var dataArray: [Data] = [Data]()
var body: some View {
VStack {
ForEach(dataArray) { data in
Text(data.text)
}
.onAppear {
getData()
}
}
private func getData() {
someCallToDatabase() { returnedData in
self.dataArray = returnedData
}
}
struct MyView_Previews: PreviewProvider {
static var previews: some View {
MyView()
}
}
基本上我想手动传递数据而不被覆盖,或者以某种方式向我的数据库调用者添加一个扩展 class 当它知道它只是为了预览.
非常感谢,仰卧起坐!
通过使用某种依赖注入,您可以确保有一个 class/object 负责执行可以模拟的数据库调用。其中一个版本可能是使用 @Envrionment
发送一个对象来处理数据库调用:
struct ApiData : Identifiable {
var id = UUID()
var text : String
}
protocol DatabaseManager {
func someCallToDatabase(_ callback : ([ApiData]) -> Void)
}
class RealDatabaseManager : DatabaseManager {
func someCallToDatabase(_ callback: ([ApiData]) -> Void) {
callback([]) //do real database call here
}
}
class MockDatabaseManager : DatabaseManager {
func someCallToDatabase(_ callback: ([ApiData]) -> Void) {
callback([])
}
}
private struct DatabaseEnvironmentKey: EnvironmentKey {
static let defaultValue : DatabaseManager = RealDatabaseManager()
}
extension EnvironmentValues {
var databaseManager : DatabaseManager {
get { self[DatabaseEnvironmentKey.self] }
set { self[DatabaseEnvironmentKey.self] = newValue }
}
}
struct MyView: View {
@State var dataArray: [ApiData] = [ApiData]()
@Environment(\.databaseManager) private var databaseManager : DatabaseManager
var body: some View {
VStack {
ForEach(dataArray) { data in
Text(data.text)
}
}
.onAppear {
getData()
}
}
func getData() {
databaseManager.someCallToDatabase { returnedData in
self.dataArray = returnedData
}
}
}
struct MyView_Previews: PreviewProvider {
static var previews: some View {
MyView().environment(\.databaseManager, MockDatabaseManager())
}
}
当然,您需要确保在非预览视图中,您还使用 [=12] 将 真实 数据库管理器向下传递到视图层次结构=] 在父视图中,因此它会涉及对现有代码的一些细微修改。