I’ve been working on transferring some image data in my iOS app using a Xojo.Net.HTTP Socket and a POST command. I had trouble and posted about it elsewhere. Thanks to @Andrew_Lambert, I found out that Xojo does not create multi-part form data for HTML when you set the content type. You have to do this yourself. Andrew had written a method but it was for the legacy HTTPSocket and didn’t work with newer sockets such as the URLConnection or Xojo.Net.HTTPSocket for iOS. I have modified Andrew’s code to make it compatible with the Xojo.Net.HTTPSocket and it should work fine for the URLConnection as well - just need to change the signature in the method.
Pass in your content sections as Dictionary pairs.
I hope this is of use to people.
Public Sub SetFormData(extends sock as Xojo.Net.HTTPSocket, contenttype as text, FormData as Xojo.Core.Dictionary, Boundary as Text = "")
// Original code for legacy HTTPSocket written by Andrew Lambert
// https://www.boredomsoft.org/file-uploads-form-encodings-and-xojo.bs
//
// This code modified by Jon Ogden, Just Add Software, LLC - September 2020 for iOS and Xojo.Net.HTTPSocket
// Could also be used on URLConnection - need to modify the signature and make sure you use Xojo.Core - Using statement included
//
// Added in the ability to set the content type in the parameters to the method. This was hard coded previously.
// Added the ability to send and process data in a memory block - the original method handled text and folder items.
//
// Code properly creates multi-part form data.
//
Using Xojo.Core
// if the user doesn't include a boundary string then create one.
If Boundary.Trim = "" Then
Dim m as MemoryBlock = TextEncoding.ASCII.ConvertTextToData(Microseconds.ToText)
Dim m2 as MemoryBlock = MD5(m)
Dim MD5Digest as Text = TextEncoding.ASCII.ConvertDataToText(MD5(m),True)
Boundary = "--" + EncodeHex(MD5(m)).RIght(24)+ "-bOuNdArY"
End If
// create some of the local variables
Static CRLF As Text = &u0D+&u0A
Dim data As New MemoryBlock(0)
Dim out As New BinaryStream(data)
// Go through each section of the form data and each key/value pair detecting what it is
// and writing out the appropriate text.
For Each d as DictionaryEntry in FormData
out.WriteText("--" + Boundary + CRLF, TextEncoding.ASCII)
Dim info As Xojo.Introspection.TypeInfo
info = Xojo.Introspection.GetType(d.value)
If Info.Name.IndexOf("Text") <> -1 Then
out.WriteText("Content-Disposition: form-data; name=""" + d.key + """" + CRLF + CRLF, TextEncoding.ASCII)
out.WriteText(d.value + CRLF, Xojo.Core.TextEncoding.ASCII)
ElseIf d.Value IsA FolderItem Then
Dim file As FolderItem = d.Value
out.WriteText("Content-Disposition: form-data; name=""" + d.key + """; filename=""" + File.Name + """" + CRLF, TextEncoding.ASCII)
out.WriteText("Content-Type: "+contenttype+ CRLF + CRLF, TextEncoding.ASCII)
Dim bs As BinaryStream = BinaryStream.Open(File,BInaryStream.LockModes.Read)
out.Write(bs.Read(bs.Length))
out.WriteText(CRLF, Xojo.Core.TextEncoding.ASCII)
bs.Close
ElseIF d.value IsA MemoryBlock Then
Dim m as MemoryBlock = d.Value
Dim t as Text ="Content-Disposition: form-data; name=""" + d.key + """; filename=""blob"""
out.WriteText("Content-Disposition: form-data; name=""" + d.key + """; filename=""blob""" + CRLF, Xojo.Core.TextEncoding.ASCII)
out.WriteText("Content-Type: "+contenttype+ CRLF + CRLF,TextEncoding.ASCII)
out.Write(m)
out.WriteText (CRLF,TextEncoding.ASCII)
End If
Next
out.WriteText("--" + Boundary + "--" + CRLF,TextEncoding.ASCII)
out.Close
sock.SetRequestContent(data, "multipart/form-data; boundary=" + Boundary)
End Sub