SALE: Save 50% on all my books and bundles >>

Updated: SwiftUI app crashes when going back in a NavigationView

Forums > SwiftUI

UPDATE:

This is even weirder than I thought, it seems to only crash on some devices. See my comment below.

--- Original question ---

I noticed a weird behavior that the app only crashes if I render the NavigationLink destination as a List. Here is code that reproduces the problem:

import SwiftUI

struct TestView: View {
    var crash: Bool
    @State private var isLoading = true
    @State private var result = [String]()

    private func fetch() {
        isLoading = true
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            self.result = ["a", "b", "c"]
            self.isLoading = false
        }
    }

    var body: some View {
        Group {
            if isLoading {
                Text("loading")
            } else {
                if crash {
                    List {
                        ForEach(0..<result.count, id: \.self) { index in
                            Text(self.result[index])
                        }
                    }
                } else {
                    Text(result.joined(separator: ", "))
                }
            }
        }
        .onAppear(perform: fetch)
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: TestView(crash: true)) {
                    Text("Crashes when going back")
                }
                NavigationLink(destination: TestView(crash: false)) {
                    Text("Does not crash")
                }
            }
        }
    }
}

So if TestView is rendering its content as a Text, it works fine. If it's rendering as a List, the app crashes when hitting the back button in the navigation bar (after letting the loading complete). Am I doing something wrong?

1      

I just ran this on Xcode 11.4 and could not get the app to crash. Hopefully you're seeing the same result.

-Dan

   

Are you waiting for the loading to complete? It still crashes for me with Xcode 11.4 & iOS 13.4.

   

I don't know how to embed video in forums like this so here's a link to a litlte YouTube video of the simulator running your code. I created a new Xcode project just now and copied/pasted your code into it, then ran the app. I wish I could help more other than the "it works on my machine" answer. 😬

https://youtu.be/JdOGhpeg6JU

1      

UPDATED ANSWER

I just updated to 13.4 and put your code back as it was...and it no longer crashes w/ your code. Looks like it may have been a bug that was fixed internally by Apple w/ the latest update.

----- My Original Answer -----

Okay, so I did see the crashing behavior you describe, but not in the simulator. It crasbed when deployed to my physical device runnng iOS 13.31.

In that scenario, I made a change and moved the List so it is the first child of the Group element as below. This is not specifically what you are looking for, this does not crash. It may help you (or Paul?) get closer to what is actually happening.

    var body: some View {
        Group {
            List {
                if isLoading {
                    Text("loading")
                } else {
                    if crash {
                        ForEach(0..<result.count, id: \.self) { index in
                            Text(self.result[index])
                        }
                    } else {
                        Text(result.joined(separator: ", "))
                    }
                }
            }
        }
        .onAppear(perform: fetch)
    }

1      

Thank you for your answers!

OK, so this is getting weirder. It seems that it only crashes on some devices. These are consistent across two different Macs (both running 10.15.4). Simulators with iOS 13.4 if not otherwise specified:

Crashes:

  • iPhone 11 Pro
  • iPhone 8
  • iPhone X (physical device, iOS 13.3.1 & iOS 13.4)
  • iPhone XS (physical device, iOS 13.3.1)

Does not crash:

  • iPhone 11 Pro Max
  • iPhone 11
  • iPhone 8 Plus

   

Hacking with Swift is sponsored by RevenueCat

SPONSORED Building in-app subscriptions are hard. RevenueCat makes it simple. With their open source SDKs, you can painlessly implement subscriptions for your app in hours, not months.

Explore the docs to learn more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

Snapthread is a casual video editor and slideshow maker that makes discovering, compiling and sharing your favorite memories effortless.

 
Unknown user

Not logged in

Log in