我应该在处理 HTTP 错误后创建新的 NSURLSessionTask 吗?

Should I create new NSURLSessionTask after handling HTTP error?

在我的 Xamarin.iOS 应用中,我想在因 http 错误而失败后重试上传。

但是我不知道如何实现。

我在想我应该在每次完成并出现 http 错误时继续创建一个新任务吗? 这是正确的实施方式吗?

NSUrlSessionTaskDelegate:

    public async override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error)
    {
        if (task.Response != null)
        {
            if (task.Response is NSHttpUrlResponse httpResponse)
            {
                if (httpResponse.StatusCode == 200)
                {
                    //some clean up logic here
                }
                else if (httpResponse.StatusCode > 400 && httpResponse.StatusCode < 500)
                {
                    //what to do to upload again?
                }
                else
                {
                    var applicationException = new ApplicationException("Server returned 500");
                    Crashes.TrackError(applicationException);
                }
            }
        }
    }

AppDelegate:

    public NSUrlSession InitBackgroundSession()
    {
        string identifier = "com.uba.BookingUploadBackgroundSession";
        INSUrlSessionDelegate backgroundUploadSessionDelegate = new BackgroundBookingUploadSessionDelegate();

        using (var config = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration(identifier))
        {
            config.HttpMaximumConnectionsPerHost = 4;
            config.TimeoutIntervalForResource = 300.0; //5mins
            return NSUrlSession.FromConfiguration(config, backgroundUploadSessionDelegate, new NSOperationQueue());
        }
    }

    //gets called when user taps Submit from ViewController
    public void UploadFile(BookingDTO newBookingDTO)
    {
        //logic to create NSMutableUrlRequest omitted

        var uploadTask = session.CreateUploadTask(request, NSUrl.FromFilename(filename));
        uploadTask.TaskDescription = newBookingDTO.ClientId;  //we need the booking id so we can delete it later
        uploadTask.Resume();
     }

我接受任何 C# 答案,Swift 或 Objective-C

NSURLSessionTask 有四个不同的 states.As,如下图所示。

当上传finished.Whether成功或失败时,状态将变为已完成。而属性 CurrentRequest 将为空。您只能处理 task.So 的响应。我认为您可以使用相同的会话但必须创建一个新的 task.You 可以使用 Notification 发送消息.

NSUrlSessionTaskDelegate:

public async override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error)
{
    if (task.Response != null)
    {
        if (task.Response is NSHttpUrlResponse httpResponse)
        {
            if (httpResponse.StatusCode == 200)
            {
                //some clean up logic here
            }
            else if (httpResponse.StatusCode > 400 && httpResponse.StatusCode < 500)
            {
                //send notification here 
                NSNotification notification = NSNotification.FromName("UploadFail",null,null);
                NSNotificationCenter.DefaultCenter.PostNotification(notification); 

            }
            else
            {
                var applicationException = new ApplicationException("Server returned 500");
                Crashes.TrackError(applicationException);
            }
        }
    }
}

并且在 AppDelegate.cs 中,在方法 FinishedLaunching

中添加通知
 NSNotificationCenter.DefaultCenter.AddObserver(this,new Selector("UploadAgain"),new NSString("UploadFail"),null);

[Export("UploadAgain")]
void UploadAgain()
{
   //call your upload code here
}