LAST CHANCE: Save 50% on all my Swift books and bundles! >>

request App Review causing strange crash

Forums > SwiftUI

I have a strange problem, and I could use some advice on how to start solving it, most probably I need advice on a good resource for debugging in xcode.

I am at the end of a fairly large project and I wanted to drop in the code to summon an App Review request. The code for the request could not be more trivial, here is a link to Paul's very short article on it https://www.hackingwithswift.com/quick-start/swiftui/how-to-ask-the-user-to-review-your-app

So the weird bug is, as soon as I include the environment variable like so...

import StoreKit

Struct MainMenu: View{
    @Environment(\.requestReview) var requestReview
...

It causes the app to freeze on any navigation attempt, checking the debug session I also see that memory is steadily ticking upwards. I am not even attempting to call the requestReview(), the @Environment alone is enough to cause the issue. There is clearly some very strange interaction somewhere in thousands of lines of code, and I don't know how to begin chasing it down.

Currently I am just trying to replicate or isolate the issue in a seperate skeleton project, but I am not having much luck yet.

Some simple print statements verifies that the init, and onAppear functions of the next view are being called and executed, but the app just will not load any NavigationStack view and the memory goes leaky.

I also found that it does not matter what view I place @Environment(.requestReview) var requestReview in, it will cause this issue. A burried view that is no where near being called will still trigger the bug.

A random thing that I dont understand but might be related, when typing out the @Environment(.request.... I see a red X in the autocomplete box that says async 'requestReview' used in a context that does not support concurrency This might just be an odd autocomplete bump, I am not sure why it would say that while typing out the @Environment, but then not display at all when the line is complete. Perhaps @Environment has a task in it or something.

If you managed to read this far, kudos for you! This is a weird bug and one of the very last items on my check list to get this app shipped, so you can imagine how frustrating it is. I will continue to write out things that I do to solve this issue and if I find a solution, but input from other people is often very helpful.

4      

Of note, simply forcing the requestReview() function to run does pop up the request review in testing.

.onAppear{
                if 5 >= 4 && !showLanguageDisclaimer{
                    requestReview()
                }
}

It still prevents navigating to another view.

I also created a very simple NavigationLink to a helloWorld View, just to make sure it was not something else in the views being called that was at issue. The freeze still occurs.

NavigationLink{
          TESTView()
} label: {
          text("TEST")
}

A very strange thing I just noticed, the code behaves fine when running in the preview window from the MainMenuView, so perhaps there is something odd with the App file or Splash screen. Further checking shows that trying to run from the SplashScreenView, which is the first view called by the WindowGroup, seems to have the error appear in previews. However, cutting the SplashScreenView from the call hierarchy and commenting it out does not prevent the error from occuring when compiled.

This feels like a successful narrowing down of where the error might lie, and a significant reduction of the code to focus on. I am going to keep on fiddling with the main App file and the SplashScreen and see if I can kill a component and stop the error.

Also, yes this is a little bit of a rubber duck thread, but I hope that such information might prove useful to me or other people at some point.

3      

Further testing is showing me that wrapping the MainMenu() View in different things causes strange interactions with the requestReview().

import SwiftUI

struct FreezeFinderView: View {
    var body: some View {
        NavigationStack{
            MainMenu()
        }
    }
}

//#Preview {
//    FreezeFinderView()
//        .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
//        .environmentObject(ContributionStore())
//}

struct FreezeFinderView_Previews: PreviewProvider{
    static var previews: some View{
        FreezeFinderView()
            .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
            .environmentObject(ContributionStore())
    }
}

Various tests Vstack - Freeze use #Preview instead of the old version of previews - Freeze Group - Works fine NavigationStack - Crazy behavior! The app starts to make reviewRequests on every view in the app, it interacts horribly with tipKit, causing rampant appear and disapears of tips

Perhaps this is some strange interaction with TipKit? It is a rather new addition. Guess I am going to go and knock that off and see what happens!

3      

Stripping TipKit out had no effect. Back to making a skeleton.

3      

Continuing to narrow things down.

I can make a simple skeleton project using all components from storeKit, tipKit, and coreData that seems to function fine with no odd issues. The problem is of course in my own code, still worth checking to make sure that the api isnt playing nasty.

After going through and eliminating every system in this app, I have found that the interaction in question has to be somewhere in my NavigationStack, so I am working on cleaning that up and trying to find a possible problem hiding in there. It is still a quandry as to why in the world the simple inclusion of @Environment(\.requestReview) var requestReview causes this issue. There is definately something to that one line of code that I do not understand.

3      

Hi Peter,

I encountered exactly the same. I also tried to strip down my code but after all just adding @Environment(\.requestReview) var requestReview leads to a memory leak and an unresponsive app - but only on a child view of the NavigationStack.

So for the moment I gave up. Thanks for your post and your in-depth analysis - at leat I now know, that I'm not alone.

Thanks Harry

3      

So updates after I eventually solved the problem.

Sadly I only have guesses at what the problem was that was causing issues with requestReview.

One of my thoughts was that it must be some sort of data/View race, as the memory useage kept going up and up. So I went through my code and basically eliminated any useage of .onAppear. I also consolodated all of the @State variables into controller structs using custom init and binding. Really paying attention and cleaning that up seems to have eliminated the issue.

My comments on TipKit possibly being at fault were simply missleading bugs with TipKit that apple has partially solved at this point. TipKit was unrelated.

I also went through and cleaned up the NavigationStack. I had been using the automated navigation stack with NavStack, and Nav links. That system kind of works but it causes some pretty annoying issues with views being created before they are called, and in my case it was happening quite a few times. TwoStraws has a description of exactly the problem that I was having here. https://www.hackingwithswift.com/books/ios-swiftui/the-problem-with-a-simple-navigationlink This clean up is actually very important for making the views behave, the bigger the app gets the more important it becomes.

But good luck to anyone else having this issue, I really do think that it has to do with requestReview causing some strange ViewLoading loop that wont resolve. But I have no idea why simply declaring the environment variable causes that issue. At least it makes the bug appear fast.

3      

I am having this exact same issue but I cannot reproduce it in a stripped down version of the app. It only occurs when I use NavigationLink though. If I used NavigationPath with buttons that update the path that is given to NavigationStack(path:root:) it works fine. Not sure what's happening.

   

Hacking with Swift is sponsored by Essential Developer.

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until July 28th.

Click to save your free spot now

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.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.