0

I have implemented iOS/iPadOS 13 state restoration using NSUserActivity, mainly because my app supports multiple scenes.

The problem is that when I'm running the Simulator with two side-by-side scenes and force restart the app by rebuilding the activities are not saved and the UI is not properly restored on relaunch.

On the other hand if I first go back to the iPad home screen and then I force relaunch the app, the activities are properly restored.

Would this mean that a crash of my app would prevent saving these activities leading to an inconsistent UI state on relaunch?

And how could I periodically "force" saving activities (get stateRestorationActivity(for scene:) called)?

Rivera
  • 10,792
  • 3
  • 58
  • 102

1 Answers1

0

The problem is that when I'm running the Simulator with two side-by-side scenes and force restart the app by rebuilding the activities are not saved and the UI is not properly restored on relaunch.

What you're seeing when you "force restart the app by rebuilding" is the expected behavior. When you force restart like that, the app does not have a chance to save your NSUserActivities. Per Apple's state restoration tutorial:

If you want to test your app’s ability to restore its state, do not use the app switcher to kill the the app during debugging. Instead, use Xcode to kill the app, or kill the app programmatically. One technique is to suspend your app using the Home button, and then stop the debugger in Xcode. When you launch the app again using Xcode, UIKit initiates the state restoration process.

I understand that you weren't killing the app in the switcher, but any "forced" stop will disable state restoration (with a caveat). To test state restoration, instead use the technique suggested by Apple's tutorial above.

Would this mean that a crash of my app would prevent saving these activities leading to an inconsistent UI state on relaunch?

I think so. This is the caveat from earlier. While Apple says that killing the app (whether in the app switcher or from a crash or whatever) will disable state restoration, this is not necessarily true. You can see for yourself that Apple's own apps have odd state restoration inconsistencies when killed in the app switcher and re-opened (you may have to try it a few times to get inconsistent behavior). While I haven't tested this, I'd imagine that those same inconsistencies can occur from app crashes.

  • Nice sum up. Now the question would be, how can I manually trigger the saving of states? – Rivera Jul 01 '20 at 13:24
  • 1
    I don't think that we can. It seems like UIKit is responsible for calling `stateRestorationActivity(for:)` when the system deems it appropriate and storing the return value on disk. That process seems to be hidden by Apple's API. We may have to accept the occasional inconsistency in state restoration. – throwaway390384085 Jul 02 '20 at 20:24
  • I was playing with this in a sandbox app and it seems to me that you can increase the chance of keeping the user activity updated by continuously updating the window scene's user activity (for example, I store the latest text field text with every key stroke). From my observation it seems to minimize the chance of loosing state because of rebuilding from Xcode. I haven't test the case where a crash occurs. – alobaili Mar 12 '22 at 18:26