Let’s say, you’ve to send following request from iOS app.
curl -X POST \
https://some.server.com/api/endpoint \
-H 'cache-control: no-cache' \
-F 'signup[email]=user@mail.com' \
-F 'signup[password]=password' \
-F product_id=productidhere \
-F transaction_id=sometransactionid
Here is the code to achieve it.
struct SignUpData {
let userEmail: String
let passData: String
let productId: String
let transactionId: String
var parameters: [String: Any] { [
"signup[email]": userEmail,
"signup[password]": passData,
"product_id": productId,
"transaction_id": transactionId,
"receipt": receipt
]
}
}
struct SignUpService {
func signup(
with data: SignUpData,
handler: @escaping (Swift.Result<Void, Error>) -> Void
) {
// 1. create URL
guard
let url = URL(string: "https://some.server.com/api/endpoint")
else { return }
// 2. create request
var request = URLRequest(url: url)
// 3. set required headers
request.setValue("no-cache", forHTTPHeaderField: "cache-control")
// 4. set POST method
request.httpMethod = "POST"
// 5. get percent encoded data of parameters
// - for `percentEncoded()` see code below this block.
let body = data.parameters.percentEncoded()
request.httpBody = body
// 6. start task & handle response
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else {
// handle error here or no data here
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
// do something if statuscode is not 200
} else {
// handle successful response here
}
}.resume()
}
}
Supporting percent Encoding with following code block
extension Dictionary {
func percentEncoded() -> Data? {
return map { key, value in
let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
return escapedKey + "=" + escapedValue
}
.joined(separator: "&")
.data(using: .utf8)
}
}
extension CharacterSet {
static let urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
var allowed = CharacterSet.urlQueryAllowed
allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
return allowed
}()
}