Xamarin.iOS 应用程序询问权限时来自 http 请求的 OperationCanceledException 在 AppDelegate.cs 中在场景委托中在您的视图控制器中

问题描述

我在使用 Xamarin.iOS 应用时遇到问题。在启动时,我向服务器发送请求以进行授权。同时,应用程序会询问用户是否有权向他们发送通知。看起来应用程序进入前台并使用 OperationCanceledException 中断连接。由于这个问题,我无法对用户进行身份验证。对于解决方法,我在捕获 OperationCanceledException 时发出了第二个请求。正因为如此,有时用户会获得两次授权。在这种情况下,我如何在不取消的情况下发送请求?

    private async Task<string> PostAndHandleHttpRequestAsync(Dictionary<string,string> content)
    {
        var cancellationTokenSource = new CancellationTokenSource();
        cancellationTokenSource.CancelAfter(15000); 
        CancellationToken token = cancellationTokenSource.Token;

        var newClient = new HttpClient();
        var contentSerialize = JsonConvert.SerializeObject(content);
        try
        {
            var postAsyncResult = await newClient.PostAsync(GlobalSettings.urlToPHP,new StringContent(contentSerialize),token);
            var responseBody = await postAsyncResult.Content.ReadAsstringAsync();
            return responseBody;
        }
        catch (OperationCanceledException c)
        {
            // onetime retry
            if (cancellationCounter == 0)
            {
                //Console.WriteLine("second");
                cancellationCounter = 1;
                var postAsyncResult = await newClient.PostAsync(GlobalSettings.urlToPHP,token);
                var responseBody = await postAsyncResult.Content.ReadAsstringAsync();
                return responseBody;
            }
            else
            {
                cancellationCounter = 0;
                return "Cancel";
            }
            return "Cancel";
        }
        catch (Exception e)
        {
            Console.WriteLine("Error PostAndHandleHttpRequestAsync " + e.Message);
            return "Error";
        }
    }

解决方法

当应用程序从后台进入前台时,您可以再次发布请求。

在 AppDelegate.cs 中

@mixin

在场景委托中

public override void WillEnterForeground(UIApplication application)
        {
            base.WillEnterForeground(application);

            if(!UIDevice.CurrentDevice.CheckSystemVersion(13,0))
            {
                NSNotificationCenter.DefaultCenter.PostNotificationName("willActive",null);
            }          
        }

在您的视图控制器中

[Export ("sceneWillEnterForeground:")]
public void WillEnterForeground (UIScene scene)
{
    NSNotificationCenter.DefaultCenter.PostNotificationName("willActive",null);

    // Called as the scene transitions from the background to the foreground.
    // Use this method to undo the changes made on entering the background.
}
    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);

        NSNotificationCenter.DefaultCenter.AddObserver(new NSString("willActive"),(notification)=> {
        
           if (cancellationCounter == 1)
            {
                //request again
            }
        
        });

    }


    public override void ViewWillDisappear(bool animated)
    {
        base.ViewWillDisappear(animated);

        NSNotificationCenter.DefaultCenter.RemoveObserver(this,"willActive");

    }