SwiftUI - 在预览中模拟 @EnvironmentObject 数据

Mat*_*der 3 mocking swift swiftui

我有这个代码:

struct WelcomeView: View {
    @EnvironmentObject var userService: UserService
    var body: some View {
        Text(userService.user.username)
    }
}

struct WelcomeView_Previews: PreviewProvider {
    static var previews: some View {
        WelcomeView().environmentObject(UserService())
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要实现的是我所有的 UI 组件都使用模拟数据。我要告诉某种方式,在预览我想看到Text(userService.user.username)Text("Alex"),例如。我怎样才能让它工作?我需要在哪里初始化我的user.username以及在哪里放置这个模拟。我只想将该user对象用于我的所有视图。我只是跳过了这个例子。

Asp*_*eri 6

假设UserService使用依赖注入正确设计,可以使用以下方法对生产代码进行任何显式更改

struct WelcomeView_Previews: PreviewProvider {
    static var previews: some View {
        let userService = UserService()
        userService.user = User(username: "Alex", email: "alex@test.com") // << any predefined set up here
        // any more parameters set up here

        return WelcomeView().environmentObject(userService)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这里真正关键的是添加 `return` (2认同)

Wes*_*ley 5

您可以在服务级别或视图级别插入模拟数据。由于您将在多个视图中使用它,因此我建议向服务添加模拟功能(如下面的第一个示例所示)。

我不知道你的UserService样子,所以我在这些示例中添加了一个基本的实现。

服务水平

import SwiftUI

struct User {
    var username: String
}

class UserService: ObservableObject {
    @Published var user: User = User(username: "Initial username")

    // If a mock user is provided to the UserService it will replace the initial user.
    init(mockUser: User? = nil) {
        if let user = mockUser {
            self.user = user
        }
    }
}

struct WelcomeView: View {
    @EnvironmentObject var userService: UserService

    var body: some View {
        Text(userService.user.username)
    }
}

struct WelcomeView_Previews: PreviewProvider {
    static var previews: some View {
        WelcomeView()
            .environmentObject(UserService(mockUser: User(username: "Test username")))
    }
}
Run Code Online (Sandbox Code Playgroud)

视图级别

import SwiftUI

struct User {
    var username: String
}

class UserService: ObservableObject {
    @Published var user: User = User(username: "Initial username")
}

struct WelcomeView: View {
    @EnvironmentObject var userService: UserService

    // Optional mock user. Will replace the user from UserService if provided.
    var mockUser: User? = nil

    var body: some View {
        Text((mockUser != nil) ? mockUser!.username : userService.user.username)
    }
}

struct WelcomeView_Previews: PreviewProvider {
    static var previews: some View {
        WelcomeView(mockUser: User(username: "Test username"))
            .environmentObject(UserService())
    }
}
Run Code Online (Sandbox Code Playgroud)