Mvvmcross: Mac playground compiles but doesn't show any windows

Created on 28 Sep 2019  路  5Comments  路  Source: MvvmCross/MvvmCross

馃敊 Regression

Hello! I'm starting with MvvmCross for Xamarin.Mac and discovered that its Playground doesn't work correctly.

Current behavior

The app appears in the dock and the program hits a breakpoint in ViewDidLoad() in RootView.cs. But no window is displayed.

There are some errors: "Language file could not be loaded for " and "MvxIoCResolveException: Failed to resolve type MvvmCross.Base.IMvxJsonConverter" but I don't think that they are relevant to the issue: application_output.txt

Reproduction steps

Run Playground.Mac

Configuration

Version: 6.4.0 [latest develop], VS4Mac 8.3, macOS Mojave 10.14.6

Platform:

  • [ ] :iphone: iOS
  • [ ] :robot: Android
  • [ ] :checkered_flag: WPF
  • [ ] :earth_americas: UWP
  • [x] :apple: MacOS
  • [ ] :tv: tvOS
  • [ ] :monkey: Xamarin.Forms
mac bug

All 5 comments

A quick fix for this is in RootView remove the IMvxOverridePresentationAttribute interface.

Thank you! Got it running and found a few other issues:

Show Child

Does not navigate to a child view but if pressed for the second time, logs the following:
[INFO] (MvvmCross.Logging.MvxLog) MvxAsyncCommand : execute ignored, already running.

Show Modal

If pressed right after the app's start, then produces NullReferenceException (see the log below). But if "Show Child" was pressed first, then the modal shows but it seems that it's too large.

image

System.NullReferenceException: Object reference not set to an instance of an object
  at MvvmCross.Platforms.Mac.Presenters.MvxMacViewPresenter.ShowModalViewController (AppKit.NSViewController viewController, MvvmCross.Platforms.Mac.Presenters.Attributes.MvxModalPresentationAttribute attribute, MvvmCross.ViewModels.MvxViewModelRequest request) [0x00035] in /Users/Q/Sources/MvvmCross/MvvmCross/Platforms/Mac/Presenters/MvxMacViewPresenter.cs:229
  at MvvmCross.Platforms.Mac.Presenters.MvxMacViewPresenter.<RegisterAttributeTypes>b__8_4 (System.Type viewType, MvvmCross.Platforms.Mac.Presenters.Attributes.MvxModalPresentationAttribute attribute, MvvmCross.ViewModels.MvxViewModelRequest request) [0x0000e] in /Users/Q/Sources/MvvmCross/MvvmCross/Platforms/Mac/Presenters/MvxMacViewPresenter.cs:92
  at MvvmCross.Presenters.MvxPresentationAttributeExtensions+<>c__DisplayClass4_0`1[TMvxPresentationAttribute].<Register>b__0 (System.Type view, MvvmCross.Presenters.Attributes.IMvxPresentationAttribute attribute, MvvmCross.ViewModels.MvxViewModelRequest request) [0x00000] in /Users/Q/Sources/MvvmCross/MvvmCross/Presenters/MvxPresentationAttributeExtensions.cs:56
  at MvvmCross.Presenters.MvxAttributeViewPresenter.Show (MvvmCross.ViewModels.MvxViewModelRequest request) [0x00001] in /Users/Q/Sources/MvvmCross/MvvmCross/Presenters/MvxAttributeViewPresenter.cs:175
  at MvvmCross.Platforms.Mac.Views.MvxMacViewDispatcher+<>c__DisplayClass2_0.<ShowViewModel>b__0 () [0x0001f] in /Users/Q/Sources/MvvmCross/MvvmCross/Platforms/Mac/Views/MvxMacViewDispatcher.cs:30
  at MvvmCross.Base.MvxMainThreadAsyncDispatcher+<>c__DisplayClass1_0.<ExecuteOnMainThreadAsync>b__0 () [0x0000f] in /Users/Q/Sources/MvvmCross/MvvmCross/Base/MvxMainThreadAsyncDispatcher.cs:27
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
  at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00002] in /Library/Frameworks/Xamarin.Mac.framework/Versions/6.2.0.42/src/Xamarin.Mac/Foundation/NSAction.cs:178

Show Sheet

Also produces NullReferenceException if "Show Child" wasn't pressed (see the log below) but if it was, then shows the Child window in a new window and a sheet inside it. Pressing "Show Root" creates a third window instead of going back:

image

System.NullReferenceException: Object reference not set to an instance of an object
  at MvvmCross.Platforms.Mac.Presenters.MvxMacViewPresenter.ShowSheetViewController (AppKit.NSViewController viewController, MvvmCross.Platforms.Mac.Presenters.Attributes.MvxSheetPresentationAttribute attribute, MvvmCross.ViewModels.MvxViewModelRequest request) [0x00035] in /Users/Q/Sources/MvvmCross/MvvmCross/Platforms/Mac/Presenters/MvxMacViewPresenter.cs:240
  at MvvmCross.Platforms.Mac.Presenters.MvxMacViewPresenter.<RegisterAttributeTypes>b__8_6 (System.Type viewType, MvvmCross.Platforms.Mac.Presenters.Attributes.MvxSheetPresentationAttribute attribute, MvvmCross.ViewModels.MvxViewModelRequest request) [0x0000e] in /Users/Q/Sources/MvvmCross/MvvmCross/Platforms/Mac/Presenters/MvxMacViewPresenter.cs:100
  at MvvmCross.Presenters.MvxPresentationAttributeExtensions+<>c__DisplayClass4_0`1[TMvxPresentationAttribute].<Register>b__0 (System.Type view, MvvmCross.Presenters.Attributes.IMvxPresentationAttribute attribute, MvvmCross.ViewModels.MvxViewModelRequest request) [0x00000] in /Users/Q/Sources/MvvmCross/MvvmCross/Presenters/MvxPresentationAttributeExtensions.cs:56
  at MvvmCross.Presenters.MvxAttributeViewPresenter.Show (MvvmCross.ViewModels.MvxViewModelRequest request) [0x00001] in /Users/Q/Sources/MvvmCross/MvvmCross/Presenters/MvxAttributeViewPresenter.cs:175
  at MvvmCross.Platforms.Mac.Views.MvxMacViewDispatcher+<>c__DisplayClass2_0.<ShowViewModel>b__0 () [0x0001f] in /Users/Q/Sources/MvvmCross/MvvmCross/Platforms/Mac/Views/MvxMacViewDispatcher.cs:30
  at MvvmCross.Base.MvxMainThreadAsyncDispatcher+<>c__DisplayClass1_0.<ExecuteOnMainThreadAsync>b__0 () [0x0000f] in /Users/Q/Sources/MvvmCross/MvvmCross/Base/MvxMainThreadAsyncDispatcher.cs:27
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
  at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00002] in /Library/Frameworks/Xamarin.Mac.framework/Versions/6.2.0.42/src/Xamarin.Mac/Foundation/NSAction.cs:178

