Swift 5: Send HTTP POST Request with XML code to API

Hi Forums

I have been trying to work with this snippet but seems like I can't get it just right. I have added an explain here below as I can't post an image of what I'm trying to achieve.

This should send the XML commands to my server API and initiate an Environment called "Animals.hwe" to be shown on a videowall.


note: the xmlcommand URL is changed because of the http not being allowed.


My test code...



Code Block
import UIKit
import SwiftUI
let session = URLSession(configuration: .default)
let url = URL(string: "http........://192.168.0.196:8000/xmlcommand")
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "<?xml version=\"1.0\"encoding=\"UTF-8\"?><Commands><command> type=\"open\"><name>environments/Animals.hwe</name><id>a1</id></command></Commands>".data(using: .utf8)
let task = session.dataTask(with: request) { data, response, error in
  // do something with the result
}
task.resume() // <- otherwise your network request won't be started


With Rested App on Mac I can make the "POST" work fine with these settings:



http. ..... ://192.168.0.196:8000/xmlcommand .................... POST

Use Custom HTTP body - HTTPBody:

Code Block
<?xml version="1.0" encoding="UTF-8"?>
<Commands>
<command type="open">
<name>environments/Animals.hwe</name>
<id>a1</id>
</command>
</Commands>



Result from Rested application that works with the XML code...



POST /xmlcommand
Response time: 24 ms


Request Headers & Body

Accept: */*
Accept-Encoding: gzip, deflate
Content-Type: text/plain
Accept-Language: en-us

Code Block
<?xml version="1.0" encoding="UTF-8"?>
<Commands>
<command type="open">
<name>environments/Animals.hwe</name>
<id>a1</id>
</command>
</Commands>


Response Headers

HTTP/1.1 200 OK
Date: Tue, 27 Oct 2020 18:03:53 GMT
Cache-Control: no-cache
Transfer-Encoding: Identity


Not sure what goes wrong in my code but seems like the XML code does not reach the server API correctly.

Any ideas would be greatly appreciated.

Thanks
Michael
Accepted Answer

My test code...

On which environment have you tested your code? Xcode Playground, Command Line Tool project or something else?
Do you have some code to wait for response?

Some other points:
  • Have you re-checked the URL used for testing?

  • Have you tried adding Content-Type: header to your request?

Code Block
request.setValue("text/plain", forHTTPHeaderField: "Content-Type") // I guess this can be "text/xml"



Hi OOPer

I'm testing this on PlayGrounds for now, and will move into Xcode when this request is working to make some Buttons that can issue these POST's

No I do only have the snippet as shown, I have to admit I'm fairly new to Xcode and Swift.

/Michael
Hi OOPer

Thank your for your hint! This actually solved the problem, I was missing a space in my XML data within the code!


Have you re-checked the URL used for testing?


Code Block
import UIKit
import SwiftUI
let session = URLSession(configuration: .default)
let url = URL(string: "http.............://192.168.0.196:8000/xmlcommand")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
//request.setValue("text/xml", forHTTPHeaderField: "Content-Type") // I guess this can be "text/xml"
// ERROR Line
//request.httpBody = "<?xml version=\"1.0\"encoding=\"UTF-8\"?><Commands><command> type=\"open\"><name>environments/Animals.hwe</name> <id>a1</id></command></Commands>".data(using: .utf8)
// Working line
request.httpBody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Commands><command type=\"open\"><name>environments/Animals.hwe</name><id>a1</id></command></Commands>".data(using: .utf8)
let task = session.dataTask(with: request) { data, response, error in
    // do something with the result
}
task.resume() // <- otherwise your network request won't be started


Wrong line missing the space
Code Block
<?xml version=\"1.0\"encoding=\"UTF-8\"?>


Corrected line with a space before encoding.
Code Block
<?xml version=\"1.0\" encoding=\"UTF-8\"?>


I also tried your other suggestions, but it looks like this was the only problem.

Pretty cool now I can get on into Xcode and make some buttons to fire these commands to my API.

Thank you

Regards
Michael

I'm testing this on PlayGround

I do only have the snippet as shown

Thanks for clarifying.

Can you try this code on the Playground and tell us what you get?
Code Block
import UIKit
import SwiftUI
let session = URLSession(configuration: .default)
let url = URL(string: "https://apple.com")! //<-
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("text/plain", forHTTPHeaderField: "Content-Type") //<-
request.httpBody = "<?xml version=\"1.0\"encoding=\"UTF-8\"?><Commands><command> type=\"open\"><name>environments/Animals.hwe</name><id>a1</id></command></Commands>".data(using: .utf8)
let task = session.dataTask(with: request) { data, response, error in
// do something with the result
print(data)
if let data = data {
print(String(data: data, encoding: .utf8))
} else {
print("no data")
}
}
task.resume()
import PlaygroundSupport //<-
PlaygroundPage.current.needsIndefiniteExecution = true //<-


I also tried your other suggestions, but it looks like this was the only problem.

Happy to hear you have solved your issue.
Please ignore my last reply, which is something I would try when communications code does not work.
Swift 5: Send HTTP POST Request with XML code to API
 
 
Q