I need to upload a file from my app to my ASP.NET WEB API backend. The HTTP POST request for the same is authenticated. Normally I do such Posts with HTTPWEBREQUEST class. And add token to request header as request.Headers.Set(HttpRequestHeader.Authorization,"Bearer "+ token);
Now I need to do the same in a background Service as I don't want the user to wait with loading screen until transfer finishes. I am trying backgrounding in ios for the first time. Since I am targeting devices above IOS 7, I understood that I should be going for BackGround Transfer Service by implementing a NSUrlSession. I checked out the samples and found one to download a file with NSUrlSessionDownloadTask. It is similar to the way we download a file directly from it's URL using Webclient class. I also know that there is NSUrlSessionUploadTask for uploading files. But could not find an implementation in which I can POST my custom JSON which includes my upload file as byte array using NSUrlSessionUploadTask. I am only familiar with using HTTPWEBREQUEST and WEBCLIENT. Please provide me an example of how I can post my Custom Json in background with Headers for authentication.
This is what I have tried
I attempted to acheive this by refering to monotouch Downloading in background examples and obj-c NSMutableURLRequest POST examples.
var jsonstr = JsonConvert.SerializeObject(imgvm);
byte[] bytes = Encoding.UTF8.GetBytes(jsonstr);
NSUrlSession session = null;
NSUrlSessionConfiguration configuration = NSUrlSessionConfiguration.BackgroundSessionConfiguration ("com.KeepCard.BackgroundSession");
session = NSUrlSession.FromConfiguration (configuration, (NSUrlSessionDelegate) new MySessionDelegate(), new NSOperationQueue());
const string UploadURLString = "**************";
NSUrlSessionUploadTask uploadTask;
NSUrl uploadURL = NSUrl.FromString (UploadURLString);
NSMutableUrlRequest requests = new NSMutableUrlRequest (uploadURL);
requests.HttpMethod="POST";
NSData bodyData = NSData.FromArray(bytes);
Dictionary<string,string> nsmd = new Dictionary<string, string> ();
nsmd.Add("Content-Type","application/json");
nsmd.Add("Content-Length",bytes.Length.ToString());
nsmd.Add("Authorization","Bearer "+token);
// nsmd.Add("Accept","*/*");
foreach (var header in nsmd)
{
requests[header.Key] = header.Value;
}
uploadTask = session.CreateUploadTask (requests);
imgvm is the viewmodel and jsonstr is the JsonString to be Posted. This is my NSUrlSessionTaskDelegate
public class MySessionDelegate : NSUrlSessionTaskDelegate
{
public override void DidFinishEventsForBackgroundSession (NSUrlSession session)
{
var appDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;
// Handle new information, update UI, etc.
// call completion handler when you're done
if (appDelegate.backgroundSessionCompletionHandler != null) {
NSAction handler = appDelegate.backgroundSessionCompletionHandler;
appDelegate.backgroundSessionCompletionHandler = null;
handler.Invoke ();
}
}
public override void DidReceiveChallenge (NSUrlSession session, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
{
Console.WriteLine ("Check Here");
}
public override void DidReceiveChallenge (NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
{
Console.WriteLine ("Check Here");
}
public override void DidBecomeInvalid (NSUrlSession session, NSError error)
{
Console.WriteLine ("Check Here");
}
public override void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, NSError error)
{
Console.WriteLine ("Check Here");
}
}
Also I have these in my AppDelegate
public override void HandleEventsForBackgroundUrl (UIApplication application, string sessionIdentifier, NSAction completionHandler)
{
this.backgroundSessionCompletionHandler = completionHandler;
}
Please point out to me what am I doing wrong. Do I have to enable background mode in info.plist ? I did not enable because none of the modes specified matched "Background Transfer Service. When I run now the execution comes upto session.CreateUploadTask (requests); and then the app stops without any exception