DidReceiveMemoryWarning in IOS using Xamarin Forms - xamarin

How can you catch the DidReceiveMemoryWarning using xamarin forms.
I can see them in the application output when debugging in xamarin studio, but i cant find how to catch the event or how to see how much memory is used.
I tried AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize but it throws a not implemented exception

There are 3 ways to capture Memory Warnings in iOS (or at least this what I know of :)
These three ways are:
In your ViewControllers, you could override DidReceiveMemoryWarning() and handle the warning there. This is not really the best way for Xamarin.Forms as you do not have UIViewController to override these methods, so move on to options 2 and 3.
In your AppDelegate, override ReceiveMemoryWarning method. This will get fired when the iOS is running low on memory. You could wire this method to any code you have on your PCL code or just handle it in your platform-specific project.
public override void ReceiveMemoryWarning (UIApplication application)
{
// handle low memory warnings here
}
You could use iOS NotificationCentre to receive a notification when there is a memory warning. This could be done like this:
// Method style void Callback (NSNotification notification)
{
Console.WriteLine ("Received a notification UIApplication", notification);
}
void Setup ()
{
NSNotificationCenter.DefaultCenter.AddObserver (UIApplication.DidReceiveMemoryWarningNotification, Callback);
}
You could then wire this "CallBack" to your PCL project to free up some memory.
You could also test this on the simulator using
Hardware >> Simulate Memory Warnings

You can override DidReceiveMemoryWarning in you iOS project, and from there notify the Xamarin.Forms pages. I can think of many ways to achieve this, but here are the 2 more obvious:
use Dependency Injection, and inject the warning as an event. Xamarin.Forms provides DependencyService as a DI container, but you can use the one you want: http://developer.xamarin.com/guides/cross-platform/xamarin-forms/dependency-service/
send messages from the native project to the other one, e.g. by using Xamarin.Forms MessagingCenter: http://developer.xamarin.com/guides/cross-platform/xamarin-forms/messaging-center/

Easiest way is to override ReceiveMemoryWarning in AppDelegate.cs as follows-
[Export("applicationDidReceiveMemoryWarning:")]
public override void ReceiveMemoryWarning(UIApplication application)
{
try
{
base.ReceiveMemoryWarning(application);
Console.WriteLine("****************************************************************");
Console.WriteLine("****************RECIEVED MEMORY WARNING***********************");
Console.WriteLine("****************************************************************");
Console.WriteLine("TOTAL MEMORY {0}",GC.GetTotalMemory(false));
AnalyticsService.Current.TrackUserActions("RECIEVED MEMORY WARNING");
}
catch (Exception ex)
{
AnalyticsService.Current.TrackException(ex);
}
}
Every time iOS running on low memory this method will get called and will crash app. Total memory(RAM) allocated/available can be checked by calling this method GC.GetTotalMemory(false) after app launch or wherever you want to check the available memory.

Related

MVVMCross View Model Prepare method not called when Hot Reload (ing) XAML changes

I started using MVVMCross several weeks ago and so far I love it, but I've noticed that whenever I'm working on the UI and making changes in the XAML and pressing save which activates the Hot Reload in Visual Studio 2019, I'm getting Null Reference Exceptions.
This is down to the fact that the MVVMCross' Prepare method is not getting called. According to their doc's this method is used to pass a parameter to the VM which can then be used throughout the VM.
public override void Prepare(MyClass param)
{
MyClass = param;
}
public override Task Initialize()
{
MyClass.DoSomething();
return base.Initialize();
}
So this is the basic usage (I think). However when I Hot Reload the XAML changes Prepare isn't called but Initialize is, which causes the Exception.
Is this a bug ?
Prepare in normal cases will only be called when calling NavigationService.Navigate.
What Hot Reload actually does is unclear. This use case is currently not officially supported by MvvmCross.

Is there any final even happen before a XF application exits for ever?

I realize there are these events:
protected override void OnSleep()
{
base.OnSleep();
}
protected override void OnResume()
{
base.OnResume();
}
But is there any event that is called in which I could perform a logging action, before the app is finally swiped out of view and closed?
No there are only 3 lifecycle events for a Xamarin.Forms application. See documentation. They are:
OnStart(), OnSleep(), and OnResume().
What you could do is just do whatever you need to in OnSleep and reverse it in OnResume. That way whether the user comes back or not, you've handled what you need to handle.
No, and it is technically impossible to make something like that on iOS and Android. On UWP you could make some native code that would invoke this on Xamarin.Forms project. But I don't think that anyone is interested in such UWP only feature on Xamarin.Forms, so if you need it you will probably need to implement it yourself.

When using Appcenter, can I still call VersionTracking inside the App constructor?

