Xamarin Forms: Close applications programmatically

In some scenarios, we need to programmatically close our application. We can do it in our common code with Xamarin Forms too. Buuuuuut …….

Can we close an iOS application?

There is no API provided for gracefully terminating an iOS application.

In iOS, the user presses the Home button to close applications. Should your application have conditions in which it cannot provide its intended function, the recommended approach is to display an alert for the user that indicates the nature of the problem and possible actions the user could take — turning on WiFi, enabling Location Services, etc. Allow the user to terminate the application at their own discretion.

Do not call the exit function. Applications calling exit will appear to the user to have crashed, rather than performing a graceful termination and animating back to the Home screen.

Source: https://developer.apple.com/library/archive/qa/qa1561/_index.html

Close on Android from Forms code

There is one important place to implement closing apps from code: When you are handling back button presses by yourself.

Imagine, that you have a main screen, which is the root page. When a users presses the hardware back button you should display a confirmer, that says “Do you really want to close the application?”

If the user choose yes, you should make a call like this:

					DependencyService.Get<IPlatformSpecificService>().CloseApplication();

The definition of the IPlatformSpecificService should be look like this:

	public interface IPlatformSpecificService
	{
		void CloseApplication();
	}

And the Android implementation of the IPlatformSpecificService should be something like:

using Plugin.CurrentActivity;

[assembly: Dependency(typeof(DeviceSpecificService))]
namespace AnAwesomeCompany.AGreatProduct.Droid.DependencyServices
{
	public class PlatformSpecificService: IPlatformSpecificService
	{
		public void CloseApplication()
		{
			CrossCurrentActivity.Current.Activity.FinishAndRemoveTask();
		}
	}
}

Activity supports a lot of closing methods of the application. FinishAndRemoveTask will clear the app from the recents list too.

Take a look at official Android documentation at: https://developer.android.com/reference/android/app/Activity#finishAndRemoveTask()

Xamarin Forms: Logging with anything from Console to SQLite

And it’s also logging the invoked method name, and the file name containing the method!

My Forms.RecurrenceToolkit NuGet package pack is now extended with logging functionality.

You can use the pre-written Console and SQLite logger without writing much code, or you can implement your own logger in a few lines, and use it instantly simultaneous with other loggers.

Install banditoth.Forms.RecurrenceToolkit.Logging.* packages, and enjoy the painless logging, and focus on the great ideas instead of being a copy paste robot. 🙂

Usage

In your App.xaml.cs, initalize the logger like:

LoggingProvider.Initalize(
	// If you have installed the console logger:
	new ConsoleLogger(),
	// If you have installed SQLite Logger:
	new SQLiteLogger()
	);

The logger is including the calling method’s name, and the .cs file name in the logs. You can access the logger from anywhere by calling these methods:

LoggingProvider.LogCritical("It's a critical message");
LoggingProvider.LogDebug("It's a debug message");
LoggingProvider.LogError("It's an error message");
LoggingProvider.LogException(new Exception(), "It's an exception");
LoggingProvider.LogInformation("It's an information message");
LoggingProvider.LogTrace("It's a trace message");
LoggingProvider.LogTrace(new StackTrace());
LoggingProvider.LogWarning("It's a warning message");

By default, the console and the SQLite logger logs exceptions in error level.

You can implement your own logger by deriving from BaseLogger class, like:

public class CustomLogger : BaseLogger
	{
		public CustomLogger() : base(new LoggerOptions()
		{
			IncludeCallerSourceFullFileName = true, // This will print C:/Users/Path/AssemblyFile.cs
			IncludeCallerSourceShortFileName = false, // This will print AssemblyFile.cs
			ExceptionLevel = Enumerations.LogLevel.Error, // The LogExceptions calls routed to log to the loglevel set.
			IncludeCallerMethodName = true // This can print the calling method's name
		})
		{

		}
		
		public override void LogCritical(string criticalMessage, string callerMethod, string filePath)
		{
			// Your own method
		}

		// .. File continues

Follow for more

https://github.com/banditoth/Forms.RecurrenceToolkit

Xamarin and Aspect Orientated Programming

I have started implementing my very first AOP like library, which is now available for testing in NuGet.org as a pre-release version.

This package is a part of my Xamarin.Forms Toolkit, and it is a good time to say thank you for using all of the three packages more than 500 times.
When I had published them, I thought the only user will be me. 🙂

In the first release of the package (1.0.0-pre-01), you can decorate your methods with attributes, in order to listen for Entering the method, and Exiting the method.

This can be handy for example, when you need to log your method invocations (Firebase analytics, Basic logging) or when you need to measure the elapsed time of the method run.

    [ConsoleYaay]
    public void BoringMethod()
    {
        Console.WriteLine(DateTime.Now);
    }

For example, the following code above will result the output below:

yaaay on enter!
2021. 05. 25. 16:56:01
yaaaay on exit

This can be achieved implementing IMethodDecorator class like this:

    [System.AttributeUsage(System.AttributeTargets.Method)]
    public class ConsoleYaay : Attribute, IMethodDecorator
    {
        public ConsoleYaay()
        {

        }

        public void OnEnter()
        {
            Console.WriteLine("yaaay on enter!");
        }

        public void OnExit()
        {
            Console.WriteLine("yaaaay on exit");
        }
    }

Try it in your project

Let’s jump to https://github.com/banditoth/Forms.RecurrenceToolkit/ to see the code, or https://www.nuget.org/packages/banditoth.Forms.RecurrenceToolkit.AOP/ to download it as a package

Future improvements

This package can be improved in a lot of aspects, so stay tuned for more details. Or just simply make a pull request with your ideas 🙂

Xamarin.Forms: Reopening application best pratices

If you have experienced that reopening your application from the phone’s app drawer or launcher is fails because it crashes your application, or displays the first set main page again instead of displaying the latest one, keep reading this article.

If you have crashes, or malfunctions, you are probably initializing something in the constructor of the App.xaml.cs, or in the overridden method called ‘OnStart’ like this:

        public App()
        {
            InitializeComponent();
            InitalizeOnlyOnceClass.Initalize();
        }

        protected override void OnStart()
        {
            AnAnotherInitalizeOnlyOnceClass.Initalize();
        }

Imaginary InitalizeOnlyOnceClass’s Initialize method can be called only once, for the second call, it throws an exception. After you have started your program, sent to background, and bringing it back throws the second Initalization’s exception. This is because the App class gets constructed again when reopening application from the drawer.

To handle this, you should make a boolean for the application’s initialization progress.

        private static bool isInitalized;

        public App()
        {
            InitializeComponent();

            if(isInitalized == false)
            {
                InitalizeOnlyOnceClass.Initalize();
            }
        }

If you receive a blank white screen, you are probably forget to set the Main Page

Make sure, that the Application.Current.MainPage always gets a value.
If you have implemented the Initialization by your self, or an another way, make sure you have handled correctly the else statement also.
Even if the application has been initialized once, the Application.Current.MainPage have to be set always when reconstructing the App.

Continue with the last page opened in the application

If you want to continue always with the last page opened, you need to store the last page always, when you are navigating from one to an another.

You can store the last page with making a class used for navigation, like this:

    public static class SimpleNavigationLogic
    {
        private static Xamarin.Forms.Page lastNavigatedPage;

        public static void ChangeMainPage(Xamarin.Forms.Page pageToSet)
        {
            Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
            {
                Application.Current.MainPage = pageToSet;
            });
            lastNavigatedPage = pageToSet;
        }

        public static void RestoreMainPage()
        {
            Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
            {
                Application.Current.MainPage = lastNavigatedPage;
            });
        }
    }

Than you can make the initialization for your application like this:

        public App()
        {
            InitializeComponent();

            if(!isInitalized)
            {
                InitalizeOnlyOnceClass.Initalize();
                SimpleNavigationLogic.ChangeMainPage(new AwesomeMainPage());
            }
            else
            {
                SimpleNavigationLogic.RestoreMainPage();
            }
        }

Xamarin: How .NET MAUI will change the life of Xamarin.Forms development

.NET 6 and .NET MAUI is on the sill, but how will it affect the development of Xamarin applications?

For today, I have brought you a video by James Montemagno, a Xamarin developer working at Microsoft.

Follow James on the following platforms:

🌱 https://montemagno.com
🎙 https://mergeconflict.fm, https://blunders.fm, https://nintendodispatch.com
🦜 https://twitter.com/jamesmontemagno
🎥 https://youtube.com/jamesmontemagno