Search code examples
xcodeasynchronousswiftui

Preview Crashes but Simulator runs fine


I'm unfortunately not able to provide much code due to how large the project is (across multiple files and any code I'd write here wouldn't really be relevant anyways), but essentially my Preview will crash and then not be able to rerun unless I close and re-open the entire project if I switch between a certain tab view too fast.

Each Tab signifies an item type, and then when opened, it uses .task {} and an async .getDocument() within .task{} to retrieve FireStore data.

Now, everything works just fine in the preview and simulator if I take my time switching between the tabs and looking at the data, but if I start spamming between the tabs the preview will crash and I get a load of these messages in the debugger:

enter image description here

However, when I use the simulator even with spamming between tabs it works just fine.

I feel like this have something to do with the use of async functions after every view change, and that switching between the views causes the preview to trip over itself while one async task was still being executed but can no longer be displayed after execution since the view has already changed, and the reason for the simulator working is because it handles these errors or just tosses them away? I'm not too familiar with exactly how xcode previews and simulators handle such things so any tips would be helpful :)

In this case though, would it be smarter to fetch all the data from FireStore on the initial base view opening and then store it locally so that I don't need to use async functions any longer, or is it a completely unrelated issue?


Solution

  • Fetching data in Previews does not always behave as expected, especially if it requires authentication. Your preview is most likely not authenticated like your simulator. As a workaround you can put this code

    if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" {
          //create dummy data
          return
    }
    

    before fetching the actual data. This block will only be entered, when you are using previews, so you can to whatever you like to simulate actual behavior.