The application I am working with uses AppCenter with code like this:
public App()
{
InitializeComponent();
VersionTracking.Track();
VersionChecks();
VersionChecks();
DB.CreateTables();
DB.GetSettings();
DB.PopulateTables();
SetDeviceInfo();
SetResourceColors();
SetResourceDimensions();
MainPage = new AppShell();
}
protected override void OnStart()
{
AppCenter.Start("xx", typeof(Crashes), typeof(Push));
Analytics.TrackEvent(VersionTracking.CurrentVersion);
}
Although I don't see any error messages when it starts up I am concerned about the way this is coded as from what I can see the App constructor fires first followed by the OnStart().
So if this happens, how can VersionTracking work. Should that code not be in the OnStart and how about the additional code that I have which sets up the application?
Would appreciate any advice that people can offer about the use of AppCenter with Xamarin forms.
Answer
Yes, you can use Xamarin.Essentials.VersionTracking in the constructor of App.
Explanation
You are confusing three different SDKs: Xamarin.Essentials, Xamarin.Forms and AppCenter.
VersionTracking is an API in Xamarin.Essentials.
App is a subclass of the Xamarin.Forms.Application API.
AppCenter.Start is an API in the AppCenter
These are three independent SDKs and each can be used independently of the others.
Xamarin.Forms app startup flow is like : Native App Startup -> Xamarin.Forms.Application Startup
Your App class is instantiated only after Native app has finished loading.
As versioning is managed by native app, there is no problem in initialising VersionTracking in constructor, as Native app has fully loaded by this time.

Xamarin Forms - How to open specific page after clicking on notification when the app is closed?

I'm actually working on a Xamarin Forms application that need push notifications. I use the Plugin.PushNotification plugin.
When the app is running in the foreground or is sleeping (OnSleep), I have no problem to open a specific page when I click on a notification that I receive. But I was wondering how can I do that when the app is closed. Thanks!
I finally found the answer by myself and I want to share it in case someone needs it.
Nota bene: according to the official documentation of the plugin, it's Xam.Plugin.PushNotification that is deprecated. I use the new version of this plugin, Plugin.PushNotification which uses FCM for Android and APS for iOS.
There is no significant differences to open a notif when the app is running, is sleeping or is closed. Just add the next callback method in the OnCreate method (MyProject.Droid > MainApplication > OnCreate) and FinishedLaunching method (MyProject.iOS > AppDelegate > FinishedLaunching):
CrossPushNotification.Current.OnNotificationOpened += (s, p) =>
{
// manage your notification here with p.Data
App.NotifManager.ManageNotif(p.Data);
};
Common part
App.xaml.cs
// Static fields
// *************************************
public static NotifManager NotifManager;
// Constructor
// *************************************
public App()
{
...
NotifManager = new NotifManager();
...
}
NotifManager.cs
public class NotifManager
{
// Methods
// *************************************
public void ManageNotif(IDictionary<string, object> data)
{
// 1) switch between the different data[key] you have in your project and parse the data you need
// 2) pass data to the view with a MessagingCenter or an event
}
}
Unfortunately there is no succinct answer for either platform. Generally speaking, you need to tell the OS what to do when it starts the app as a result of the push notification. On both platforms, you should also consider what API level you are targeting, otherwise it won't work or even crash the app.
On iOS, you will need to implement this method in AppDelegate appropriately: FinishedLaunching(UIApplication application, NSDictionary launchOptions). The launchOptions will have the payload from the push notification for you to determine what to do with it (e.g. what page to open). For more information on iOS, Xamarin's documentation is a good place to start.
Android has a more complicated topology in terms of more drastic differences between API levels, whether you are using GCM/FCM, as well as requiring more code components. However, to answer the question directly, you will need to handle this in OnCreate(Bundle savedInstanceState) of your main Activity. If you are using Firebase, the push notification payload is available in Intent.Extras. Again, Xamarin's documentation has a good walkthrough.
Finally, note that the Plugin.PushNotification library you are using has been deprecated. I suggest you either change your library and/or your implementation soon. Part of the reason that library has been deprecated is because Google has deprecated the underlying Google Cloud Messaging (GCM) service, which will be decommissioned on April 11, 2019.

Error while leaving my application xamarin forms android in the background

My solution when I leave the application or leave it in the background gives an error 'The test application stopped', I can not find out where this queue comes from. Does anyone know where this trigger comes from the moment it leaves in the background
Is it something in this part of the code?
protected override void OnStart()
{
Debug.WriteLine("OnStart");
}
protected override void OnResume()
{
Debug.WriteLine("OnResume");
}
protected override void OnSleep()
{
Debug.WriteLine("OnSleep");
}
This type of errors came along with a specific part of your code, like #apineda mentioned maybe you are using an Android service that is updating some data on your application or it may be there to show a local notification who knows? but the thing I want to imply is that you need to take a look at your code and investigate further which is the part that is making the crash. Here are some tips:
1.- If you are using push notifications that may lead to something!
2.- Check you MainActivity.cs class since this is the one responsible of the Xamarin.Forms activity life cycle.
3.- If you have any timers on your shared code or even a background Task created with Task.Run or a Task.Factory.StartNew() check those too, deadlocks on Xamarin.Forms applications between the UI thread and background threads are a common thing on Xamarin.Forms.
I hope this helps!

Resources