I'm building an iOS app in SwiftUI and hoping to run it on the Mac using Catalyst as well. I've added a keyboard shortcut CMD+N
using UIKeyCommand
on the main hosting controller, which fires a Notification
that my ObservableObject model listens to, toggling an alert property to show an alert. Here's the code:
class KeyCommandHostingController<Content: View>: UIHostingController<Content> {
override var keyCommands: [UIKeyCommand]? {
[
UIKeyCommand(title: "New Game", action: #selector(postNewGame), input: "n", modifierFlags: .command)
]
}
@objc func postNewGame() {
print("postNewGame called")
NotificationCenter.default.post(name: .newGameRequested, object: nil)
}
}
public extension Notification.Name {
static let newGameRequested = Notification.Name(rawValue: "newGameRequested")
}
class Model: ObservableObject {
@Published var presentAlert = false
var cancellables = Set<AnyCancellable>()
init() {
NotificationCenter.default
.publisher(for: .newGameRequested)
.sink { [unowned self] _ in
self.presentAlert.toggle()
print("new game requested")
}
.store(in: &cancellables)
}
}
struct ContentView: View {
@ObservedObject var model: Model
var body: some View {
Text("Hello, World!")
.alert(isPresented: $model.presentAlert) {
Alert(title: Text("New Game"),
message: Text("Are you sure you want to start a new game? The current game will be recorded as a loss."),
primaryButton: Alert.Button.destructive(Text("New Game")) {
print("New Game selected")
},
secondaryButton: Alert.Button.cancel()
)
}
}
}
When I execute the keyboard command in iPhone or iPad simulator, this behaves correctly - one notification is fired, and the alert is shown. However, in the Mac Catalyst app, hitting the keyboard shortcut once causes the notification to be endlessly fired, which causes the app to attempt to endlessly show the alert over and over. The console output confirms it, with the following infinite output (snipped):
new game requested
postNewGame called
new game requested
postNewGame called
new game requested
postNewGame called
new game requested
2020-03-29 14:04:11.179475-0400 AlertMadness[1332:29452] Warning: Attempt to present <SwiftUI.PlatformAlertController: 0x10192de00> on <_TtGC12AlertMadness27KeyCommandHostingControllerVS_11ContentView_: 0x10310bcf0> while a presentation is in progress!
postNewGame called
new game requested
postNewGame called
new game requested
postNewGame called
new game requested
postNewGame called
new game requested
2020-03-29 14:04:11.595161-0400 AlertMadness[1332:29452] Warning: Attempt to present <SwiftUI.PlatformAlertController: 0x10195ca00> on <_TtGC12AlertMadness27KeyCommandHostingControllerVS_11ContentView_: 0x10310bcf0> while a presentation is in progress!
(etc...)
Am I doing something wrong, or is this a bug in Catalyst/SwiftUI? Using Xcode 11.4 and macOS 10.15.4.