无法在此文件中预览 - [App Name].app 可能已在 Xcode 11 Beta 5 上崩溃
Posted
技术标签:
【中文标题】无法在此文件中预览 - [App Name].app 可能已在 Xcode 11 Beta 5 上崩溃【英文标题】:Cannot preview in this file - [App Name].app may have crashed on Xcode 11 Beta 5 【发布时间】:2019-08-03 17:21:44 【问题描述】:如果我添加 EnviromentObject
属性包装器,Xcode 预览将不起作用。每次我添加一个 Canvas 时,我都会收到此错误:
无法在此文件中预览 - [App Name].app 可能已崩溃
如果我用ObservedObject
替换EnviromentObject
属性包装器并初始化它一切正常。
这是我的代码:
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
更新:
当我使用绑定时,它也不会加载预览:
struct ContentView : View
@EnvironmentObject var networkManager: NetworkManager
@Binding var test123: String
var body: some View
Text("Canvas not working")
#if DEBUG
struct ContentView_Previews: PreviewProvider
@State static var test1 = ""
static var previews: some View
ContentView(test123: $test1).environmentObject(NetworkManager())
#endif
【问题讨论】:
您的示例在 Beta 5 中构建和预览对我来说很好。您能确认您发布的实际示例崩溃了吗?我猜你没有包括整个 NetworkManager。 【参考方案1】:正如@graycampbell 建议的那样,您需要确保在 SceneDelegate 中将 EnvironmentObject 提供给您的 ContentView。虽然许多预览/画布机制都在黑匣子中,但 Xcode 的 UI 会建议调用新预览或刷新现有预览,构建(或更新相关部分)应用程序的变体,即使是常规预览,如反对“实时预览”。如果未正确设置 SceneDelegate,此过程可能会失败。
对于您的@Binding 问题,Binding.constant(_:) 应该会有所帮助。根据 SwiftUI Documentation .constant 执行以下操作:
创建一个具有不可变值的绑定。
这是您想要预览的内容,而不是您的示例代码显示的 @State。您可以在this Apple tutorial 的第 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
您可以执行以下操作:
#if DEBUG
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView(test123: .constant("Some Preview String"))
.environmentObject(NetworkManager())
#endif
通过此更改,您的代码预览非常适合我。 请记住,您再次需要在您的 SceneDelegate 或您使用此特定 ContentView 的任何其他位置中为此绑定提供一个值。否则,您将遇到与 EnvironmentObject 类似的问题,只是这个特殊的遗漏幸运地被编译器错误突出显示。
【讨论】:
【参考方案2】:根据您提供的代码,我假设您的 SceneDelegate
如下所示:
if let windowScene = scene as? UIWindowScene
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView())
self.window = window
window.makeKeyAndVisible()
我不会假装我确切知道画布在生成预览时在幕后做了什么,但基于错误明确指出应用程序可能已经崩溃的事实,我假设它是在尝试生成预览时尝试启动整个应用程序。也许它需要使用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()
【讨论】:
这是正确的,但在我的实际应用程序中,我有很多使用 .enviromentObject() 相互呈现的视图,它仍然不会加载预览。查看我更新的问题,当我使用绑定时它也不会加载预览 您的问题的更新实际上并没有改变任何东西。@Binding
属性与您遇到的问题无关。如果实际上您的应用程序只是由您的SceneDelegate
启动的ContentView
,正如您的示例代码所暗示的那样,我的回答确实可以解决问题。如果您在问题中提供的代码不能准确地代表您的应用程序的结构,我无法就您的实际应用程序为您提供答案。
我知道,但我该如何解决这个绑定问题
@Binding
属性无关紧要——这就是我的观点。绑定属性不是您的示例代码的问题。在您添加绑定属性之前,预览已经没有加载,那为什么会在之后加载呢?
上一个问题已通过将 .envObj() 添加到场景委托中得到修复。但现在如果我添加 binding
属性,它就不起作用了【参考方案3】:
我遇到了同样的问题,我发现了原因。
我只是忘了添加.environmentObject()
修饰符
预览部分中的ContentView()
。
struct Content_Previews: PreviewProvider
static var previews: some View
ContentView().environmentObject(NetworkManager())
这就是 Xcode 构建它的原因,没有显示代码错误, 但在画布上预览时崩溃了。 - 简单的错误,我知道。
【讨论】:
【参考方案4】:看起来像 Xcode 问题。尝试使用蓝色按钮而不是“再试一次”。
【讨论】:
问题是它没有出现【参考方案5】:对此我确实有一个解决方法,但是确实存在 XCode 中的错误。
要解决这个问题。您必须先设置您的SceneDelegate
。
if let windowScene = scene as? UIWindowScene
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(NetworkManager()))
self.window = window
window.makeKeyAndVisible()
.
您也必须设置预览。看来你已经这样做了。
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView().environmentObject(NetworkManager())
.
最后,只需在ContentView
中声明一个@State
变量,与@Published
和@EnvironmentObject
的类型相同,无论您是否使用它来绑定ContentView
中的任何位置都没有关系。
@State var bindingVar: Double = 0.0
正如我之前所说,这是 XCode 错误,我不知道为什么 ContentView
需要一个相同类型的 @State 变量来开始预览 @EnvironmentObject
绑定代码。
可能是ContentView_Previews
无法从@EnvironmentObject
找到绑定。
您可以在我的代码中看到下面的内容,它就像一个魅力。
【讨论】:
以上是关于无法在此文件中预览 - [App Name].app 可能已在 Xcode 11 Beta 5 上崩溃的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI Preview 显示错误 - 无法在此文件中预览 - 当前目标需要调整构建设置