无法在此文件中预览 - [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 显示错误 - 无法在此文件中预览 - 当前目标需要调整构建设置

uniapp图片或文件的预览和下载,兼容ios+安卓+浏览器+企业微信H5

SwiftUI Preview 因 *** 崩溃

APP图标设计小技巧:在iOS上快速获得APP图标的真实预览图