microsoftconnect / ms-intune-app-sdk-ios

Intune App SDK for iOS enables data protection and mobile app management features in iOS mobile apps with Microsoft Intune
90 stars 27 forks source link

A System.InvalidOperationException is thrown when adding event handlers to UITextViews #474

Open rpendleton opened 1 week ago

rpendleton commented 1 week ago

Microsoft Intune App SDK for MAUI.iOS Issue

Summary

Describe the bug:

After introducing the Intune App SDK to our .NET for iOS project, our app is encountering exceptions when trying to add event handlers to classes such as UITextView, especially when loaded from storyboards and NIBs. The crash doesn't occur if we remove the Intune SDK from our project.

To Reproduce:

Download and run the attached sample project, or:

  1. Create a .NET for iOS project using dotnet new ios
  2. Add a PackageReference for the Intune App SDK to the .csproj
  3. Create a storyboard containing a UIViewController with a UITextView
  4. Assign a class name to the view controller
  5. Create an outlet from the text view to the view controller
  6. Mark the view controller as the initial view controller for the storyboard
  7. Update the AppDelegate to load the view controller from the storyboard, such as:
    var storyboard = UIStoryboard.FromName("ViewController", null);
    var vc = storyboard.InstantiateInitialViewController();
    Window.RootViewController = vc;
  8. In the view controller's ViewDidLoad, attempt to add an event handler to the UITextView:
    TextView.Started += (sender, args) => Console.WriteLine("TextView.Started");
  9. Build and run the app

Expected behavior: The event handler should be successfully added, and should be invoked when appropriate.

Actual behavior: The app crashes with an exception due to there being an unexpected delegate on the text view.

System.InvalidOperationException: Event registration is overwriting existing delegate. Either just use events or your own delegate: Foundation.NSObject UIKit.UITextView+_UITextViewDelegate
   at UIKit.UIApplication.EnsureEventAndDelegateAreNotMismatched(Object del, Type expectedType) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 118
   at UIKit.UITextView.EnsureUITextViewDelegate() in /Users/builder/azdo/_work/1/s/xamarin-macios/src/build/dotnet/ios/generated-sources/UIKit/UITextView.g.cs:line 2943
   at UIKit.UITextView.add_Started(EventHandler value) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/build/dotnet/ios/generated-sources/UIKit/UITextView.g.cs:line 3076
   at IntuneDelegateEventCrashes.ViewController.ViewDidLoad() in /Users/rpendleton/sd/research/IntuneDelegateEventCrashes/IntuneDelegateEventCrashes/ViewController.cs:line 13

Notes:

When using a debugger, we see that the text view has an unexpected delegate of type CMARnzoANXkfrCWEhqReusTm. From what we can see using lldb and when dumping symbols, this class seems to come from the Intune SDK.

In our case, we're specifically seeing this issue with UITextViews. We're unsure if the Intune SDK uses a similar approach when swizzling other UIKit controls though. If it does, those controls will need to be fixed too.

Details

wangxiaoms commented 1 week ago

Hi, what is your use case, would UITextViewDelegate help your case?

rpendleton commented 1 week ago

We have a fairly large .NET for iOS application, and several customers have requested that we integrate it with the Intune App SDK. However, after doing so, a significant number of our unit tests and UI automation workflows are now encountering this exception.

We are open to investigating a switch to UITextViewDelegate as an alternative to event handlers, but we have some concerns with this. While this change might work for this specific case, we're unsure whether similar changes will be required for other UIKit components, either now or in the future. Refactoring our existing code from event handlers to delegates also comes with some inherent risk, especially if such changes become necessary at unexpected points in the future.

With that in mind, our primary concern is that integrating with the SDK caused issues with something as fundamental as Xamarin event handlers, which we use extensively throughout our application. This raises concerns about the current and long-term stability of our app when integrated with the SDK. Ideally, we would expect standard Xamarin features to continue to function as indented.

mythesithyoda commented 8 hours ago

Hello, I work for the same company as Ryan Pendleton and I too am interested in seeing this resolved. Is there an update on whether or not this is something that may be addressed? It is blocking our implementation of Intune to our application.

wangxiaoms commented 2 hours ago

Hi @rpendleton @mythesithyoda we have checked this case, the recommendation here would be to use UITextViewDelegate instead of Xamarin events. It appears that Xamarin events use this same delegate under the hood and will throw an exception if the delegate has already been set by the application or in this case, one of its frameworks. The Intune .Net/MAUI Bindings for iOS are just a .Net wrapper around the native Objective-C/Swift Intune iOS MAM SDK, which needs to use the delegate property to enforce policy. At the native layer, there is nothing the SDK can do to avoid this issue.