I have an app already in production that uses SwiftUI's lifecycle (paired with an AppDelegate
). Due to some specific behaviour of the app, we decided to migrate the app to use UIKit's lifecycle, adding the corresponding SceneDelegate
to the app, as well as modifying the Info.plist
file accordingly to accommodate to these new changes.
Although everything seems to work when installing the app from zero, installing it on top of a previous version makes the screen go black so the user cannot interact with the app at all unless they reinstall it completely. As I've read online, iOS is reusing the window configuration from the previous execution of the app. I know this because the AppDelegate's application(application:connectingSceneSession:options)
is not being called when coming from a previous version of the app.
I would like to know if anyone has experienced this behaviour and how did they do to solve it, because we cannot ask our user base to reinstall the application.
Edit:
After a lot of debugging and messing with the existing code, I've found a way to circumvent the problem. It seems like using the SwiftUI lifecycle and attaching the SceneDelegate
does work. At least partially, because right now I am using an EmptyView
as the root of my app in SwiftUI even though I then initialise the app in the SceneDelegate
correctly. This allows me to partially use the UIKit lifecycle, but I cannot abandon SwiftUI's lifecycle completely. I like the solution if it can be used as a partial update for the app that should be followed by another update that really uses only UIKit's lifecycle.
When I check the UIApplication
object in the AppDelegate
, I see that it has an openSession
already configured, and I've seen that it has a AppSceneDelegate
associated (which is presumably created by SwiftUI). Now, my question is, is there a way to remove this opened session? It will be great as a final update for my app, because having a hybrid SwiftUI-UIKit's lifecycle is a solution I don't really love right now.
Edit 2:
Even though the app works and Universal Links are correctly handled with the SceneDelegate
when the app is firstly opened by a Universal Link, tapping a Universal Link when the app is in background doesn't trigger the corresponding method in the SceneDelegate
but instead, it should be handled via onOpenURL
in SwiftUI. Once again, I guess this is because the weird hybrid lifecycle that I had to use to make it work.
After messing around with it I've found the problem and how to fix it.
The problem was that there's an option in the Build Settings
of Xcode called Application Scene Manifest (Generation)
by default when the project is created with SwiftUI (I don't know about UIKit) this option is set to YES.
This configuration seems to override whatever values you set in your Info.plist
regarding the Scene Configuration,
thus leaving the app with a black screen with no content. The solution wat setting that configuration to NO
and, magically, the screen appeared correctly on my device.