无法在此文件中预览-[App Name] .app可能在Xcode 11 Beta 5上崩溃了

jsb*_*eJS 1 iphone xcode ios swiftui xcode11

如果我添加EnviromentObject属性包装器,则Xcode预览不起作用。每次我添加一个Canvas都不会建立,并且出现此错误:

无法在此文件中预览-[App Name] .app可能已崩溃

如果我替换EnviromentObject属性包装器ObservedObject并对其进行初始化,则一切正常。

这是我的代码:

class NetworkManager: ObservableObject {

}

struct ContentView : View {
    @EnvironmentObject var networkManager: NetworkManager

    var body: some View {
        Text("Canvas not working")
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environmentObject(NetworkManager())
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

更新:

当我使用绑定时,它也不会加载预览:

class NetworkManager: ObservableObject {

}

struct ContentView : View {
    @EnvironmentObject var networkManager: NetworkManager

    var body: some View {
        Text("Canvas not working")
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environmentObject(NetworkManager())
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

gra*_*ell 8

我假设根据您提供的代码,您SceneDelegate看起来像这样:

if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = UIHostingController(rootView: ContentView())
    self.window = window
    window.makeKeyAndVisible()
}
Run Code Online (Sandbox Code Playgroud)

我不会假装我确切地知道画布在生成预览时在幕后做了什么,但基于错误明确指出应用程序可能已经崩溃的事实,我假设它正在尝试启动尝试生成预览时的整个应用程序。也许它需要使用SceneDelegate来启动预览,也许它完全是其他东西 - 我不能肯定地说。

无论如何,应用程序崩溃的原因是因为您没有在SceneDelegate. 你SceneDelegate应该是这样的:

if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(NetworkManager()))
    self.window = window
    window.makeKeyAndVisible()
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*ges 5

正如@graycampbell所建议的那样,您需要确保将EnvironmentObject提供给SceneDelegate中的ContentView。尽管许多预览/画布机制都位于黑框中,但Xcode的UI建议使用新预览或刷新现有预览,甚至为常规预览构建(或更新)应用变体的形式,例如反对“实时预览”。如果SceneDelegate的设置不正确,则此过程可能会失败。

对于您的@Binding问题,Binding.constant(_ :)应该会有所帮助。根据SwiftUI文档 .constant执行以下操作:

创建一个具有不变值的绑定。

这就是您要预览的内容,而不是示例代码显示的@State。您可以在本Apple教程的第3节中看到使用中的.constant示例。

所以代替这个:

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    @State static var test1 = "Some Preview String"
    static var previews: some View {
        ContentView(test123: $test1)
             .environmentObject(NetworkManager())
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

您可以执行以下操作:

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(test123: .constant("Some Preview String"))
            .environmentObject(NetworkManager())
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

进行此更改后,您的代码预览将非常适合我。请记住,您再次需要在SceneDelegate或使用此特定ContentView的任何其他位置为此Binding提供一个值。否则,您将遇到与EnvironmentObject面临的问题类似的问题,只是幸运的是,编译器错误突出了这一特殊的遗漏。