SwiftUI中的预览是否真的需要#if DEBUG语句才能在发布版本中删除它?

x7rlezfr  于 12个月前  发布在  Swift
关注(0)|答案(7)|浏览(127)

预处理器宏在SwiftUI官方教程/视频中非常常见,例如:

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

字符串
需要这些吗?编译器肯定可以看到struct没有在内部使用,并省略了整个struct,因为访问修饰符是隐式的internal,对吗?我认为符合PreviewProvider的所有内容都可以删除,但也许不是每个符合的对象都是这样,但如果它没有使用,为什么Apple决定包含预处理器宏?
我试着在发布模式下运行它,并在派生数据文件夹中找到编译后的类,但我对它(.o文件)一无所知。任何人都可以确认我们是否真的需要在发布版本中包含宏来省略未使用的代码(ContentView_Previews类型不会在代码中的任何地方使用,除非用于预览,反正在发布版本中不会使用)?

zc0qhyus

zc0qhyus1#

注意事项:需要特别说明的是,您不需要将预览提供程序 Package 在#if DEBUG条件中。它们已从生产构建中删除。

我迟到了一点,但我只是不得不注意到这一点,因为混乱是遍布网络,它原来是相当滑稽.发行说明下“已解决的问题”和解决票的标题是“PreviewProviders are not properly removed from built products when archived.(51539802".
是啊,现在都说得通了。
The still证明
万一你认为他们后来可能改变了它......更多的证据

  • (我很彻底...也许太彻底了)*
4c8rllxm

4c8rllxm2#

对于您的特定情况,您可以删除#if DEBUG宏,但是当您想要使用#if DEBUG宏中的一些mock时,问题就来了。对于Release,构建将失败,因为看起来Xcode仍然会尝试构建PreviewProvider,最有可能的是在构建之后,它会从Release工件中剥离或取消链接代码。

#if DEBUG

class MyServiceMock: ServiceMockType {
    ...
}

#endif

// Will fail when you try to release.

struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView(service: MyServiceMock())
    }
}

字符串
这对于测试和预览都很好,但是当你尝试发布时会失败。
尽管它们不是必需的,但如果你使用任何只为Debug声明的代码,你就需要它们。我的建议是,如果你在预览版中使用的代码只可用于调试,那么就保留它们。

#if DEBUG

class MyServiceMock: ServiceMockType {
    ...
}

#endif

...

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView(service: MyServiceMock())
    }
}
#endif

py49o6xq

py49o6xq3#

它似乎是从11转基因种子中删除的。转基因种子发布说明说(在已解决的问题下):
“已从SwiftUI模板中删除PreviewProvider类型周围的#if/#endif编译器条件。存档时,PreviewProvider未从生成的产品中正确删除。(51539802)”
不确定这是否意味着预览提供程序目前没有被删除,或者他们修复了这个问题,现在删除了它们。我想如果模板代码删除了#,如果这意味着苹果认为它不再需要。

zc0qhyus

zc0qhyus4#

Xcode 11.2及更高版本不需要#if DEBUG,因此,您可以执行以下操作并删除PreviewProvider周围的#if DEBUG

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                Text("First Row")
                Text("First Row")
                Text("First Row")
                Text("First Row")
            }.navigationBarTitle(Text("Dynamic List"))
        }
    }

}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

字符串

pbossiut

pbossiut5#

2023年12月。我刚刚在Xcode 15.1上遇到了同样的问题。只有当我为TestFlight部署构建Archive构建时才发现这个问题。
新的#Preview宏代码必须 Package 在#if DEBUG和Preview Content文件夹中的任何数据类中。

ddhy6vgd

ddhy6vgd6#

你不需要删除它。DEBUG是一个自定义的标志,它会自动添加到Your Target -> Build Settings -> Active compilation Conditions中。这个标志只存在于Your Target -> Build Settings -> Active compilation Conditions配置中,对于发布版本,你将使用没有这个标志的发布配置。

如果标志不存在-代码将被省略

Read more here在“调试预处理器宏”部分

jgwigjjp

jgwigjjp7#

在我的例子中:Xcode 13.2.1
我将一些仅预览的模拟移到了development asset,发布版本开始失败。编译错误是关于预览代码中缺少模拟。我认为#if DEBUG宏仍然是必要的

相关问题