Multipart upload NSURLSession?

MittchelvanVlietMittchelvanVliet USUniversity ✭✭

Hi there,

For a project we need to upload images to a server plus a JSON object. The api requires multipart form.

I would really like to use NSURLSessionTaskDelegate for this since it enables backgrounding and it would be cool to finish uploads while the app is in background. It also gives me progress indication.

So, my question is.. is it possible to do multipart file upload + a json object with nsurlsession?

Posts

  • NuninzNuninz USMember ✭✭

    have a look at this url:
    http://hayageek.com/ios-nsurlsession-example/

    and this one:

    http://stackoverflow.com/questions/18059588/httpclient-multipart-form-post-in-c-sharp

    you will have to write the request yourself as you can see on that link. It's not hard but it requires some work. In iOS you could start with something like

    NSMutableUrlRequest request = new NSMutableUrlRequest (url);
    request.HttpMethod = "POST";

    request ["Content-Type"] = "multipart/form-data;";

  • MittchelvanVlietMittchelvanVliet USUniversity ✭✭
    edited December 2015

    @Nuninz thanks!

    How do I accept your answer?

  • DannyCDannyC US ✭✭✭✭

    @MittchelvanVliet check my repo on Github below for a Xamarin.iOS example. Check the AppDelegate method PrepareUpload() where I initiate an UploadTask.

    https://github.com/dannycabrera/SimpleBackgroundUpload

  • NuninzNuninz USMember ✭✭

    I knew I had used some code that I found but it was a while ago so I couldn't remember. Thanks @DannyC , I've used that code before and it works just fine :)

  • DannyCDannyC US ✭✭✭✭

    No problem @Nuninz, was a PIA to get it going so sharing the knowledge :)

  • MittchelvanVlietMittchelvanVliet USUniversity ✭✭
    edited December 2015

    @DannyC Does this code work with multiple upload's at same time? Sinds the 'BodyData' file can't be written twice...?

  • DannyCDannyC US ✭✭✭✭

    @MittchelvanVliet if you are going to queue multiple uploads make sure each one has it's own bodypart file with a unique name. The SimpleBackgroundUpload is just an example.

  • DannyCDannyC US ✭✭✭✭

    Received an email about a post you did asking about timeouts but seems you might have removed/edited that post. Since you are using NSUrlSession iOS will enforce App Transport Security (ATS) so make sure to add the required keys to your plist file.

    http://developer.xamarin.com/guides/ios/platform_features/introduction_to_ios9/ats/

  • MittchelvanVlietMittchelvanVliet USUniversity ✭✭

    @DannyC I do have some issues sending along other information. I followed multiple examples online, but can't seem to get it working.

    My code:
    `// For demo purposes file is attached to project as "Content" and PDF is 8.1MB.
    var fileToUpload = fileName;

                if(File.Exists(fileToUpload)) 
                {
                    var boundary = "SportuondoFormBoundary";
                    var bodyPath = Path.Combine (Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "BodyData.tmp");
    
                    // Create request
                    NSUrl uploadHandleUrl = NSUrl.FromString ("google.com");
                    NSMutableUrlRequest request = new NSMutableUrlRequest (uploadHandleUrl);
                    request.HttpMethod = "POST";
                    request ["Content-Type"] = "multipart/form-data; boundary=" + boundary;
                    request ["FileName"] = Path.GetFileName(fileToUpload);
    
                    // Userid
                    System.Text.StringBuilder sb = new System.Text.StringBuilder("");
                    sb.AppendFormat("--{0}\r\n",boundary);
                    sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n", "UploadByUserId");
                    sb.AppendFormat("{0}\r\n", "eaabf6d6-c24b-4b86-ae3e-5e570dc0b9f4");
    
                    sb.AppendFormat("--{0}\r\n", boundary);
                    sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\"; filename=\"fitImage.jpg\"\r\n", "file");
                    sb.Append("Content-Type: image/jpeg\r\n\r\n");
    
                    // Delete any previous body data file
                    if (File.Exists(bodyPath))
                        File.Delete(bodyPath);
    
                    // Write file to BodyPart
                    var fileBytes = File.ReadAllBytes (fileToUpload);
                    using (var writeStream = new FileStream (bodyPath, FileMode.Create, FileAccess.Write, FileShare.Read)) {
                        writeStream.Write (Encoding.Default.GetBytes (sb.ToString ()), 0, sb.Length);
                        writeStream.Write (fileBytes, 0, fileBytes.Length);
    
                        sb.Clear();
                        sb.Append("\r\n");
                        sb.AppendFormat("--{0}--\r\n", boundary);
                        writeStream.Write (Encoding.Default.GetBytes (sb.ToString ()), 0, sb.Length);
                    }
    
                    sb.Clear();
    
                    sb = null;
                    fileBytes = null;
    
                    // Creating upload task
                    var uploadTask = session.CreateUploadTask(request, NSUrl.FromFilename(bodyPath));
                    Console.WriteLine ("New TaskID: {0}", uploadTask.TaskIdentifier);
    
                    // Start task
                    uploadTask.Resume (); `
    

    The bodyData file: http://pastebin.com/Z1jW3VFS

    What am I doing wrong here?

  • MittchelvanVlietMittchelvanVliet USUniversity ✭✭

    I'm having trouble to actually get a right response in the didcomplete. It returns null error's while I should get unauthorized, cause I'm not authorizing yet.

  • MittchelvanVlietMittchelvanVliet USUniversity ✭✭

    I managed to fix the issue by applying the cookies, cause I found out that this was the problem.. but I'm still not receiving the 401's in my DidComplete, any ideas?

  • DannyCDannyC US ✭✭✭✭

    If you don't get any errors in Xamarin's Application Output window I suggest you open Xcode Organizer and check your device's output log. Really no way to guess what the problem is without being able to debug.

  • MittchelvanVlietMittchelvanVliet USUniversity ✭✭

    @DannyC I mean in the DidCompleteWithError I never get an error code. I should receive an 401, but that never happens.. the error is always null even though there is one.

Sign In or Register to comment.