Repository: beeware/toga

Issue:
Crash when displaying InfoDialog on iOS
### Describe the bug

InfoDialog could not be called from a Button on iOS

### Steps to reproduce

1. Run the `dialogs` example
2. Click on any of the buttons that display a dialog 
3. See error:

```
Traceback (most recent call last):
  File "/Users/carstenschmidt/Library/Developer/CoreSimulator/Devices/DDAB8D40-4B82-42E8-840A-DAC5BA41273C/data/Containers/Bundle/Application/4EBA5383-22B3-4BF3-B5A9-4E0DB9B3F918/ToolBox.app/app_packages/rubicon/objc/api.py", line 334, in __call__
    result = self.py_method(py_self, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/carstenschmidt/Library/Developer/CoreSimulator/Devices/DDAB8D40-4B82-42E8-840A-DAC5BA41273C/data/Containers/Bundle/Application/4EBA5383-22B3-4BF3-B5A9-4E0DB9B3F918/ToolBox.app/app_packages/toga_iOS/widgets/button.py", line 22, in onPress_
    self.interface.on_press(None)
  File "/Users/carstenschmidt/Library/Developer/CoreSimulator/Devices/DDAB8D40-4B82-42E8-840A-DAC5BA41273C/data/Containers/Bundle/Application/4EBA5383-22B3-4BF3-B5A9-4E0DB9B3F918/ToolBox.app/app_packages/toga/handlers.py", line 65, in _handler
    result = handler(interface, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/carstenschmidt/Library/Developer/CoreSimulator/Devices/DDAB8D40-4B82-42E8-840A-DAC5BA41273C/data/Containers/Bundle/Application/4EBA5383-22B3-4BF3-B5A9-4E0DB9B3F918/ToolBox.app/app/toolbox/app.py", line 624, in show_not_function
    self.main_window.info_dialog(
  File "/Users/carstenschmidt/Library/Developer/CoreSimulator/Devices/DDAB8D40-4B82-42E8-840A-DAC5BA41273C/data/Containers/Bundle/Application/4EBA5383-22B3-4BF3-B5A9-4E0DB9B3F918/ToolBox.app/app_packages/toga/window.py", line 287, in info_dialog
    self.factory.dialogs.InfoDialog(
  File "/Users/carstenschmidt/Library/Developer/CoreSimulator/Devices/DDAB8D40-4B82-42E8-840A-DAC5BA41273C/data/Containers/Bundle/Application/4EBA5383-22B3-4BF3-B5A9-4E0DB9B3F918/ToolBox.app/app_packages/toga_iOS/dialogs.py", line 83, in __init__
    super().__init__(interface, title, message, on_result=on_result)
  File "/Users/carstenschmidt/Library/Developer/CoreSimulator/Devices/DDAB8D40-4B82-42E8-840A-DAC5BA41273C/data/Containers/Bundle/Application/4EBA5383-22B3-4BF3-B5A9-4E0DB9B3F918/ToolBox.app/app_packages/toga_iOS/dialogs.py", line 31, in __init__
    interface.window._impl.controller.presentViewController(
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'MainWindow' object has no attribute 'controller'
```

### Expected behavior

InfoDialog should be displayed.

### Screenshots

I believe this is not needed

### Environment

- Operating System: iOS
- Python version: any
- Software versions:
  - Briefcase: 0.3.15
  - Toga: 5d9a077345d34018342944199212fb7861d8d772 (0.3.1+)
  - ...


### Logs

```

```


### Additional context

This problem was introduced by #1969. The fix is relatively simple:
```
diff --git a/iOS/src/toga_iOS/dialogs.py b/iOS/src/toga_iOS/dialogs.py
index a0a8bce38..1448bf8fa 100644
--- a/iOS/src/toga_iOS/dialogs.py
+++ b/iOS/src/toga_iOS/dialogs.py
@@ -28,7 +28,7 @@ class AlertDialog(BaseDialog):
 
         self.populate_dialog()
 
-        interface.window._impl.controller.presentViewController(
+        interface.window._impl.native.rootViewController.presentViewController(
             self.native,
             animated=False,
             completion=None,
```


Discussion:
I will have a look at this :-)

Resolving patch:
diff --git a/iOS/src/toga_iOS/dialogs.py b/iOS/src/toga_iOS/dialogs.py
--- a/iOS/src/toga_iOS/dialogs.py
+++ b/iOS/src/toga_iOS/dialogs.py
@@ -28,7 +28,7 @@ def __init__(self, interface, title, message, on_result=None):
 
         self.populate_dialog()
 
-        interface.window._impl.controller.presentViewController(
+        interface.window._impl.native.rootViewController.presentViewController(
             self.native,
             animated=False,
             completion=None,


Test patch: