Keep Your App Up-to-Date: Version Tracking in Xamarin and .NET MAUI

Keep Your App Up-to-Date: Version Tracking in Xamarin and .NET MAUI

Please, support my blog by clicking on our sponsors ad!


 Introduction

Ensuring that users have the latest version of your app is crucial for providing the best user experience and security. In this blog post, we will discuss how to implement version tracking in Xamarin and .NET MAUI applications for both Android and iOS platforms. By the end of this guide, you will be able to check if there is a new version available and prompt users to update their apps.

Setting Up Version Tracking

To implement version tracking, we need to install the following NuGet packages:

  • HtmlAgilityPack (1.11.61)
  • Jurassic (3.2.6)
  • Xamarin.Essentials (1.7.5)
  • Xam.Plugin.LatestVersion (1.1.2)

Code Explanation

Let's dive into the code implementation for both Android and iOS.

App.cs (for Android)

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        MainPage = new AppShell();
    }

    protected async override void OnStart()
    {
        try
        {
            if (Device.RuntimePlatform == Device.Android)
            {
                string liveversion = await GetLatestVersionNumber();
                string installedVersionNumber = CrossLatestVersion.Current.InstalledVersionNumber;

                if (Convert.ToDouble(liveversion) > Convert.ToDouble(installedVersionNumber))
                {
                    Device.BeginInvokeOnMainThread(async () =>
                    {
                        bool result = await App.Current.MainPage.DisplayAlert("", "New Version Available", "Update", "Cancel");
                        if (result)
                        {
                            if (Device.RuntimePlatform == Device.Android)
                            {
                                string urls = "https://play.google.com/store/apps/details?id=com.companyname.veepee";
                                await Xamarin.Essentials.Browser.OpenAsync(urls, Xamarin.Essentials.BrowserLaunchMode.External);
                            }
                        }
                    });
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    public async Task<string> GetLatestVersionNumber()
    {
        var version = string.Empty;
        var url = $"https://play.google.com/store/apps/details?id=com.companyname.app&hl=en";

        using (var request = new HttpRequestMessage(HttpMethod.Get, url))
        {
            using (var handler = new HttpClientHandler())
            {
                using (var client = new HttpClient(handler))
                {
                    using (var responseMsg = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead))
                    {
                        if (!responseMsg.IsSuccessStatusCode)
                        {
                            throw new Exception("Error connecting to the Play Store.");
                        }

                        try
                        {
                            var content = responseMsg.Content == null ? null : await responseMsg.Content.ReadAsStringAsync();
                            var doc = new HtmlDocument();
                            doc.LoadHtml(content);

                            var scripts = doc.DocumentNode.Descendants()
                                 .Where(n => n.Name == "script" && n.InnerText.Contains("AF_initDataCallback({key: 'ds:5'"))
                                 .ToArray();
                            var script = scripts.First().InnerText;

                            var engine = new Jurassic.ScriptEngine();
                            var eval = "(function() { var AF_initDataCallback = function(p) { return p.data[1][2][140][0][0][0]; };  return " + script + " })()";
                            var result = engine.Evaluate(eval);

                            version = result is null ? string.Empty : result.ToString();
                        }
                        catch (Exception e)
                        {
                            throw new Exception("Error parsing content from the Play Store.", e);
                        }
                    }
                }
            }
        }

        return version;
    }
}

In this code, we check the latest version available on the Google Play Store using the HtmlAgilityPack and Jurassic libraries. If a newer version is available, a prompt is shown to the user to update the app.

AppDelegate.cs (for iOS)
public class AppDelegate : MauiUIApplicationDelegate
{
    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        GetLatestVersion();
        return base.FinishedLaunching(app, options);
    }

    public async void GetLatestVersion()
    {
        bool isforcedUpdate = false;
        try
        {
            var url = new NSUrl($"https://itunes.apple.com/lookup?id=6450380169&country=IN");
            var data = NSData.FromUrl(url);

            NSError errors = null;
            var lookup = NSJsonSerialization.Deserialize(data, 0, out errors) as NSDictionary;

            if (lookup[new NSString("resultCount")].ToString() == "1")
            {
                var appStoreArray = lookup[new NSString("results")] as NSArray;
                var appStoreversion = Convert.ToDouble(appStoreArray.GetItem<NSMutableDictionary>(0)[new NSString("version")].ToString());
                string installedVersionNumber = CrossLatestVersion.Current.InstalledVersionNumber;
                if (Convert.ToDouble(appStoreversion) > Convert.ToDouble(installedVersionNumber))
                {
                    Device.BeginInvokeOnMainThread(async () =>
                    {
                        if (!isforcedUpdate)
                        {
                            bool result = await App.Current.MainPage.DisplayAlert("", "New Version Apps Available", "Update", "Cancel");
                            if (result)
                            {
                                string urls = "https://apps.apple.com/in/app/appname/id9999999";
                                await Browser.OpenAsync(urls, BrowserLaunchMode.External);
                            }
                        }
                    });
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
}

For iOS, we fetch the latest version from the Apple App Store using an API call and prompt the user to update the app if a newer version is available.

Conclusion
Implementing version tracking in your Xamarin and .NET MAUI applications ensures that your users always have access to the latest features and improvements. By following the steps outlined in this blog, you can easily integrate version checking functionality for both Android and iOS platforms. Keeping your app up-to-date not only enhances the user experience but also helps in maintaining security and performance.

Stay tuned for more tips and tricks on mobile app development with Xamarin and .NET MAUI!

#Xamarin #dotNETMAUI #MobileDevelopment #VersionTracking #AppUpdates

Comments

Popular posts from this blog

Explore the UI libraries available for .NET MAUI at no cost.

Push Notification using Firebase in xamarin form (Android and IOS)

School UI Design using xamarin form