0

Background:

The situation described is very similar to those highlighted in the following questions on SO and Apple Developer forums.

Unfortunately, after trying the suggested solutions, as well as hours spent on trying a permutation of other solutions, none has worked except for using a private level API.

Full context:

A SwiftUI app was handled to me to be reworked as a UIKit app. The migration involved, in brief, updating the Info.plist to use the UIApplicationSceneManifest, adding a SceneDelegate, and adding the @main to the AppDelegate file.

Issue: for iPhone devices that had the prior app with the SwiftUI arch installed, installing the updated version of the UIKit app would show a black screen.

Further investigations shows that:

  • the SceneDelegate methods are never called
  • application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration is never called from AppDelegate
  • this issue would not occur if the user deleted the prior version app, and installed the new UIKIt app
  • this may be due to the cached SceneDelegate sessions, which was introduced in iOS 13

However, it is not possible to ask the users to delete the prior SwiftUI app and download the new app.

"Bad" solution:

The only thing that has worked so far is to insert the following

application.openSessions.forEach { session in application.perform(Selector(("_removeSessionFromSessionSet:")), with: session) } 

in didFinishLaunchingWithOptions in AppDelegate. However, because this is a private-level API, I am unable to use it in the live app.

For context, the private API solution was found here from a write-up on testing.

Question

Are there other ways to perform the session removal similar to what the private API did, which will remove the cached SceneDelegate sessions? I have also tried UIApplication.shared.requestSceneSessionDestruction(session, options: nil) and UIApplication.shared.requestSceneSessionRefresh(session), but neither worked.

Thanks!

2
  • I tried to replicate this issue but I could not. I created a new iOS project based on SwiftUI. I ran that default "Hello World" project on an iOS 17.4 simulator. I returned to the Home screen and then terminated the app in Xcode. I then added a new target to the project. This time a Storyboard-based iOS app. I edited the new target's Build Settings to give it the same bundle identifier as the SwiftUI app. I then built and ran the UIKit app. It ran just fine. It overwrote the SwiftUI app since it had the same bundle id. Can you post a minimal SwiftUI app that replicates the issue? Commented Apr 30, 2024 at 0:58
  • Thanks for taking the time to replicate this issue, @HangarRash I have also tried a starter project, but like you, I am unable to get this issue to replicate. That said, it does seem to be an issue for prod apps switching lifecycle mgmt (from the linked questions).I know from experimentation and using the private API that it is due to a prior cached SceneDelegate from the SwiftUI version, so removing all of the cached sessions with _removeSessionFromSessionSet: did the trick. Would there be another way to tackle removing sessions? Commented Apr 30, 2024 at 1:33

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.