.NET Maui: how do you process low memory notifications from iOS

Kurt K 176 Reputation points
2023-09-06T02:48:46.1+00:00

iOS sends warnings to an app when it approaches its memory limit. How do you process those warnings in a .NET Maui app? (I see that for Android, .NET Maui supports delegates OnApplicationLowMemory and OnApplicationTrimMemory, but I do not see any such support for iOS.)

Thank you.

Developer technologies | .NET | .NET MAUI
{count} votes

Accepted answer
  1. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 36,436 Reputation points Microsoft External Staff
    2023-09-06T09:37:27.3933333+00:00

    Hello,

    In app lifecycle events, low memory delegates have been implemented for Android but not iOS. You could create a feature request at https://github.com/dotnet/maui/issues/new/choose.

    As described in Apple's responding to low-memory warnings doc, you could implement the applicationDidReceiveMemoryWarning(_:) method of your app delegate and the didReceiveMemoryWarning() method of active UIViewController objects.

    Please refer to the following code:

    public class AppDelegate : MauiUIApplicationDelegate
    {
       [Export("applicationDidReceiveMemoryWarning:")]
        public  void ReceiveMemoryWarning(UIApplication application)
        {
          ...}//receive
    
    }
    

    Each ContentPage has a PageHandler, please refer to this solution and create a custom handler which inherit PageHandler, then override the DidReceiveMemoryWarning method.

    #if IOS
        public class ReceiveMemoryPageHandler : PageHandler
        {
            class MyPageViewController : PageViewController
            {
                public MyPageViewController(IView page, IMauiContext mauiContext) : base(page, mauiContext)
                {
                }
             public override void DidReceiveMemoryWarning()
            {
                base.DidReceiveMemoryWarning();
           }
        }
    
           protected override Microsoft.Maui.Platform.ContentView CreatePlatformView()
            {// refer to https://github.com/dotnet/maui/issues/7174#issuecomment-1505519377
        }
    
    #endif
    

    Register ReceiveMemoryPageHandler in MauiProgram.cs :

    #if IOS
            builder.ConfigureMauiHandlers(handlers =>
            {
                handlers.AddHandler(typeof(MainPage), typeof(ReceiveMemoryPageHandler));
            });
    #endif
    

    Update

    Where should the "ReceiveMemoryWarning" method be placed? At the start of the existing "AppDelegate" class in AppDelegate.cs?

    Yes. At the start of the existing "AppDelegate" class. (Platfoms/iOS/AppDelegate)

    Where should the "ReceiveMemoryPageHandler" class be placed in the app?

    ReceiveMemoryPageHandler is a new class, you can put it at the end of MainPage.cs or a new file in Platfoms/iOS folder or other place, pay attention to the namespace and iOS condition(#if IOS ...#endif).

    Is "[Import(...)]" not required in this case?

    Yes, because it's a native method. You could refer to the source code for other methods: MauiUIApplicationDelegate.cs

    Where do I place the application code for reducing memory when the "applicationDidReceiveMemoryWarning" is issued by iOS?

    It's depended on your needs. When you get the notification, you could deal with the business logic after base.DidReceiveMemoryWarning(); . I know you may be worried that the logic is not in this handler. You could try to publish message from this handler and subscribe to messages in the ViewModel. See Publish and subscribe to messages - .NET MAUI | Microsoft Learn

    Update

    What code should be placed in method ReceiveMemoryWarning?

    The logic of cleaning the large resources, such as the item source of ListView, some image caches.

    When does ReceiveMemoryWarning get called?

    This notification usually is sent by operating system. You could simulate this process on your physical device by calling the following code:

    #if IOS
    UIKit.UIApplication.SharedApplication.PerformSelector(new ObjCRuntime.Selector("_performMemoryWarning"));
    #endif
    

    Or you could run the app on an iOS simulator, then go to Simulator->Debug->Simulate Memory Warning

    Update

    Would you mind clarifying what code should be placed in those two methods?

    In UIKit.UIViewController.DidReceiveMemoryWarning method, what code should be placed depends on your app's logic. You could clean the large recourses. For example, I tried to clean the item source of a collectionview.(Refer to this official collectionview sample) clean item source in VM

     public void CleanRecources()
    
    {
        Monkeys.Clear();
        selectedMonkeys.Clear();
    }
    

    Find the handler in CollectionViewPage's loaded method (your MainPage)

     private void CollectionViewPage_Loaded(object sender, EventArgs e)
    
    {
    
    #if IOS
    
        ReceiveMemoryPageHandler handler = this.Handler as ReceiveMemoryPageHandler;
        var myPageViewController = handler.ViewController as ReceiveMemoryPageHandler.MyPageViewController;
        myPageViewController.LowMemoryAction += () =>
        {
            MonkeysViewModel vm = this.BindingContext as MonkeysViewModel;
            vm.CleanRecources();
        };
    
    #endif
    
    }
    

    Add Action or MessageingCenter to invoke the cleaning recourses method.

    public Action LowMemoryAction { get; set; }
     public override void DidReceiveMemoryWarning()
            {
                base.DidReceiveMemoryWarning();
                if (this.LowMemoryAction != null)
                {
                    this.LowMemoryAction();//when you receive this DidReceiveMemoryWarning system notification, trigger the action to clean some large recourses.
                }
              //  MessagingCenter.Send<MyPageViewController>(this, "lowmemory");
    
            }
    

    In applicationDidReceiveMemoryWarning method, you could clean some global static recourses that store in your app.

    Best Regards,

    Wenyan Zhang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.