2

I'm using

SKStoreReviewController.RequestReview ();

in a dependency service for Xamarin.Forms. However this is now deprecated from iOS 14. And I want to know how to integrate with the new UIWindowScene

requestReview(in windowScene: UIWindowScene)

in Xamarin.Forms

Shubham Tyagi
  • 798
  • 6
  • 21

2 Answers2

1

First, you can try to add SKStoreReviewController.RequestReview(Window.WindowScene) in the FinishedLaunching method of your xxx.ios->AppDelegate.cs; start the project to see if it is correct.

If the above method goes wrong, using DependencyService is the right way to go.

Here is the interface code:

 public interface MyInterface
{
     void RequestReview();
}

Here is the implementation method of the interface in ios:

[assembly: Dependency(typeof(MyInterfaceImpl))]
namespace App19.iOS
{
    public class MyInterfaceImpl : MyInterface
    {
        public void RequestReview()
        {
           var myv = UIDevice.CurrentDevice.CheckSystemVersion(14, 0);
            if (myv)
            {
                UIWindow window = UIApplication.SharedApplication.Delegate.GetWindow();
            SKStoreReviewController.RequestReview(window.WindowScene);
            }
            else 
            {
                SKStoreReviewController.RequestReview();
            }
        }
    }
}

You can call it in the OnStart method inside APP.xaml.cs:

 protected override void OnStart()
    {
        if (Device.RuntimePlatform == Device.iOS)
        {
            DependencyService.Get<IReviewService>().RequestReview();
        }
    }
Wen xu Li
  • 1,698
  • 1
  • 4
  • 7
0

I might have a solution:

using StoreKit;
using UIKit;

public void RequestReview(){
    var scene = UIApplication.SharedApplication.KeyWindow.WindowScene;

    if (scene is null)
    {
        //handle the scene being null here
        return;
    }

    SKStoreReviewController.RequestReview(scene);
}

I've found multiple ways of getting the current scene and they both worked when I tested them:

var scene = UIApplication.SharedApplication.KeyWindow.WindowScene;

var alsoScene = UIApplication.SharedApplication.Delegate.GetWindow()?.WindowScene;

You can read more about the difference between the two in this issue

The complete solution where you check the iOS version in order to call the right thing might look like this

using StoreKit;
using UIKit;

public void RequestReview()
{
    var isIos14OrAbove = UIDevice.CurrentDevice.CheckSystemVersion(14, 0);
    if (isIos14OrAbove)
    {
        var scene = UIApplication.SharedApplication.KeyWindow.WindowScene;

        if (scene is null)
        {
            //handle the scene being null here
            return;
        }

        SKStoreReviewController.RequestReview(scene);
    }
    else
    {
        SKStoreReviewController.RequestReview();
    }
}

Hope this helps.

Michal Diviš
  • 2,008
  • 12
  • 19
  • I think this function will fail if the scene is empty. – Wen xu Li Jan 27 '22 at 07:40
  • @WenxuLi-MSFT Would the `UIApplication.SharedApplication.Delegate.GetWindow()?.WindowScene` work better in that case? – Michal Diviš Jan 27 '22 at 07:46
  • The reason for the empty is that the project loads xxx.ios first and then runs the Forms file. So I call the method after FinishedLaunching executes. In this way, you can avoid the problem of null values that will not take effect. – Wen xu Li Jan 27 '22 at 08:12
  • The main thing is to avoid the occurrence of null values, and there cannot be a situation where the null value will not take effect. – Wen xu Li Jan 27 '22 at 08:16
  • Thanks for the tip. However, it seems pretty obvious that you wouldn't call the `RequestReview` method before the app launches.. I'm guessing the most sensible usage of the `RequestReview` method would be after `OnStartup` or later, after the user has been using the app for a while. No reason to call it before the app launches. – Michal Diviš Jan 27 '22 at 08:21
  • After FinishedLaunching method. – Wen xu Li Jan 27 '22 at 08:24