xamarin-macios
xamarin-macios copied to clipboard
XIB files are not copied from the referenced executable project
Apple platform
macOS
Framework version
net8.0-, net9.0-
Affected platform version
.net 9.0.203
Description
Note: I'm not sure if this should be fixed. However, it may be reasonable to add a compile-time error or warning.
During quick prototyping, I accidentally referenced the executable project instead of the class library. I was able to successfully reuse the code from this project, but I was not able to use the xib-s interface definitions because xib files was not copied to the final app bundle.
The expected behavior may be one of the following
- copy the xib files from all referenced projects;
- do not allow references to executable projects. Add the corresponding compiler warning or error.
Additional notes
I believe that is pretty strange to reference the executable project, but there are a few nuances:
- tooling (xcsync, Rider) can't handle the UI in the class libraries. The corresponding classes are simply not visible in XCode when the "Edit with XCode" action. So, some people may try to reference executable projects to workaround the tooling issues.
- IDE hotfixes.I encountered this issue after the Rider told me something like "Foo is undefined. Let's reference the AnotherApp.csproj and add the missing using directives to fix this".
Steps to Reproduce
-
Open test project UiFromExecutable.zip
-
run the
AppToReferenceproject and make sure it run and works - you can see theNSCollectionViewwith a buttons (one button for each collection item) -
run the
UiFromClassLiband find the exception telling "could not dequeue an item of kind: NSCollectionElementKindItem with identifier MyItem - must register a nib or a class for the identifier, or name a nib or class to match the identifier"Full exception text
ObjCRuntime.ObjCException: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: could not dequeue an item of kind: NSCollectionElementKindItem with identifier MyItem - must register a nib or a class for the identifier, or name a nib or class to match the identifier Native stack trace: 0 CoreFoundation 0x000000018a14727c __exceptionPreprocess + 176 1 libobjc.A.dylib 0x0000000189c2a158 objc_exception_throw + 60 2 Foundation 0x000000018b2bb1cc -[NSCalendarDate initWithCoder:] + 0 3 AppKit 0x000000018e3bb2e4 -[_NSCollectionViewCore _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 1244 4 AppKit 0x000000018e3bbd84 -[_NSCollectionViewCore dequeueReusableItemWithReuseIdentifier:forIndexPath:] + 84 5 AppKit 0x000000018dacf678 -[NSCollectionView makeItemWithIdentifier:forIndexPath:] + 88 6 UiFromClassLib 0x000000010416b2d0 xamarin_dyn_objc_msgSend + 160 7 ??? 0x00000003012701e8 0x0 + 12904235496 8 ??? 0x000000030126fbb0 0x0 + 12904233904 9 ??? 0x000000030126f974 0x0 + 12904233332 10 ??? 0x0000000301853874 0x0 + 12910409844 11 ??? 0x0000000300492e18 0x0 + 12889697816 12 ??? 0x00000003004ad234 0x0 + 12889805364 13 ??? 0x0000000301257918 0x0 + 12904134936 14 ??? 0x0000000301256e64 0x0 + 12904132196 15 ??? 0x0000000301256ccc 0x0 + 12904131788 16 UiFromClassLib 0x0000000104154b54 xamarin_bridge_runtime_invoke_method + 132 17 UiFromClassLib 0x00000001041665f4 mono_runtime_invoke + 72 18 UiFromClassLib 0x0000000104163fa8 xamarin_invoke_trampoline + 6072 19 UiFromClassLib 0x000000010416a3c0 xamarin_arch_trampoline + 148 20 UiFromClassLib 0x000000010416b1a4 xamarin_arm64_common_trampoline + 64 21 AppKit 0x000000018dacf508 -[_NSCollectionViewDataSourceAdapter collectionView:itemForRepresentedObjectAtIndexPath:] + 220 22 AppKit 0x000000018e3afaf8 -[_NSCollectionViewCore _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 100 23 AppKit 0x000000018e3b24c8 -[_NSCollectionViewCore _updateVisibleCellsNow:] + 3156 24 AppKit 0x000000018e3b6204 -[_NSCollectionViewCore _layoutItems] + 212 25 AppKit 0x000000018dac3138 -[NSCollectionView layout] + 304 26 AppKit 0x000000018e3dfe30 ___NSViewLayout_block_invoke + 592 27 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 28 AppKit 0x000000018d97903c _NSViewLayout + 96 29 AppKit 0x000000018e3d64dc __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 364 30 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 31 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 32 AppKit 0x000000018e3d6620 __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 688 33 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 34 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 35 AppKit 0x000000018e3d6620 __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 688 36 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 37 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 38 AppKit 0x000000018e3d6620 __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 688 39 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 40 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 41 AppKit 0x000000018e3d6620 __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 688 42 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 43 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 44 AppKit 0x000000018e3d6fc4 __56-[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:]_block_invoke + 796 45 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 46 AppKit 0x000000018d978b90 -[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:] + 100 47 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 48 AppKit 0x000000018d978b20 -[NSView layoutSubtreeIfNeeded] + 96 49 AppKit 0x000000018e681850 -[NSWindow(NSConstraintBasedLayoutInternal) _layoutViewTree] + 104 50 AppKit 0x000000018e6819d8 -[NSWindow(NSConstraintBasedLayoutInternal) layoutIfNeeded] + 240 51 AppKit 0x000000018d9d7754 __NSWindowGetDisplayCycleObserverForLayout_block_invoke + 364 52 AppKit 0x000000018d9d6cec NSDisplayCycleObserverInvoke + 168 53 AppKit 0x000000018d9d6948 NSDisplayCycleFlush + 644 54 QuartzCore 0x00000001922ca76c _ZN2CA11Transaction19run_commit_handlersE18CATransactionPhase + 120 55 QuartzCore 0x00000001922c950c _ZN2CA11Transaction6commitEv + 320 56 AppKit 0x000000018da5aac8 __62+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayLink]_block_invoke + 272 57 AppKit 0x000000018e41b4e4 ___NSRunLoopObserverCreateWithHandler_block_invoke + 64 58 CoreFoundation 0x000000018a0d180c __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36 59 CoreFoundation 0x000000018a0d16f8 __CFRunLoopDoObservers + 536 60 CoreFoundation 0x000000018a0d0d24 __CFRunLoopRun + 776 61 CoreFoundation 0x000000018a0d03c4 CFRunLoopRunSpecific + 608 62 HIToolbox 0x000000019487d19c RunCurrentEventLoopInMode + 292 63 HIToolbox 0x000000019487ce2c ReceiveNextEventCommon + 220 64 HIToolbox 0x000000019487cd30 _BlockUntilNextEventMatchingListInModeWithFilter + 76 65 AppKit 0x000000018d931cc8 _DPSNextEvent + 660 66 AppKit 0x000000018e1284d0 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 700 67 AppKit 0x000000018d924ffc -[NSApplication run] + 476 68 AppKit 0x000000018d8fc240 NSApplicationMain + 880 69 ??? 0x000000030125319c 0x0 + 12904116636 70 ??? 0x0000000301252e90 0x0 + 12904115856 71 ??? 0x000000030124aa20 0x0 + 12904081952 72 libcoreclr.dylib 0x0000000105dabab8 CallDescrWorkerInternal + 132 73 libcoreclr.dylib 0x0000000105c2f794 _ZN18MethodDescCallSite16CallTargetWorkerEPKyPyi + 832 74 libcoreclr.dylib 0x0000000105b33a9c _Z7RunMainP10MethodDescsPiPP8PtrArray + 624 75 libcoreclr.dylib 0x0000000105b33df8 _ZN8Assembly17ExecuteMainMethodEPP8PtrArrayi + 268 76 libcoreclr.dylib 0x0000000105b5843c _ZN8CorHost215ExecuteAssemblyEjPKDsiPS1_Pj + 640 77 libcoreclr.dylib 0x0000000105b234b4 coreclr_execute_assembly + 232 78 UiFromClassLib 0x0000000104166318 mono_jit_exec + 204 79 UiFromClassLib 0x000000010416a274 xamarin_main + 884 80 UiFromClassLib 0x000000010420aac8 main + 64 81 dyld 0x0000000189c67154 start + 2476 at ObjCRuntime.Messaging.NativeHandle_objc_msgSend_NativeHandle_NativeHandle(IntPtr receiver, IntPtr selector, NativeHandle arg1, NativeHandle arg2) at AppKit.NSCollectionView.MakeItem(String identifier, NSIndexPath indexPath) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/build/dotnet/macos/generated-sources/AppKit/NSCollectionView.g.cs:line 865 at AppToReference.TestCollectionViewDataSource.GetItem(NSCollectionView collectionView, NSIndexPath indexPath) in /Users/sergey/Downloads/UiFromClassLib/Shared/TestCollectionViewDataSource.cs:line 51 at InvokeStub_TestCollectionViewDataSource.GetItem(Object, Span`1) at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) Native stack trace: 0 CoreFoundation 0x000000018a14727c __exceptionPreprocess + 176 1 libobjc.A.dylib 0x0000000189c2a158 objc_exception_throw + 60 2 Foundation 0x000000018b2bb1cc -[NSCalendarDate initWithCoder:] + 0 3 AppKit 0x000000018e3bb2e4 -[_NSCollectionViewCore _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 1244 4 AppKit 0x000000018e3bbd84 -[_NSCollectionViewCore dequeueReusableItemWithReuseIdentifier:forIndexPath:] + 84 5 AppKit 0x000000018dacf678 -[NSCollectionView makeItemWithIdentifier:forIndexPath:] + 88 6 UiFromClassLib 0x000000010416b2d0 xamarin_dyn_objc_msgSend + 160 7 ??? 0x00000003012701e8 0x0 + 12904235496 8 ??? 0x000000030126fbb0 0x0 + 12904233904 9 ??? 0x000000030126f974 0x0 + 12904233332 10 ??? 0x0000000301853874 0x0 + 12910409844 11 ??? 0x0000000300492e18 0x0 + 12889697816 12 ??? 0x00000003004ad234 0x0 + 12889805364 13 ??? 0x0000000301257918 0x0 + 12904134936 14 ??? 0x0000000301256e64 0x0 + 12904132196 15 ??? 0x0000000301256ccc 0x0 + 12904131788 16 UiFromClassLib 0x0000000104154b54 xamarin_bridge_runtime_invoke_method + 132 17 UiFromClassLib 0x00000001041665f4 mono_runtime_invoke + 72 18 UiFromClassLib 0x0000000104163fa8 xamarin_invoke_trampoline + 6072 19 UiFromClassLib 0x000000010416a3c0 xamarin_arch_trampoline + 148 20 UiFromClassLib 0x000000010416b1a4 xamarin_arm64_common_trampoline + 64 21 AppKit 0x000000018dacf508 -[_NSCollectionViewDataSourceAdapter collectionView:itemForRepresentedObjectAtIndexPath:] + 220 22 AppKit 0x000000018e3afaf8 -[_NSCollectionViewCore _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 100 23 AppKit 0x000000018e3b24c8 -[_NSCollectionViewCore _updateVisibleCellsNow:] + 3156 24 AppKit 0x000000018e3b6204 -[_NSCollectionViewCore _layoutItems] + 212 25 AppKit 0x000000018dac3138 -[NSCollectionView layout] + 304 26 AppKit 0x000000018e3dfe30 ___NSViewLayout_block_invoke + 592 27 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 28 AppKit 0x000000018d97903c _NSViewLayout + 96 29 AppKit 0x000000018e3d64dc __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 364 30 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 31 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 32 AppKit 0x000000018e3d6620 __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 688 33 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 34 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 35 AppKit 0x000000018e3d6620 __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 688 36 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 37 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 38 AppKit 0x000000018e3d6620 __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 688 39 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 40 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 41 AppKit 0x000000018e3d6620 __36-[NSView _layoutSubtreeWithOldSize:]_block_invoke + 688 42 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 43 AppKit 0x000000018d978fd0 -[NSView _layoutSubtreeWithOldSize:] + 100 44 AppKit 0x000000018e3d6fc4 __56-[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:]_block_invoke + 796 45 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 46 AppKit 0x000000018d978b90 -[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:] + 100 47 AppKit 0x000000018d9748fc NSPerformVisuallyAtomicChange + 108 48 AppKit 0x000000018d978b20 -[NSView layoutSubtreeIfNeeded] + 96 49 AppKit 0x000000018e681850 -[NSWindow(NSConstraintBasedLayoutInternal) _layoutViewTree] + 104 50 AppKit 0x000000018e6819d8 -[NSWindow(NSConstraintBasedLayoutInternal) layoutIfNeeded] + 240 51 AppKit 0x000000018d9d7754 __NSWindowGetDisplayCycleObserverForLayout_block_invoke + 364 52 AppKit 0x000000018d9d6cec NSDisplayCycleObserverInvoke + 168 53 AppKit 0x000000018d9d6948 NSDisplayCycleFlush + 644 54 QuartzCore 0x00000001922ca76c _ZN2CA11Transaction19run_commit_handlersE18CATransactionPhase + 120 55 QuartzCore 0x00000001922c950c _ZN2CA11Transaction6commitEv + 320 56 AppKit 0x000000018da5aac8 __62+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayLink]_block_invoke + 272 57 AppKit 0x000000018e41b4e4 ___NSRunLoopObserverCreateWithHandler_block_invoke + 64 58 CoreFoundation 0x000000018a0d180c __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36 59 CoreFoundation 0x000000018a0d16f8 __CFRunLoopDoObservers + 536 60 CoreFoundation 0x000000018a0d0d24 __CFRunLoopRun + 776 61 CoreFoundation 0x000000018a0d03c4 CFRunLoopRunSpecific + 608 62 HIToolbox 0x000000019487d19c RunCurrentEventLoopInMode + 292 63 HIToolbox 0x000000019487ce2c ReceiveNextEventCommon + 220 64 HIToolbox 0x000000019487cd30 _BlockUntilNextEventMatchingListInModeWithFilter + 76 65 AppKit 0x000000018d931cc8 _DPSNextEvent + 660 66 AppKit 0x000000018e1284d0 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 700 67 AppKit 0x000000018d924ffc -[NSApplication run] + 476 68 AppKit 0x000000018d8fc240 NSApplicationMain + 880 69 ??? 0x000000030125319c 0x0 + 12904116636 70 ??? 0x0000000301252e90 0x0 + 12904115856 71 ??? 0x000000030124aa20 0x0 + 12904081952 72 libcoreclr.dylib 0x0000000105dabab8 CallDescrWorkerInternal + 132 73 libcoreclr.dylib 0x0000000105c2f794 _ZN18MethodDescCallSite16CallTargetWorkerEPKyPyi + 832 74 libcoreclr.dylib 0x0000000105b33a9c _Z7RunMainP10MethodDescsPiPP8PtrArray + 624 75 libcoreclr.dylib 0x0000000105b33df8 _ZN8Assembly17ExecuteMainMethodEPP8PtrArrayi + 268 76 libcoreclr.dylib 0x0000000105b5843c _ZN8CorHost215ExecuteAssemblyEjPKDsiPS1_Pj + 640 77 libcoreclr.dylib 0x0000000105b234b4 coreclr_execute_assembly + 232 78 UiFromClassLib 0x0000000104166318 mono_jit_exec + 204 79 UiFromClassLib 0x000000010416a274 xamarin_main + 884 80 UiFromClassLib 0x000000010420aac8 main + 64 81 dyld 0x0000000189c67154 start + 2476 -
inspect app bundle content
./UiFromClassLib/UiFromClassLib/bin/Debug/net9.0-macos/osx-arm64/UiFromClassLib.app/Contents/Resourcesand find thatMyItem.xibdoes not exists here (but exists in the app bundle for theAppToReference -
Note that in the
UiFromClassLib.ViewControllerwe explicitly referencing/instantiating theTestCollectionViewDataSourcetype from theAppToReference, so compiler should not optimize out the whole assembly.
Did you find any workaround?
All works fine if all the UI will be in the current executable project or in the class library. Just do not try to reuse UI from the other executable project.
Build logs
Additionally, even if I copy MyItem.xib to the destination project (UiFromClassLib), the app still won't run because the MyItem obj-c class (not xib) cannot be found. It looks like registrar does not register types from the referenced executable project. I'm not sure if this is a separate issue or just another case of the general rule "do not reference executables".
I can reproduce this.
The reason the resources aren't collected from the executable project reference, is that we only collect resources from projects that aren't apps or app extensions:
https://github.com/dotnet/macios/blob/26b2e27a7f587b8907b69034c455419631d38e97/msbuild/Xamarin.Shared/Xamarin.Shared.targets#L2072
This is by design, and I don't think it should change (it would either involve increasing the app size for all apps with resources, because the resources would be included there, or it would require us to build executable projects differently depending on whether they're referenced elsewhere or not, which sounds like a bad idea).
It looks doable to create a warning/error though, it would probably involve something like this:
- Add
OutputTypeto theAdditionalPropertiesFromProjectitem group. - Add a target that checks
_MSBuildProjectReferenceExistentfor references to executable projects / app projects (note that we have to allow references to app extensions, because that's how we attach app extensions to apps). An escape hatch would be nice. - Add a test!
This doesn't sound like it's affecting a lot of people though, so unless that changes it won't have a high priority to get it fixed.
Thanks for the excellent bug report!