46

In my SwiftUI app, I have put some sample model objects in Xcode's "Preview Content" folder. I only access them in my SwiftUI PreviewProviders. My understanding is that the code/assets in this folder are only used for previewing in the Canvas. My previews work properly. I'm using Xcode 11.6 (11E708).

However, when I go to Archive my app, it fails because it cannot find these sample model objects. I was under the impression that PreviewProvider code is not build into the final binary as of Xcode 11. See this question, along with the item from the Xcode 11 release notes that says,

Resolved Issues

The #if/#endif compiler conditionals surrounding PreviewProvider types have been removed from SwiftUI templates. PreviewProviders aren’t properly removed from built products when archived. (51539802)

(Curiously, I am able to compile with the Release configuration. It's just Archive that fails.)

As a workaround, I can put the #if DEBUG/#endif wrappers around my PreviewProvider but the above quote from the release notes indicates that shouldn't be necessary.

Do I misunderstand how the "Preview Content" folder works?

bdesham
  • 15,430
  • 13
  • 79
  • 123
Jeremy
  • 2,801
  • 2
  • 30
  • 31
  • 17
    I'm not sure why someone voted this down.. I think this is a great question. I've also run into this and used the same workaround `#if DEBUG`. I hope someone can shed light on this! – JoeBayLD Jul 25 '20 at 10:04
  • Same issue. I have a custom class in "Preview Content" folder which causes a compiler error when I try to archive. I'll have to add the `#if DEBUG` until Apple resolves the issue. (Xcode 12.2). – Vinzius Dec 04 '20 at 15:18
  • SwiftUI previews can only be deployed to devices when the deployment target of the project is iOS 10+ - does your deployment target support < iOS 10? – Pranav Kasetti Jan 06 '21 at 05:07
  • @PranavKasetti it works when wrapped in `#if DEBUG` so it’s not a deployment target issue – LaX Jan 07 '21 at 10:19
  • @LaX that's not correct, archiving includes compiling and deploying to a generic device target. I've taken the known issue from [here](https://developer.apple.com/documentation/xcode-release-notes/xcode-11-release-notes). When < iOS 10, the `#if DEBUG` looks needed since they are not stripped on deploy. – Pranav Kasetti Jan 07 '21 at 10:53
  • @PranavKasetti - My project is targeting iOS 14+. – Jeremy Jan 07 '21 at 15:43
  • Ok, that narrows it down at least. Do you have any custom classes in `Preview Content`? Also maybe worth filing a bug report on Feedback Assistant.app. – Pranav Kasetti Jan 08 '21 at 08:44
  • Yes I did have custom classes, for my sample test data. Yeah, given the number of upvotes and lack of answers I don't think I'm missing anything now. Probably worth a feedback. – Jeremy Jan 08 '21 at 15:45
  • I filed FB8969539 for this with Apple. Here is the writeup, if anyone else wants to clone: https://openradar.appspot.com/radar?id=4985741033603072 – Jeremy Jan 13 '21 at 21:29

2 Answers2

3

Edit: Nevermind, this approach "works" but the preview code is still in the final archive, so it doesn't really help anything.

I put all my preview test data in its own `PreviewProvider` so that I can access it in other Previews. The Archive still succeeds, and the test data will get stripped in the final Archive. No `#if DEBUG` is needed.

Example (specific to my own use case):

struct PreviewData: PreviewProvider {
    static var previews: some View {
        Text("This is test data for use in other previews.")
    }

    // Use enums for namespacing if desired
    enum Choices {
        static let deals = Choice(id: UUID().uuidString, text: "I want the best deals.", iconName: "bestDealsIcon")
        static let technology = Choice(id: UUID().uuidString, text: "I love technology!", iconName: "technologyIcon")
    }

Then I can access PreviewData.Choices.deals in other PreviewProviders.

Jeremy
  • 2,801
  • 2
  • 30
  • 31
  • 1
    somehow this solution doesn't work for me. I'm still getting the not found compiler error. So I had to use `#if DEBUG` as well. I'm using Xcode Version 12.3 (12C33). – Buju May 20 '21 at 16:02
  • 2
    Nevermind - I realized this test data is *not* stripped from the final archive. I tried using some of it in my normal views (not Previews) and it works, when it shouldn't. – Jeremy Aug 03 '21 at 21:19
0

I had a very similar issue occur, only I was building an App Clip for an existing app. I couldn't compile with the release scheme or archive for distribution with neither versions of Xcode 12.5.1 or 13.0.

The solution was to include the Preview Content directory under the development assets of the parent app's target, not the App Clip target itself. As a result, I got it to work in all scenarios, including SwiftUI previews, release builds and archiving the parent app for distribution.

Marcos Curvello
  • 873
  • 13
  • 25