问题描述
我在使用 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");
}