I can easily issue a GET request and it returns (as expected) JSON data that is decoded to myDataModel object:
class func getData(completionHandler: @escaping (myDataModel?, Error?) -> Void)
{
let url = "https://example.com/api/someResource?ws_key=ABC...XYZ"
if let myUrl = URL(string: url)
{
URLSession.shared.dataTask(with: myUrl)
{
(data, response, err) in
if let data = data
{
do
{
let result = try JSONDecoder().decode(myDataModel.self, from: data)
completionHandler(result, nil)
}
catch let JSONerr
{
completionHandler(nil, JSONerr)
}
}
}.resume()
}
}
This work fine, so GET is no problem. (PS. the above has been simplified and modified.)
Likewise, I can issue a POST request and it returns (as expected) JSON data, when I use parameters like key1=value1&key2=value2
. (I read that the default POST Content-Type
is application/x-www-form-urlencoded
.)
However, in another application I need to POST a piece of XML. After many tries and getting many errors, the approach I'm using is to: Set the header Content-Type
to text/xml; charset=utf-8
; Have no parameters and send the XML as the request body. I use a refined method:
PostHTTP(url: "https://example.com/api/someResource?ws_key=ABC...XYZ",
parameters: nil,
headers: ["Content-Type": "text/xml; charset=utf-8", "Content-Length": "\(xml.count)"],
body: "\(xml)") { (result) in ... }
(I image that you can determine what happens behind the scenes.)
For the POST request, to send a piece of XML:
Do I need to set the Content-Length
or is this automatic?
Can I send parameters with the XML?
What headers (like Content-Type
) do I require?
What structure (eg. xml=<?xml
...) and encoding (eg. addingPercentEncoding
) do I require?
Also I need to PUT data and I have similar method. The response from my attempt has the error
String could not be parsed as XML, XML length: 0
For a PUT request:
What headers (like Content-Type
) do I require?
What structure (eg. xml=<?xml
...) and encoding (eg. addingPercentEncoding
) do I require?
Since I have tried many ways, an example of both PUT and POST would be ideal.
If you want to send data of XML
you can do this in both PUT
and POST
It does not have to be determined Content-Length
But you must add Content-Type
let req = NSMutableURLRequest(url: URL(string:"myUrl")!)
req.httpMethod = "POST"
req.setValue("application/xml;charset=utf-8;", forHTTPHeaderField: "Content-Type")
req.setValue("application/xml;", forHTTPHeaderField: "Accept")
var postBody = Data()
if let anEncoding = ("<?xml version='1.0' encoding='UTF-8'?>").data(using: .utf8) {
postBody.append(anEncoding)
}
if let anEncoding = "<Request>".data(using: .utf8) {
postBody.append(anEncoding)
}
if let anEncoding = "<test>\(123)</test>".data(using: .utf8) {
postBody.append(anEncoding)
}
if let anEncoding = "</Request>".data(using: .utf8) {
postBody.append(anEncoding)
}
req.httpBody = postBody
req.setValue("\(postBody.count)", forHTTPHeaderField: "Content-Length")
URLSession.shared.dataTask(with: req as URLRequest) { (data, urlreq, error) in
}