The answer to this seemingly simple question is eluding me.
I am using Alamofire version 5.6.1.
I am trying to extract httpBody
of Foundation's URLRequest
and put it into an NSLog
statement. However, the URLRequest
is generated and wrapped by an Alamofire.UploadRequest
.
Alamofire.UploadRequest
seems to delay creation of the URLRequest
until deep in the bowels of Alamofire. Currently, I have breakpoints in Alamofire.Session.performUploadRequest
and the URLRequest
still has not been fully assembled.
I tried logging from our app's data fetcher where the response comes back. The response type is Alamofire.DataResponse
and that has a reference to the original URLRequest
. However, at this point, the URLRequest
is reported as having httpBody
of nil
and this is simply false because the call is succeeding and the data used to configure the Alamofire.UploadRequest
which must eventually become the httpBody
of a URLRequest
, is arriving successfully at the backend service.
Regarding how far I have gotten, as I wrote, I can see the data still separate from a URLRequest
contained within a Alamofire.UploadRequest
at Alamofire.Session.performUploadRequest
. Here is the code for that:
func performUploadRequest(_ request: UploadRequest) {
dispatchPrecondition(condition: .onQueue(requestQueue))
performSetupOperations(for: request, convertible: request.convertible) {
do {
let uploadable = try request.upload.createUploadable()
// START of code I added.
switch uploadable {
case .data(let d):
let s = String(data: d, encoding: .utf8)
NSLog("YOJEFF uploadable case data = \(String(describing: s))")
default:
NSLog("YOJEFF uploadable case is not data")
}
// END of code I added.
self.rootQueue.async { request.didCreateUploadable(uploadable) }
And that shows the data which will eventually become httpBody
of a URLRequest
but I want to log the data from the actual URLRequest
passed to a URLSession
.
How much deeper into Alamofire must I go? Or am I missing some property further up?
I already have a logger that I wrote that conform to Alamofire.EventMonitor
, and it is injected into Alamofire.Session
but why that is not working on this particular network call is a separate puzzle.
URLSessionUploadTask
s, which Alamofire uses under the upload functionality, don't use the httpBody
property. Instead, it attaches to the httpBodyStream
of the URLRequest
after it's passed into the URLSession
issuing the request. Currently Alamofire doesn't have any events that occur when this happens (URLSession
is generally a blackbox at that level) but you can access request.task.currentRequest
to get the current state of the URLRequest
as URLSession
operates. In fact, this value is key value observable, so you could even get a live observation from that:
session.upload(...)
.onURLSessionTaskCreation { task in
<store observation> = task.observe(\.currentRequest) { task, change in
debugPrint(task.currentRequest?.httpBodyStream)
}
}
In my testing this value actually changes a few times under URLSession
, which is one of the reasons Alamofire offers no built-in hooks here.
However, it may be simpler to log your upload before it's passed to the request in the first place, especially if all you're trying to do is confirm its value. You could do this before creating the upload at all or by implementing the request(_ request:didCreateUploadable:)
event.