如何检查 .NET MAUI 的最新应用程序版本?

huangapple go评论54阅读模式
英文:

How can I check the .net maui latest app version?

问题

我是.NET Maui的新手。我想通知那些使用旧版本的我的应用程序的用户,新版本已经在商店中可用。
当用户单击登录按钮时,我成功使用以下几行代码来实现:

[RelayCommand]
async Task Login()
{
    var isLatest = await CrossLatestVersion.Current.IsUsingLatestVersion();
    
    if (!isLatest)
    {
        await Application.Current.MainPage.DisplayAlert("更新", "新版本可用", "确定");
        await CrossLatestVersion.Current.OpenAppInStore();
    }
    else
    {...}
}

但是我想在LoginPage出现之前通知用户。我尝试在LoginPage的OnAppearing()方法中实现,但它不起作用,似乎调用CrossLatestVersion.Current.IsUsingLatestVersion()时出现问题,没有错误消息或其他响应...

有什么建议吗?
提前感谢大家!

英文:

I'm new to .NET Maui. I would like to notify users who have an old version of my app that a new version is available on the store.
I managed to do it when the user click on the Login Button with these few lines of code:


[RelayCommand]

async Task Login()
{

    var isLatest = await CrossLatestVersion.Current.IsUsingLatestVersion();

    if (!isLatest)
    {
        await Application.Current.MainPage.DisplayAlert("Update", 
              "New version available", "OK");
        await CrossLatestVersion.Current.OpenAppInStore();
    }
    else
    {...}
}

But I would like to notify the user before the LoginPage appears. I tried to
do it in the method

protected override async void OnAppearing()

of the LoginPage but it doesn't work, it seems that the call

CrossLatestVersion.Current.IsUsingLatestVersion();

dies, without errors and otherwise unanswered...

Any suggestions?
Thank you all in advance!!

答案1

得分: 3

关于上面的评论,这是我用来从应用商店获取最新版本的代码片段。这与您正在使用的NuGet包中使用的技术相同。尝试进入您所使用的NuGet包的GitHub页面,它类似。

public async Task<string> GetLatestVersionAvailableOnStores()
{
    string remoteVersion = "";
    string bundleID = YOUR_BUNDLE_ID;
    bool IsAndroid = DeviceInfo.Current.Platform == DevicePlatform.Android;

    var url = IsAndroid ?
        "https://play.google.com/store/apps/details?id=" + bundleID :
        "http://itunes.apple.com/lookup?bundleId=" + bundleID;

    using (HttpClient httpClient = new HttpClient())
    {
        string raw = await httpClient.GetStringAsync(new Uri(url));

        if (IsAndroid)
        {
            var versionMatch = Regex.Match(raw, @"\[\[""\d+.\d+.\d+""\]\]"); //查找模式[["X.Y.Z"]]
            if (versionMatch.Groups.Count == 1)
            {
                var versionMatchGroup = versionMatch.Groups[0];
                if (versionMatchGroup.Success)
                    remoteVersion = versionMatch.Value.Replace("[", "").Replace("]", "").Replace("\"", "");
            }
        }
        else
        {
            JObject obj = JObject.Parse(raw);
            if (obj != null)
                remoteVersion = obj["results"]?[0]?["version"]?.ToString() ?? "9.9.9";
        }
    }

    return remoteVersion;
}

您可以通过在项目中使用任何静态变量来获取应用程序版本。然后,您可以执行字符串之间的比较。我使用自然比较来检查哪个是最新版本。

iOS:

SharedProjectClass.ApplicationVersion = NSBundle.MainBundle.InfoDictionary["CFBundlePublicVersionString"].ToString();

Android:

SharedPRojectClass.ApplicationVersion = PackageManager.GetPackageInfo(PackageName, 0).VersionName;

Common Project:
public static class SharedProjectCLass
{
    /// <summary>
    /// The application version.
    /// </summary>
    public static string ApplicationVersion;
}
async Task CheckVersion()
{
    var currentVersion = SharedProjectClass.ApplicationBuildNumber;

    var remoteVersion = await GetLatestVersionAvailableOnStores();

    // 用于自然比较格式为d.d.d的应用程序版本的函数
    Func<string, string, bool> CompareNaturalStringsOfAppVersion = (currentVersion, remoteVersion) =>
    {
        string[] components1 = currentVersion.Split('.');
        string[] components2 = remoteVersion.Split('.');

        for (int i = 0; i < components1.Length; i++)
        {
            int value1 = Convert.ToInt32(components1[i]);
            int value2 = Convert.ToInt32(components2[i]);

            if (value1 < value2)
            {                  
                return true; // 字符串1较低
            }
            else if (value1 > value2)
            {
                return false; // 字符串2较低
            }
        }

        return false; // 两个字符串相等
    };

    bool needToUpdateApp = CompareNaturalStringsOfAppVersion(currentVersion, remoteVersion);

    if (needToUpdateApp)
    {
         // 显示弹出窗口,告知用户有新版本可用。
    }
}
英文:

Inref to the above comment, here is the code snippet i use to get the latest version of App from the stores. It is the same technique used in the nugget package you are using. Try to get into the GitHub of the nugget you using, its similar.

public async Task&lt;string&gt; GetLatestVersionAvailableOnStores()
        {
            string remoteVersion = &quot;&quot;;
            string bundleID = YOUR_BUNDLE_ID;
            bool IsAndroid = DeviceInfo.Current.Platform == DevicePlatform.Android;

            var url = IsAndroid ?
                &quot;https://play.google.com/store/apps/details?id=&quot; + bundleID :
                &quot;http://itunes.apple.com/lookup?bundleId=&quot; + bundleID;

            using (HttpClient httpClient = new HttpClient())
            {
                string raw = await httpClient.GetStringAsync(new Uri(url));

                if (IsAndroid)
                {
                    var versionMatch = Regex.Match(raw, @&quot;\[\[&quot;&quot;\d+.\d+.\d+&quot;&quot;\]\]&quot;); //look for pattern [[&quot;X.Y.Z&quot;]]
                    if (versionMatch.Groups.Count == 1)
                    {
                        var versionMatchGroup = versionMatch.Groups[0];
                        if (versionMatchGroup.Success)
                            remoteVersion = versionMatch.Value.Replace(&quot;[&quot;, &quot;&quot;).Replace(&quot;]&quot;, &quot;&quot;).Replace(&quot;\&quot;&quot;, &quot;&quot;);
                    }
                }
                else
                {
                    JObject obj = JObject.Parse(raw);
                    if (obj != null)
                        remoteVersion = obj[&quot;results&quot;]?[0]?[&quot;version&quot;]?.ToString() ?? &quot;9.9.9&quot;;
                }
            }

            return remoteVersion;
        }

You can have the Application version by using any static variable in your project. And then you can perform the comparison between both the strings. I used natural comparison to check which is the latest version.

iOS:

            SharedProjectClass.ApplicationVersion = NSBundle.MainBundle.InfoDictionary[&quot;CFBundlePublicVersionString&quot;].ToString();

Android:

            SharedPRojectClass.ApplicationVersion = PackageManager.GetPackageInfo(PackageName, 0).VersionName;

Common Project:
	public static class SharedProjectCLass
	{
		/// &lt;summary&gt;
		/// The application version.
		/// &lt;/summary&gt;
		public static string ApplicationVersion;
     }
async Task CheckVersion()
{
            var currentVersion = SharedProjectClass.ApplicationBuildNumber;

            var remoteVersion = await GetLatestVersionAvailableOnStores();

            // Function to natural compare the App version of format d.d.d
            Func&lt;string, string, bool&gt; CompareNaturalStringsOfAppVersion = (currentVersion, remoteVersion) =&gt;
            {
                string[] components1 = currentVersion.Split(&#39;.&#39;);
                string[] components2 = remoteVersion.Split(&#39;.&#39;);

                for (int i = 0; i &lt; components1.Length; i++)
                {
                    int value1 = Convert.ToInt32(components1[i]);
                    int value2 = Convert.ToInt32(components2[i]);

                    if (value1 &lt; value2)
                    {                  
                        return true; // string1 is lower
                    }
                    else if (value1 &gt; value2)
                    {
                        return false; // string2 is lower
                    }
                }

                return false; // both strings are equal
            };

            bool needToUpdateApp = CompareNaturalStringsOfAppVersion(currentVersion, remoteVersion);

            if (needToUpdateApp)
            {
                 //Show aleart pop-up to user saying new version is available.
            }
}

答案2

得分: 0

OnAppearing中添加您尝试但失败的完整代码。

如果LoginPage是您的应用程序中首先显示的页面,那么绝对不要阻止OnAppearing返回,同时检查版本 - 在启动时尽快显示您的应用程序非常重要。

我创建了一个名为“StartupPage”的页面,其中包含应用程序/公司徽标和“Loading...”。这会在运行任何初始化逻辑时显示。

这个技巧是在后台运行初始化。完成后,跳转到适当的页面。在您的情况下,可以跳转到以下两个页面之一:

  • 如果是最新版本,请转到登录页面。
  • 如果获取商店版本失败,也转到登录页面!
  • 如果有新版本,转到通知用户新版本的页面,带有两个按钮。一个按钮前往应用商店,另一个按钮前往登录页面。

StartupPage的OnAppearing:

public partial class StartupPage : ContentPage
{
    protected override void OnAppearing()
    {
        base.OnAppearing();

        // 启动后台工作。重要提示:不要“await” Task.Run 本身;
        // 在完成此工作之前让 `OnAppearing` 返回。
        Task.Run(async () => await Initialization());
    }

    // 确保在后台线程上运行此方法(通过 Task.Run)。
    // 原因:不希望延迟 StartupPage 的显示。
    private async Task Initialization()
    {
        // 如果有可用更新则为 true。
        // 如果没有更新则为 false。
        // 如果检查应用程序版本时超时或出错,则为 false。
        bool appUpdateExists = false;

        try
        {
            // ... 检查应用程序版本的代码
            if (...)
            {
                appUpdateExists = true;
            }
        }
        catch (Exception ex)
        {
            // 任何失败都假定没有更新,因此继续登录。
            appUpdateExists = false;
        }

        // 在切换到新页面之前返回到主线程。
        MainThread.BeginInvokeOnMainThread(async () =>
        {
            if (appUpdateExists)
                ... // 转到 UpdateExistsPage。
            else
                ... // 转到 LoginPage。
        });
    }
}
英文:

Add to question the complete code of your failed attempt in OnAppearing.

If LoginPage was the first page that displays in your app, then you definitely don't want to prevent OnAppearing from returning, while you check the version - it is important to have your app display something ASAP on startup.

I make a "StartupPage" with app/company logo + "Loading...". This displays while any initialization logic is running.

The technique is to run initialization in the background. When complete, go to an appropriate page. In your case, go to one of two pages:

  • If up-to-date, go to Login page.
  • If attempt to get store version fails, also go to Login page!
  • If there is a newer version, go to page that informs user of new version, with two buttons. One button goes to App Store, the other button goes to Login page.

StartupPage's OnAppearing:

public partial class StartupPage : ContentPage
{
    protected override void OnAppearing()
    {
        base.OnAppearing();

        // Start background work. IMPORTANT: DO NOT &quot;await&quot; Task.Run itself;
        // let `OnAppearing` return before this work is done.
        Task.Run( async () =&gt; await Initialization() );
    }

    // Make sure this is run on a background thread (via Task.Run).
    // REASON: Don&#39;t want to delay StartupPage appearing.
    private async Task Initialization()
    {
        // true if there is an update available.
        // false if no update.
        // false if time out or error while checking app version.
        bool appUpdateExists = false;

        try
        {
            // ... your code to check app version
            if (...)
            {
                appUpdateExists = true;
            }
        }
        catch (Exception ex)
        {   // Any failure; assume there is no update, so proceeds to login.
            appUpdateExists = false;
        }

        // Get back to MainThread, before switching to new page.
        MainThread.BeginInvokeOnMainThread( async () =&gt;
        {
            if (appUpdateExists)
                 ... // to UpdateExistsPage.
            else
                 ... // to LoginPage.
        }
    }
}


</details>



huangapple
  • 本文由 发表于 2023年6月15日 18:22:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76481539.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定