Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are the #if DEBUG statements really needed for previews in SwiftUI to remove it in a release build?

The preprocessor macro's are pretty commonly seen in the SwiftUI official tutorials/videos, e.g.:

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

Are those needed? The compiler can surely see that the struct isn't used internally and omit the whole struct since the access modifier is implicit internal right? I think that everything that conforms to PreviewProvider can be removed away, but maybe that isn't the case for every conforming object, but if it isn't used, why does Apple decides to include the preprocessor macro's?

I tried to run it in release mode and locate the compiled class in the derived data folder, but I don't understand anything about it (.o file). Can anyone confirm if we really need to include the macros to omit unused code (the ContentView_Previews type doesn't get used anywhere in the code expect for previewing which isn't used in the release build anyway) in the release build?

like image 793
J. Doe Avatar asked Jun 06 '19 21:06

J. Doe


2 Answers

NOTE: To be extra clear, you DO NOT need to wrap your preview providers in #if DEBUG conditionals. They are removed from your production build.

I'm a little late, but I just had to make note of this because the confusion is all over the web and it turns out to be quite comical. The release note was under "Resolved Issues" and the title of the resolved ticket was "PreviewProviders aren’t properly removed from built products when archived. (51539802)".

Yeah, it all makes sense now.

The still The proof

Annnd Just in case you think they may have changed it later..... more proof

(I'm thorough... maybe too much so)

like image 157
Dave Arel Avatar answered Sep 27 '22 19:09

Dave Arel


For your particular case you can remove the #if DEBUG macro, but the issues comes when you want to use some mocks that are inside #if DEBUG macros. The build will fail for Release, because looks like Xcode will still try to build the PreviewProvider, most likely after it is build it strips or unlinks the code from the Release artifact.

#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())     } } 

This will work just fine for tests and for preview, but will fail when you try to release.

Despite they are not necessary, you need them if you use any code declared only for Debug. My suggestion is to keep them if you have code used in preview that is available only for debug.

#if DEBUG  class MyServiceMock: ServiceMockType {     ... }  #endif  ...  #if DEBUG struct ContentView_Previews : PreviewProvider {     static var previews: some View {         ContentView(service: MyServiceMock())     } } #endif 
like image 37
Mihai Georgescu Avatar answered Sep 27 '22 17:09

Mihai Georgescu