Skip to content

Instantly share code, notes, and snippets.

@abhi21git
Last active February 19, 2024 12:23
Show Gist options
  • Star 40 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save abhi21git/3dc611aab9e1cf5e5343ba4b58573596 to your computer and use it in GitHub Desktop.
Save abhi21git/3dc611aab9e1cf5e5343ba4b58573596 to your computer and use it in GitHub Desktop.
Swift cURL Printer

Ever wanted to generate cURL from URLRequest for faster debugging? Simply convert URLRequest in cURL format (Swift)

//
// ExtensionURLRequest.swift
//
// Created by Abhishek Maurya on 16/07/20.
// Copyright © 2020. All rights reserved.
//
import Foundation
extension URLRequest {
public func cURL(pretty: Bool = false) -> String {
let newLine = pretty ? "\\\n" : ""
let method = (pretty ? "--request " : "-X ") + "\(self.httpMethod ?? "GET") \(newLine)"
let url: String = (pretty ? "--url " : "") + "\'\(self.url?.absoluteString ?? "")\' \(newLine)"
var cURL = "curl "
var header = ""
var data: String = ""
if let httpHeaders = self.allHTTPHeaderFields, httpHeaders.keys.count > 0 {
for (key,value) in httpHeaders {
header += (pretty ? "--header " : "-H ") + "\'\(key): \(value)\' \(newLine)"
}
}
if let bodyData = self.httpBody, let bodyString = String(data: bodyData, encoding: .utf8), !bodyString.isEmpty {
data = "--data '\(bodyString)'"
}
cURL += method + url + header + data
return cURL
}
}
//
// UtilityFunction.swift
//
// Created by Abhishek Maurya on 23/10/20.
// Copyright © 2020. All rights reserved.
//
import Alamofire
import Foundation
class UtilityFunction: NSObject {
internal static let shared: UtilityFunction = {
return UtilityFunction()
}()
// Call this funcction inside Alomofire.request and pass the data response
class func debugApiResponse<T>(_ response: DataResponse<T>, pretty: Bool = false) {
print("\n")
if let statusCode = response.response?.statusCode {
print("Status code: " + String(statusCode))
}
if let request = response.request?.cURL(pretty: pretty) {
print("Request cURL: \n" + request)
} else {
if let url = response.request?.url?.absoluteString {
print("URL: \n" + url)
}
if let headers = response.request?.allHTTPHeaderFields {
print("Headers: \n\(headers as AnyObject)")
}
}
if let data = response.data {
if let json = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers), let jsonData = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted), pretty {
print("Response JSON pretty-printed: \n" + String(decoding: jsonData, as: UTF8.self))
} else if let jsonString = String(data: data, encoding: .utf8) {
print("Response JSON: \n" + jsonString)
}
if let responseHeader = response.response?.allHeaderFields, responseHeader.keys.count > 0 {
var header = "{\(pretty ? "\\\n" : "")"
for (key,value) in responseHeader {
header += " \"\(key): \(value)\",\(pretty ? "\\\n" : "")"
}
print("Response Header: \n\(header.dropLast())\(pretty ? "\\\n" : "")}")
}
}
print("\n")
}
}
// If you want to use cURL() with Alomofire request
@jamztang
Copy link

jamztang commented Aug 30, 2023

Thanks for the snippet, minor suggestion to make it work better for json body.

		if let bodyData = self.httpBody, let bodyString = String(data: bodyData, encoding: .utf8),  !bodyString.isEmpty {
-			data = "--data '\(bodyString)'"
+                       let escaped = bodyString.replacingOccurrences(of: "'", with: "'\\''")   // important to escape ' so it become '\'' that would work in command line
+                       data = "--data '\(escaped)'"
		}

@Rukh
Copy link

Rukh commented Feb 19, 2024

Cleaned up the code and updated it to modern Swift. Also added the ability to embed any binary data, even those that cannot be decoded into String https://gist.github.com/Rukh/6a0655842e1db5fe48fcd699221d7b68

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment