Seems solve issue for me. This is my answer.
First, write method below which can get VoiceShortcut object with UserActivity's Identifier if any.
private func getShortcut(id: String, completion: ((INVoiceShortcut?) -> Void)?) {
INVoiceShortcutCenter.shared.getAllVoiceShortcuts { (shortcuts, error) in
let result = shortcuts?.filter { $0.shortcut.userActivity?.persistentIdentifier == id }.first
completion?(result)
}
}
Next, we should call present(editVoiceShortcutViewController) but not present(addVoiceShortcutViewController) in func present(_ addVoiceShortcutViewController: INUIAddVoiceShortcutViewController, for addVoiceShortcutButton: INUIAddVoiceShortcutButton).
We need VoiceShortcut object to instantiate INUIEditVoiceShortcutViewController. So we need to wait until the shortcut's generated by system.
In my code, delayed 300 milli sec, I don't think this is the best way to solve the issue.
func present(_ addVoiceShortcutViewController: INUIAddVoiceShortcutViewController,
for addVoiceShortcutButton: INUIAddVoiceShortcutButton) {
addVoiceShortcutViewController.delegate = self
// do not call this !!! // present(addVoiceShortcutViewController, animated: true)
let id = addVoiceShortcutButton.shortcut!.userActivity!.persistentIdentifier!
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
self.getShortcut(id: id) { sc in
if let sc = sc {
DispatchQueue.main.async {
let vc = INUIEditVoiceShortcutViewController(voiceShortcut: sc)
self.present(vc, for: addVoiceShortcutButton)
}
} else {
fatalError()
}
}
}
Remember this code is for iOS 15. If you support iOS 14, just call previous present(addVoiceShortcutViewController).
I still don't figure out this is the best solution and need to keep watching another iOS beta version.