In my Xamarin.iOS app, I want to retry an upload after a failure due to http error.
But I'm not sure how to implement.
I was thinking I should just keep creating a new task every time it completes with an http error? Is this the correct way to implement?
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();
}
I'll accept any answer in C#, Swift or Objective-C
NSURLSessionTask has four different states.As shown in the following image.
When the upload finished.Whether success or fail,the states will become Completed.And the property CurrentRequest will be null. You can only handle the Response of the task.So .I think you can use the same session but have to create a new task.You can use the Notification to send message.
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);
}
}
}
}
And in AppDelegate.cs , add the notification in method FinishedLaunching
NSNotificationCenter.DefaultCenter.AddObserver(this,new Selector("UploadAgain"),new NSString("UploadFail"),null);
[Export("UploadAgain")]
void UploadAgain()
{
//call your upload code here
}