Sitemap
Rubens Machion

Rubens Machion

iOS developer

Utilizando URLProtocol para debug em HTTP requests

2 min readJul 25, 2024

No dia a dia de um desenvolvedor iOS, debugar o próprio código para encontrar erros é essencial. Na maioria das vezes, enchemos o código de prints ou utilizamos bibliotecas de terceiros para verificar chamadas na API. Muitas vezes, apenas uma simples implementação já é suficiente para cobrir 100% das chamadas REST. Hoje, vou mostrar como utilizar o URLProtocolpara interceptar as chamadas e exibir o cURL no console.

Get Rubens Machion’s stories in your inbox

Join Medium for free to get updates from this writer.

Para iniciar cria chamada DebugPrint que implementará o URLProcol e sobrescreverá o método canInit(with request:)

import Foundation

final class DebugPrint: URLProtocol {

override public class func canInit(with request: URLRequest) -> Bool {
// TODO: - added request intercep

return false
}
}

No próximo passo adicionaremos uma extensão privada da URLRequest para formatarmos as requisições no formato cURL

import Foundation

final class DebugPrint: URLProtocol {

override public class func canInit(with request: URLRequest) -> Bool {
request.curl(/service/scope: "Debug Network")

return false
}
}

private extension URLRequest {
func curl(/service/scope: String) {
print("---------------------------------------------------------------")
print("---------------------------------------------------------------")
print("DEBUG FOR: \(scope)")
guard let url = self.url else { return }
var baseCommand = #"curl "\#(url.absoluteString)""#
if self.httpMethod == "HEAD" {
baseCommand += " --head"
}

var command = [baseCommand]
if let method = self.httpMethod, method != "GET" && method != "HEAD" {
command.append("-X \(method)")
}

if let headers = self.allHTTPHeaderFields {
for (key, value) in headers where key != "Cookie" {
command.append("-H '\(key): \(value)'")
}
}

if let data = self.httpBody, let body = String(data: data, encoding: .utf8) {
command.append("-d '\(body)'")
}

print(command.joined(separator: " \\\n\t"))
}
}

Agora para finalizar configuramos um URLSessionConfiguration e registramos a nossa classe no URLProtocol

private func doRequest() {
URLProtocol.registerClass(DebugPrint.self)

let configuration = URLSessionConfiguration.default
configuration.protocolClasses?.insert(DebugPrint.self, at: 0)

let session = URLSession(configuration: configuration)
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")! // Don't do this, don't force, this is just a example
let request = URLRequest(url: url)

let task = session.dataTask(with: request) { data, response, error in
// TODO: do something
}

task.resume()
}

--

--