Since Xcode 12.5, I am seeing a lot of "Unable to present. Please file a bug." console logs in the Xcode console which I remember not seeing prior to 12.5.
This message is shown when I am using NavigationLink
from a parent view to navigate to a child view, and if logic in the child view updates one of the states that parent view depends on.
Below is a sample pseudo code where a list of messages are shown in the parent view, message detail is shown in the child view from a list, and lastly, independent settings child view.
struct MessageListView: View {
...
@StateObject var messageList = MessageList()
var body: some View {
debugPrint("!!MessageListView has been redrawn!!")
return VStack {
NavigationLink(destination:SettingsView()){
Text("Go to settings")
}
ForEach(messageList.data.sorted(by: {$0.key < $1.key}), id:\.key) { k, m in
NavigationLink(destination:MessageView(message:...){
Text(m.text)
}
}
}
}
}
struct MessageView: View {
...
@ObservedObject var messageList : MessageList
@ObservedObject var message : Message
...
var body: some View {
Text(...)
.onAppear {
messageList.readAndIncrement(message.id) //<- This updates both this view & parent view.
}
}
}
class MessageList : ObservableObject {
@Published var data : [String:Message] = [:]
func readAndIncrement(id: String){
//Modify one of the message in dictionary.
}
}
So when user clicks on message and traverses the navigation like below,
MessageListView -> MessageView
As soon as MessageView
appears on screen, it will increment message's "read count" due to at the logic in onAppear
, which will update data in MessageListView
at the same time.
As soon as that happens, it appears that the parent view, MessageListView
which is observing MessageList objects gets updated, the two following things happen.
debugPrint
will print message!!MessageListView has been redrawn!!
(from source code above) on console, which proves that the parent view has been updated while Navigation is currently showing child view.- 'Unable to present. Please file a bug.' console log gets shown on screen, probably because the update in the parent view "cannot" be presented on screen?
So SwiftUI seems to be throwing "Unable to present" error log when I am updating parent view's observed data while viewing & interacting in the child view, but I am unsure how I can properly fix to get rid of this error.
The reason that I am thinking this is not a bug, but my error is because of the following.
When user traverses into a completely different view, something like
MessageListView -> SettingsView
and if the following two conditions are met,
- The child view (SettingsView) does not use or rely on any of the parent view's state objects.
- Parent view's data model is updated by other means, such as from network updates/sync, periodic refresh, etc.
then the parent view (MessageListView) gets redrawn for its dependent model's every single update and the child view starts stacking itself like below.
At least, in the above case, Unable to present. Please file a bug.
doesn't get shown in the console.
In the iOS 14.5 & Xcode 12.5 patch notes, the only comments related to NavigationLink
is as follows, but that does not seem to be relevant to my case.
The destination of NavigationLink that only differs by local state now resets that state when switching between links as expected. (72117345)
So my question is... how can I properly manage states (or decouple them) in this case that won't cause funkiness in SwiftUI Navigation?
Is it against SwiftUI's paradigm to update parent view's state data while presenting child view on screen or is this simply a NavigationLink
bug in Xcode 12.5?