Search code examples
swiftxmlpostgetput

sending get / put / post in swift


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.


Solution

  • 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
    
                }