Show Window

Doesn't work other than tracing (MvvmCross.Logging.MvxLog) MacNavigation.

Show Tabs

Crashes the app, probably because of not being able to pick the tabs from the storyboard?

Playground.Mac[24274:2395869] *** Assertion failure in -[Playground_Mac_TabsRootView setSelectedTabViewItemIndex:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1671.60.109/Controllers/NSTabViewController.m:760
Playground.Mac[24274:2395869] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Selected index (0) is outside of the valid bounds (0 - 0)'
*** First throw call stack:
(
  0   CoreFoundation                      0x00007fff32072b79 __exceptionPreprocess + 256
  1   libobjc.A.dylib                     0x00007fff5c7eb3c6 objc_exception_throw + 48
  2   CoreFoundation                      0x00007fff3208db7a +[NSException raise:format:arguments:] + 98
  3   Foundation                          0x00007fff3434b791 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 194
  4   AppKit                              0x00007fff2f86586f -[NSTabViewController setSelectedTabViewItemIndex:] + 1098
  5   Playground.Mac                      0x000000010ae6f42c xamarin_dyn_objc_msgSendSuper + 220
  6   ???                                 0x0000000114882488 0x0 + 4639433864
)

Sorry, dunno what the state is of the Playground on macOS.

The Playground isn't a sample and is just used for developing and trying out stuff. Don't use it as a reference.

If you have time, feel free to fix it and make a Pull Request.

I debugged the issue: the source of the problem was another NSWindow with null for Identifier. NSApplication.SharedApplication.Windows.ToList() contains the following:

  1. {{X=200,Y=1000,Width=1024,Height=790}}, id null
  2. {{X=300,Y=200,Width=250,Height=272}}, id RootView

When MvxMacViewPresenter was looking for a window in ShowContentViewController(), it was picking that wrong one because MvxContentPresentationAttribute also had null for WindowIdentifier.

The null-id window is created by MvxApplicationDelegate's MainWindow property. The window for RootView is created by ShowWindowViewController() in MvxMacViewPresenter.

Unfortunately, I don't know what would be the right resolution for this: fix the condition in ShowContentViewController() or make ShowWindowViewController() reuse the existing window instead of creating a new one.

(I assume that MvxApplicationDelegate definitely must have a non-null MainWindow property because it calls it in DidFinishLaunching().)

Finally getting back to this and it seems to me that MvxApplicationDelegate shouldn't create an arbitrary-sized window when it can't find one, instead it should receive an already instantiated window from AppDelegate. But I would go even further and remove NSWindow _window from MvxMacSetup because macOS does not require apps to have an active window to avoid being closed.

I will work with Mac Playground to produce some typical Mac use cases and fix the existing issues listed above.

Was this page helpful?
0 / 5 - 0 ratings