edsnider / latestversionplugin

LatestVersion Plugin for Xamarin and Windows apps
MIT License
151 stars 38 forks source link

GetLatestVersionNumber throws an exception #50

Open ChristianM66 opened 2 years ago

ChristianM66 commented 2 years ago

Bug

Plugin Version: 2.1.1-beta.107 Platform: Android 12 (31-S)
Device/Hardware:

Expected behavior

CrossLatestVersion.Current.GetLatestVersionNumber() does not return the version number, instead it throws a Jurassic.JavaScriptException.

Actual behavior

{Plugin.LatestVersion.LatestVersionException: Fehler beim Parsen von Inhalten aus dem Play Store. Url=https://play.google.com/store/apps/details?id=com.ist.saleboard.mobile&hl=en. ---> Jurassic.JavaScriptException: TypeError: undefined cannot be converted to an object at Jurassic.TypeConverter.ToObject (Jurassic.ScriptEngine engine, System.Object value, System.Int32 lineNumber, System.String sourcePath, System.String functionName) [0x00037] in <018e8bf6db3d46cd85eb0a9bc95f4b3f>:0 at (wrapper dynamic-method) Jurassic. Compiler.MethodGenerator.anonymous(Jurassic.Compiler.ExecutionContext,object[]) at Jurassic.Library.UserDefinedFunction.CallLateBound (System.Object thisObject, System.Object[] argumentValues) [0x00014] in <018e8bf6db3d46cd85eb0a9bc95f4b3f>:0 at Jurassic. Library.FunctionInstance.CallWithStackTrace (System.String path, System.String function, System.Int32 line, System.Object thisObject, System.Object[] argumentValues) [0x0000f] in <018e8bf6db3d46cd85eb0a9bc95f4b3f>:0 at (wrapper dynamic-method) Jurassic. Compiler.MethodGenerator.anonymous(Jurassic.Compiler.ExecutionContext,object[]) at Jurassic.Library.UserDefinedFunction.CallLateBound (System.Object thisObject, System.Object[] argumentValues) [0x00014] in <018e8bf6db3d46cd85eb0a9bc95f4b3f>:0 at Jurassic. Library.FunctionInstance.CallWithStackTrace (System.String path, System.String function, System.Int32 line, System.Object thisObject, System.Object[] argumentValues) [0x0000f] in <018e8bf6db3d46cd85eb0a9bc95f4b3f>:0 at (wrapper dynamic-method) Jurassic. Compiler.MethodGenerator.eval(Jurassic.Compiler.ExecutionContext) at Jurassic.Compiler.GlobalOrEvalMethodGenerator.Execute (Jurassic.ScriptEngine engine, Jurassic.Compiler.RuntimeScope parentScope, System. Object thisObject) [0x00030] in <018e8bf6db3d46cd85eb0a9bc95f4b3f>:0 at Jurassic.ScriptEngine.Evaluate (Jurassic. ScriptSource source) [0x000a7] in <018e8bf6db3d46cd85eb0a9bc95f4b3f>:0 at Jurassic.ScriptEngine.Evaluate (System.String code) [0x00007] in <018e8bf6db3d46cd85eb0a9bc95f4b3f>:0 at Plugin. LatestVersion.LatestVersionImplementation.GetLatestVersionNumber () [0x001ff] in <7361502664264164a28b556feec777a7>:0 --- Ende der inneren Ausnahme Stack Trace --- at Plugin.LatestVersion.LatestVersionImplementation.GetLatestVersionNumber ()

Description:

SamPollard94 commented 2 years ago

I am observing the same issue.

idenardi commented 2 years ago

49 fixes this issue. It was merged but the NuGet package hasn't been published yet.

bestekarx commented 1 year ago

Is there a temporary solution?

ejastre commented 1 year ago

Is there a fix or a workaround for it? Thanks

ivgomezarnedo commented 1 year ago

Is there a fix or a workaround for it? Thanks

@ejastre You can use the following method instead of the NuGet package: https://gist.github.com/ivgomezarnedo/44ee8b9a204f930245b945e039b77077

Then, compare the user's installed version with the latest available in Google Play with:

Boolean checkAppLastVersion()
{
    string app_last_version = null;
    app_last_version = getAppLastVersion_js();
    PackageInfo packageInfo = this.PackageManager.GetPackageInfo(this.PackageName, 0);
    string installed_versionNumber = packageInfo.VersionName.Trim();
    return app_last_version == null ? true : app_last_version == installed_versionNumber;
}

By the way, I have written about how I have implemented it (and how I have added a double check) in: https://medium.com/@ivangomezarnedo/checking-app-version-on-google-play-83229c07577c

marcogramy commented 1 year ago

Please, when you plan to release the updated NuGet package with this fix?

Stensan commented 10 months ago

Any update on the NuGet package?

bestekarx commented 10 months ago

It doesn't work but here is my solution that I use for my project.

private async Task VersionControl()
 {
     try
     {
         var isCurrentVersion = true;
         if (Device.RuntimePlatform == Device.Android)
             isCurrentVersion = DependencyService.Get<ICustomAndroidVersionCheck>().GetAppLastVersion_js();
         else
         {
             var url = "http://itunes.apple.com/lookup?bundleId=com.companyname.app";
             using HttpClient client = new HttpClient();
             client.BaseAddress = new Uri(url);
             client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
             var response = await client.GetAsync(url);
             response.EnsureSuccessStatusCode(); // Optional: Throws exception if not successful
             var jsonResult = await response.Content.ReadAsStringAsync();
             var result = JsonConvert.DeserializeObject<AppStoreModel>(jsonResult);

             var appStoreVersion = Convert.ToDecimal(result.Results?.FirstOrDefault()?.Version.Replace(".", ""));
             var currentAppVersion = Convert.ToDecimal(VersionTracking.CurrentVersion.Replace(".", ""));

             if (currentAppVersion < appStoreVersion)
                 isCurrentVersion = false;
         }

         if (isCurrentVersion == false)
         {
             NavigationModel<VersionMessagePageViewParamModel> navigationModel = new NavigationModel<VersionMessagePageViewParamModel>
             {
                 Model = new VersionMessagePageViewParamModel(),

                 ClosedPageEventCommand = VersionMessagePageViewParamModel_ClosedPageEventCommand
             };
             await NavigationService.NavigateToBackdropAsync<VersionMessagePageViewModel>(navigationModel);
         }
     }
     catch (Exception ex)
     {
     }
 }
public class CustomAndroidVersionCheck : ICustomAndroidVersionCheck
{
    public bool GetAppLastVersion_js()
    {
        try
        {
            string url = $"https://play.google.com/store/apps/details?id={Android.App.Application.Context.PackageName}";
            // Use HttpClient to send a GET request to the URL
            HttpClient client = new HttpClient();
            HttpResponseMessage response = client.GetAsync(url).Result;

            // Read the response as a string
            var responseString = response.Content.ReadAsStringAsync().Result;

            var doc = new HtmlDocument();
            doc.LoadHtml(responseString);

            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);
            var appVersionName = Android.App.Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Android.App.Application.Context.ApplicationContext.PackageName, 0)
                ?.VersionName;
            var googlePlayVersion = Convert.ToInt32(result.ToString().Replace(".", ""));
            var currentAppVersion = Convert.ToInt32(appVersionName?.Replace(".", ""));
            return (currentAppVersion < googlePlayVersion) == false;
        }
        catch (Exception ex)
        {
            return true;
        }
    }
}
HavenDV commented 9 months ago

We were inspired by this library and made a continuation for MAUI, maybe it will be useful to someone - https://github.com/oscoreio/Maui.AppStoreInfo We decided to abandon this implementation for Android and instead used Android In-App Updates to check for new versions specifically for the Android platform - https://github.com/oscoreio/Maui.Android.InAppUpdates