From c1fffdc652c946029338e0084378a54a784170f9 Mon Sep 17 00:00:00 2001 From: James Montemagno Date: Sat, 30 Nov 2024 19:09:20 -0800 Subject: [PATCH] Refactor and update platform support and documentation Updated README.md to reflect .NET 8+ support for iOS, Android, MacCatalyst, and Windows, and removed outdated platform information. Changed UWP method signatures to return `Task` for `OpenStoreListing` and `OpenStoreReviewPage`. Updated Android setup instructions in README.md to remove outdated steps. Refactored `CrossStoreReview.shared.cs` and `StoreReviewImplementation` files for modern C# syntax and improved nullability. Simplified `IStoreReview.shared.cs` interface. Updated `StoreReview.Plugin.csproj` with correct metadata. Improved exception handling and logging across all platforms. --- README.md | 37 +--- .../CrossStoreReview.shared.cs | 76 ++++--- src/StoreReview.Plugin/IStoreReview.shared.cs | 41 ++-- .../StoreReview.Plugin.csproj | 16 +- .../StoreReviewImplementation.android.cs | 208 +++++++++--------- .../StoreReviewImplementation.apple.cs | 181 ++++++--------- .../StoreReviewImplementation.uwp.cs | 162 +++++++------- 7 files changed, 319 insertions(+), 402 deletions(-) diff --git a/README.md b/README.md index a3c07c5..fc4e8a1 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,8 @@ -## Store Review Plugin for .NET MAUI, Windows, & Xamarin +## Store Review Plugin for .NET MAUI, iOS, Android, MacCatalyst, Windows **Platform Support** -|Platform|Version| -| ------------------- | :------------------: | -|Xamarin.iOS|iOS 7+| -|Xamarin.tvOS|All| -|Xamarin.Android|API 10+| -|UWP|API 10+| -|.NET 6+ | iOS/Android/Mac/Windows/MAUI | -|macOS|All| +Support for .NET 8+ for iOS/Android/MacCatalyst/Windows/MAUI ### Build Status @@ -31,7 +24,7 @@ UWP: This is the Store ID: You can find the link to your app's Store listing on /// Opens the store listing. /// /// App identifier. -void OpenStoreListing(string appId); +Task OpenStoreListing(string appId); ``` #### Open to Review Page @@ -42,7 +35,7 @@ Launches app directly to Review Page if possible /// Opens the store review page. /// /// App identifier. -void OpenStoreReviewPage(string appId); +Task OpenStoreReviewPage(string appId); ``` #### Request In-App Review @@ -60,7 +53,7 @@ Read for Android: [In-app reviews for your Android apps](https://devblogs.micros Task RequestReview(bool testMode) ``` -If you are on .NET 6 Windows you will need to set the Window handle before calling the method: +If you are on .NET 8 Windows you will need to set the Window handle before calling the method: ```csharp #if WINDOWS @@ -71,26 +64,6 @@ If you are on .NET 6 Windows you will need to set the Window handle before calli Test mode is only used on Android. -### Android setup - -Ensure that you follow the [Xamarin.Essentials setup steps](https://docs.microsoft.com/xamarin/essentials/get-started?WT.mc_id=friends-0000-jamont). And follow the steps below if you linker behavior is not set to `Don't Link`. - -#### Android code shrinker (Proguard & r8) - -If you use the plugin with `Link SDK assemblies only`/`Link all`, you have to do the following: - -1. Create a `proguard.txt` file in your android project and add the following: - -``` - -keep class com.google.android.play.core.common.PlayCoreDialogWrapperActivity - -keep class com.google.android.play.core.review.** { *; } - -keep class com.google.android.play.core.tasks.** { *; } -``` - -2. Include it to your project -3. Properties > Build Action > ProguardConfiguration -4. Go to you Android project options and set your `Code Shrinker` to `ProGuard` or `r8` - ### Testing & Debugging issues #### iOS diff --git a/src/StoreReview.Plugin/CrossStoreReview.shared.cs b/src/StoreReview.Plugin/CrossStoreReview.shared.cs index 03031e5..b7ce5a4 100644 --- a/src/StoreReview.Plugin/CrossStoreReview.shared.cs +++ b/src/StoreReview.Plugin/CrossStoreReview.shared.cs @@ -1,51 +1,49 @@ using Plugin.StoreReview.Abstractions; -using System; -namespace Plugin.StoreReview +namespace Plugin.StoreReview; + +public enum ReviewStatus { - public enum ReviewStatus - { - Succeeded, - Error, - CanceledByUser, - NetworkError, - Unknown - } - /// - /// Cross platform StoreReview implemenations - /// - public class CrossStoreReview - { - static Lazy implementation = new Lazy(() => CreateStoreReview(), System.Threading.LazyThreadSafetyMode.PublicationOnly); + Succeeded, + Error, + CanceledByUser, + NetworkError, + Unknown +} +/// +/// Cross platform StoreReview implemenations +/// +public class CrossStoreReview +{ + static readonly Lazy implementation = new(() => CreateStoreReview(), LazyThreadSafetyMode.PublicationOnly); - /// - /// Gets if the plugin is supported on the current platform. - /// - public static bool IsSupported => implementation.Value == null ? false : true; + /// + /// Gets if the plugin is supported on the current platform. + /// + public static bool IsSupported => implementation.Value != null; - /// - /// Current plugin implementation to use - /// - public static IStoreReview Current - { - get - { - var ret = implementation.Value; - return ret is null ? throw NotImplementedInReferenceAssembly() : ret; - } + /// + /// Current plugin implementation to use + /// + public static IStoreReview Current + { + get + { + var ret = implementation.Value; + return ret is null ? throw NotImplementedInReferenceAssembly() : ret; } + } - static IStoreReview CreateStoreReview() - { + static IStoreReview CreateStoreReview() + { #if ANDROID || IOS || MACCATALYST || MACOS || WINDOWS - return new StoreReviewImplementation(); + return new StoreReviewImplementation(); #else - return null; + return null!; #endif - } + } + + internal static Exception NotImplementedInReferenceAssembly() => + new NotImplementedException("This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation."); - internal static Exception NotImplementedInReferenceAssembly() => - new NotImplementedException("This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation."); - - } } diff --git a/src/StoreReview.Plugin/IStoreReview.shared.cs b/src/StoreReview.Plugin/IStoreReview.shared.cs index 8015ae9..157da6a 100644 --- a/src/StoreReview.Plugin/IStoreReview.shared.cs +++ b/src/StoreReview.Plugin/IStoreReview.shared.cs @@ -1,27 +1,24 @@ -using System.Threading.Tasks; +namespace Plugin.StoreReview.Abstractions; -namespace Plugin.StoreReview.Abstractions +/// +/// Interface for StoreReview +/// +public interface IStoreReview { - /// - /// Interface for StoreReview - /// - public interface IStoreReview - { - /// - /// Opens the store listing. - /// - /// App identifier. - Task OpenStoreListing(string appId); + /// + /// Opens the store listing. + /// + /// App identifier. + Task OpenStoreListing(string appId); - /// - /// Opens the store review page. - /// - /// App identifier. - Task OpenStoreReviewPage(string appId); + /// + /// Opens the store review page. + /// + /// App identifier. + Task OpenStoreReviewPage(string appId); - /// - /// Requests an app review. - /// - Task RequestReview(bool testMode); - } + /// + /// Requests an app review. + /// + Task RequestReview(bool testMode); } diff --git a/src/StoreReview.Plugin/StoreReview.Plugin.csproj b/src/StoreReview.Plugin/StoreReview.Plugin.csproj index 45232a7..bf91499 100644 --- a/src/StoreReview.Plugin/StoreReview.Plugin.csproj +++ b/src/StoreReview.Plugin/StoreReview.Plugin.csproj @@ -22,19 +22,21 @@ 1.0.0.0 - author - Copyright © author and contributors + James Montemagno + Copyright Refractored LLC and contributors True - https://github.com/jfversluis/Plugin.Maui.Feature - https://github.com/jfversluis/Plugin.Maui.Feature + Plugin.StoreReview + https://github.com/jamesmontemagno/storereviewplugin + https://github.com/jamesmontemagno/storereviewplugin git - dotnet-maui;maui;plugin; + dotnet-maui;maui;plugin;review;storereview;android;ios;windows;maccatalyst True true true snupkg - .NET MAUI Feature Plugin - Plugin.Maui.Feature provides the ability to do this amazing thing in your .NET MAUI application. + Store Review Plugin for .NET MAUI, iOS, Android, MacCatalyst, and Windows + Easily request a review or open the store page for your app. + Easily request a review or open the store page for your app. MIT True portable diff --git a/src/StoreReview.Plugin/StoreReviewImplementation.android.cs b/src/StoreReview.Plugin/StoreReviewImplementation.android.cs index 538e9bf..11f9a7c 100644 --- a/src/StoreReview.Plugin/StoreReviewImplementation.android.cs +++ b/src/StoreReview.Plugin/StoreReviewImplementation.android.cs @@ -1,133 +1,129 @@ -using Android.App; using Android.Content; +using Android.Gms.Tasks; using Android.OS; -using Android.Runtime; +using Microsoft.Maui.ApplicationModel; using Plugin.StoreReview.Abstractions; using Xamarin.Google.Android.Play.Core.Review; using Xamarin.Google.Android.Play.Core.Review.Testing; -using Android.Gms.Tasks; -using Microsoft.Maui.ApplicationModel; +namespace Plugin.StoreReview; -namespace Plugin.StoreReview +public class StoreReviewImplementation : Java.Lang.Object, IStoreReview, IOnCompleteListener { - /// - /// Implementation for Feature - /// - [Preserve(AllMembers = true)] - public class StoreReviewImplementation : Java.Lang.Object, IStoreReview, IOnCompleteListener + /// + /// Opens the store listing. + /// + /// App identifier. + public Task OpenStoreListing(string appId) => + OpenStoreReviewPage(appId); + + static Intent GetRateIntent(string url) { - /// - /// Opens the store listing. - /// - /// App identifier. - public Task OpenStoreListing(string appId) => - OpenStoreReviewPage(appId); - + var intent = new Intent(Intent.ActionView, Android.Net.Uri.Parse(url)); - Intent GetRateIntent(string url) + intent.AddFlags(ActivityFlags.NoHistory); + intent.AddFlags(ActivityFlags.MultipleTask); + if ((int)Build.VERSION.SdkInt >= 21) { - var intent = new Intent(Intent.ActionView, Android.Net.Uri.Parse(url)); - - intent.AddFlags(ActivityFlags.NoHistory); - intent.AddFlags(ActivityFlags.MultipleTask); - if((int)Build.VERSION.SdkInt >= 21) - { - intent.AddFlags(ActivityFlags.NewDocument); - } - else - { - intent.AddFlags(ActivityFlags.ClearWhenTaskReset); - } - intent.SetFlags(ActivityFlags.ClearTop); - intent.SetFlags(ActivityFlags.NewTask); - return intent; + intent.AddFlags(ActivityFlags.NewDocument); } + else + { + intent.AddFlags(ActivityFlags.ClearWhenTaskReset); + } + intent.SetFlags(ActivityFlags.ClearTop); + intent.SetFlags(ActivityFlags.NewTask); + return intent; + } - /// - /// Opens the store review page. - /// - /// App identifier. - public Task OpenStoreReviewPage(string appId) + /// + /// Opens the store review page. + /// + /// App identifier. + public Task OpenStoreReviewPage(string appId) + { + var url = $"market://details?id={appId}"; + try { - var url = $"market://details?id={appId}"; - try - { - var intent = GetRateIntent(url); - Application.Context.StartActivity(intent); - return System.Threading.Tasks.Task.FromResult(true); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine("Unable to launch app store: " + ex.Message); - } + var intent = GetRateIntent(url); + Application.Context.StartActivity(intent); + return System.Threading.Tasks.Task.FromResult(true); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("Unable to launch app store: " + ex.Message); + } - url = $"https://play.google.com/store/apps/details?id={appId}"; - try - { - var intent = GetRateIntent(url); - Application.Context.StartActivity(intent); - return System.Threading.Tasks.Task.FromResult(true); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine("Unable to launch app store: " + ex.Message); - } - return System.Threading.Tasks.Task.FromResult(false); + url = $"https://play.google.com/store/apps/details?id={appId}"; + try + { + var intent = GetRateIntent(url); + Application.Context.StartActivity(intent); + return System.Threading.Tasks.Task.FromResult(true); } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("Unable to launch app store: " + ex.Message); + } + return System.Threading.Tasks.Task.FromResult(false); + } - IReviewManager manager; - TaskCompletionSource tcs; - /// - /// Requests an app review. - /// - public async Task RequestReview(bool testMode) - { - tcs?.TrySetCanceled(); - tcs = new TaskCompletionSource(); + IReviewManager? manager; + TaskCompletionSource? tcs; + /// + /// Requests an app review. + /// + public async Task RequestReview(bool testMode) + { + tcs?.TrySetCanceled(); + tcs = new TaskCompletionSource(); - if (testMode) - manager = new FakeReviewManager(Application.Context); - else - manager = ReviewManagerFactory.Create(Application.Context); + if (testMode) + manager = new FakeReviewManager(Application.Context); + else + manager = ReviewManagerFactory.Create(Application.Context); - forceReturn = false; - var request = manager.RequestReviewFlow(); - request.AddOnCompleteListener(this); - var status = await tcs.Task; - manager.Dispose(); - request.Dispose(); + forceReturn = false; + var request = manager.RequestReviewFlow(); + request.AddOnCompleteListener(this); + var status = await tcs.Task; + manager.Dispose(); + request.Dispose(); - return status ? ReviewStatus.Succeeded : ReviewStatus.Error; - } + return status ? ReviewStatus.Succeeded : ReviewStatus.Error; + } - Activity Activity => - Platform.CurrentActivity ?? throw new NullReferenceException("Current Activity is null, ensure that the MainActivity.cs file is configuring Essentials in your source code so the StoreReview can use it."); + Activity Activity => + Platform.CurrentActivity ?? throw new NullReferenceException("Current Activity is null, ensure that .NET MAUI is configured for Essentials."); - bool forceReturn; - Android.Gms.Tasks.Task launchTask; - public void OnComplete(Android.Gms.Tasks.Task task) - { - if (!task.IsSuccessful || forceReturn) - { - tcs.TrySetResult(forceReturn); - launchTask?.Dispose(); + bool forceReturn; + Android.Gms.Tasks.Task? launchTask; + public void OnComplete(Android.Gms.Tasks.Task task) + { + if (!task.IsSuccessful || forceReturn) + { + tcs?.TrySetResult(forceReturn); + launchTask?.Dispose(); + return; + } + + try + { + if (task.GetResult(Java.Lang.Class.FromType(typeof(ReviewInfo))) is not ReviewInfo reviewInfo) + { + tcs?.TrySetResult(false); return; - } + } - try - { - var reviewInfo = (ReviewInfo)task.GetResult(Java.Lang.Class.FromType(typeof(ReviewInfo))); - forceReturn = true; - launchTask = manager.LaunchReviewFlow(Activity, reviewInfo); - launchTask.AddOnCompleteListener(this); - } - catch (Exception ex) - { - tcs.TrySetResult(false); - System.Diagnostics.Debug.WriteLine(ex.Message); - } - } + forceReturn = true; + launchTask = manager?.LaunchReviewFlow(Activity, reviewInfo); + launchTask?.AddOnCompleteListener(this); + } + catch (Exception ex) + { + tcs?.TrySetResult(false); + System.Diagnostics.Debug.WriteLine(ex.Message); + } } } \ No newline at end of file diff --git a/src/StoreReview.Plugin/StoreReviewImplementation.apple.cs b/src/StoreReview.Plugin/StoreReviewImplementation.apple.cs index 7dabc9b..938a2f6 100644 --- a/src/StoreReview.Plugin/StoreReviewImplementation.apple.cs +++ b/src/StoreReview.Plugin/StoreReviewImplementation.apple.cs @@ -1,127 +1,92 @@ -using Foundation; -using Plugin.StoreReview.Abstractions; - -using System; using System.Diagnostics; -using System.Threading.Tasks; -#if !__MACOS__ -using UIKit; -using System.Linq; -#endif +using Plugin.StoreReview.Abstractions; using StoreKit; -namespace Plugin.StoreReview +namespace Plugin.StoreReview; + +/// +/// Implementation for StoreReview +/// +[Preserve(AllMembers = true)] +public class StoreReviewImplementation : IStoreReview { - /// - /// Implementation for StoreReview - /// - [Preserve(AllMembers = true)] - public class StoreReviewImplementation : IStoreReview + /// + /// Opens the store listing. + /// + /// App identifier. + public Task OpenStoreListing(string appId) { - /// - /// Opens the store listing. - /// - /// App identifier. - public Task OpenStoreListing(string appId) - { -#if __IOS__ - var url = $"itms-apps://itunes.apple.com/app/id{appId}"; -#elif __TVOS__ - var url = $"com.apple.TVAppStore://itunes.apple.com/app/id{appId}"; -#elif __MACOS__ - var url = $"macappstore://itunes.apple.com/app/id{appId}?mt=12"; -#endif - try - { -#if __MACOS__ - AppKit.NSWorkspace.SharedWorkspace.OpenUrl(new NSUrl(url)); -#else - return UIApplication.SharedApplication.OpenUrlAsync(new NSUrl(url), new UIApplicationOpenUrlOptions()); -#endif - } - catch (Exception ex) - { - Debug.WriteLine("Unable to launch app store: " + ex.Message); - } - return Task.FromResult(false); - } + var url = $"itms-apps://itunes.apple.com/app/id{appId}"; - /// - /// Opens the store review page. - /// - /// App identifier. - public Task OpenStoreReviewPage(string appId) + try { -#if __IOS__ - var url = $"itms-apps://itunes.apple.com/app/id{appId}?action=write-review"; -#elif __TVOS__ - var url = $"com.apple.TVAppStore://itunes.apple.com/app/id{appId}?action=write-review"; -#elif __MACOS__ - var url = $"macappstore://itunes.apple.com/app/id{appId}?action=write-review"; -#endif - try - { -#if __MACOS__ - AppKit.NSWorkspace.SharedWorkspace.OpenUrl(new NSUrl(url)); -#else - return UIApplication.SharedApplication.OpenUrlAsync(new NSUrl(url), new UIApplicationOpenUrlOptions()); -#endif - } - catch (Exception ex) - { - Debug.WriteLine("Unable to launch app store: " + ex.Message); - } - - return Task.FromResult(false); + return UIApplication.SharedApplication.OpenUrlAsync(new NSUrl(url), new UIApplicationOpenUrlOptions()); + } + catch (Exception ex) + { + Debug.WriteLine("Unable to launch app store: " + ex.Message); } - /// - /// Requests an app review. - /// - public Task RequestReview(bool testMode) - { -#if __IOS__ - if (IsiOS103) - { - if (IsiOS14) - { - var windowScene = UIApplication.SharedApplication?.ConnectedScenes?.ToArray()?.FirstOrDefault(x => x.ActivationState == UISceneActivationState.ForegroundActive) as UIWindowScene; - if (windowScene != null) - { - SKStoreReviewController.RequestReview(windowScene); - return Task.FromResult(ReviewStatus.Unknown); - } - } - SKStoreReviewController.RequestReview(); - } -#elif __MACOS__ - using var info = new NSProcessInfo(); - if (ParseVersion(info.OperatingSystemVersion.ToString()) >= new Version(10, 14)) - { - SKStoreReviewController.RequestReview(); - } -#endif + return Task.FromResult(false); + } + + /// + /// Opens the store review page. + /// + /// App identifier. + public Task OpenStoreReviewPage(string appId) + { + var url = $"itms-apps://itunes.apple.com/app/id{appId}?action=write-review"; - return Task.FromResult(ReviewStatus.Unknown); + try + { + return UIApplication.SharedApplication.OpenUrlAsync(new NSUrl(url), new UIApplicationOpenUrlOptions()); + } + catch (Exception ex) + { + Debug.WriteLine("Unable to launch app store: " + ex.Message); } - internal static Version ParseVersion(string version) - { - if (Version.TryParse(version, out var number)) - return number; + return Task.FromResult(false); + } - if (int.TryParse(version, out var major)) - return new Version(major, 0); + /// + /// Requests an app review. + /// + public Task RequestReview(bool testMode) + { + if (IsiOS103) + { + if (IsiOS14) + { + var windowScene = UIApplication.SharedApplication?.ConnectedScenes?.ToArray()?.FirstOrDefault(x => x.ActivationState == UISceneActivationState.ForegroundActive) as UIWindowScene; + if (windowScene is not null) + { +#pragma warning disable CA1422 // Validate platform compatibility + SKStoreReviewController.RequestReview(windowScene); +#pragma warning restore CA1422 // Validate platform compatibility + return Task.FromResult(ReviewStatus.Unknown); + } + } +#pragma warning disable CA1422 // Validate platform compatibility + SKStoreReviewController.RequestReview(); +#pragma warning restore CA1422 // Validate platform compatibility + } + return Task.FromResult(ReviewStatus.Unknown); + } - return new Version(0, 0); - } + internal static Version ParseVersion(string version) + { + if (Version.TryParse(version, out var number)) + return number; -#if __IOS__ - bool IsiOS103 => UIDevice.CurrentDevice.CheckSystemVersion(10, 3); - bool IsiOS14 => UIDevice.CurrentDevice.CheckSystemVersion(14, 0); - bool IsiOS16 => UIDevice.CurrentDevice.CheckSystemVersion(16, 0); -#endif + if (int.TryParse(version, out var major)) + return new Version(major, 0); + return new Version(0, 0); } + + static bool IsiOS103 => UIDevice.CurrentDevice.CheckSystemVersion(10, 3); + static bool IsiOS14 => UIDevice.CurrentDevice.CheckSystemVersion(14, 0); } diff --git a/src/StoreReview.Plugin/StoreReviewImplementation.uwp.cs b/src/StoreReview.Plugin/StoreReviewImplementation.uwp.cs index 6005b04..b96b27d 100644 --- a/src/StoreReview.Plugin/StoreReviewImplementation.uwp.cs +++ b/src/StoreReview.Plugin/StoreReviewImplementation.uwp.cs @@ -1,113 +1,99 @@ -using Plugin.StoreReview.Abstractions; -using System; using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; -using Windows.Foundation; +using Plugin.StoreReview.Abstractions; using Windows.Services.Store; -using Windows.ApplicationModel.Store; -using System.Collections.Generic; -using Windows.System; -namespace Plugin.StoreReview +namespace Plugin.StoreReview; + +/// +/// Implementation for StoreReview +/// +public class StoreReviewImplementation : IStoreReview { /// - /// Implementation for StoreReview + /// Opens the store listing. /// - public class StoreReviewImplementation : IStoreReview + /// App identifier. + public Task OpenStoreListing(string appId) { - /// - /// Opens the store listing. - /// - /// App identifier. - public Task OpenStoreListing(string appId) + try { - try - { - return OpenUrl($"ms-windows-store://pdp/?ProductId={appId}"); - } - catch (Exception ex) - { - Debug.WriteLine("Unable to launch app store: " + ex.Message); - } - return Task.FromResult(false); + return OpenUrl($"ms-windows-store://pdp/?ProductId={appId}"); } + catch (Exception ex) + { + Debug.WriteLine("Unable to launch app store: " + ex.Message); + } + return Task.FromResult(false); + } - /// - /// Opens the store review page. - /// - /// App identifier. - public Task OpenStoreReviewPage(string appId) + /// + /// Opens the store review page. + /// + /// App identifier. + public Task OpenStoreReviewPage(string appId) + { + try { - try - { - return OpenUrl($"ms-windows-store://review/?ProductId={appId}"); - } - catch (Exception ex) - { - Debug.WriteLine("Unable to launch app store: " + ex.Message); - } - return Task.FromResult(false); + return OpenUrl($"ms-windows-store://review/?ProductId={appId}"); } + catch (Exception ex) + { + Debug.WriteLine("Unable to launch app store: " + ex.Message); + } + return Task.FromResult(false); + } -#if NET6_0_OR_GREATER - public static object Window { get; set; } -#endif - /// - /// Requests an app review. - /// - public async Task RequestReview(bool testMode) + public static object? Window { get; set; } + /// + /// Requests an app review. + /// + public async Task RequestReview(bool testMode) + { + try { - try - { - var context = StoreContext.GetDefault(); + var context = StoreContext.GetDefault(); -#if NET6_0_OR_GREATER - if(Window is null) - throw new NullReferenceException("WindowObject is null. Please set the WindowObject property before calling RequestReview."); - - var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(Window); - - WinRT.Interop.InitializeWithWindow.Initialize(context, hwnd); -#endif + if (Window is null) + throw new NullReferenceException("WindowObject is null. Please set the WindowObject property before calling RequestReview."); - var result = await context.RequestRateAndReviewAppAsync(); - return result.Status switch - { - StoreRateAndReviewStatus.Succeeded => ReviewStatus.Succeeded, - StoreRateAndReviewStatus.CanceledByUser => ReviewStatus.CanceledByUser, - StoreRateAndReviewStatus.Error => ReviewStatus.Error, - StoreRateAndReviewStatus.NetworkError => ReviewStatus.NetworkError, - _ => ReviewStatus.Error, - }; - } - catch(Exception ex) - { - Debug.WriteLine(ex); - return ReviewStatus.Error; - } - finally + var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(Window); + + WinRT.Interop.InitializeWithWindow.Initialize(context, hwnd); + + var result = await context.RequestRateAndReviewAppAsync(); + return result.Status switch { -#if NET6_0_OR_GREATER - Window = null; -#endif - } + StoreRateAndReviewStatus.Succeeded => ReviewStatus.Succeeded, + StoreRateAndReviewStatus.CanceledByUser => ReviewStatus.CanceledByUser, + StoreRateAndReviewStatus.Error => ReviewStatus.Error, + StoreRateAndReviewStatus.NetworkError => ReviewStatus.NetworkError, + _ => ReviewStatus.Error, + }; + } + catch (Exception ex) + { + Debug.WriteLine(ex); + return ReviewStatus.Error; } + finally + { + Window = null; + } + } - Task OpenUrl(string url) + static Task OpenUrl(string url) + { + try { - try - { - return Windows.System.Launcher.LaunchUriAsync(new Uri(url)).AsTask(); - - } - catch (Exception ex) - { - Debug.WriteLine("Unable to open store: " + ex.Message); - } + return Windows.System.Launcher.LaunchUriAsync(new Uri(url)).AsTask(); - return Task.FromResult(false); } + catch (Exception ex) + { + Debug.WriteLine("Unable to open store: " + ex.Message); + } + + return Task.FromResult(false); } }