'URLRequest equality doesn't include httpBody
Overview
There are 2 URLRequests, one with httpBody and one with no httpBody.
However when compared, it shows both are equal.
Question
Is this expected behaviour or am I missing something ?
Code
let url = URL(string: "www.somevalidURL.com")!
var r1 = URLRequest(url: url)
r1.addValue("Content-Type", forHTTPHeaderField: "application/json; charset=utf-8")
r1.httpBody = makeBody(withParameters: ["email" : "[email protected]"])
var r2 = URLRequest(url: url)
r2.addValue("Content-Type", forHTTPHeaderField: "application/json; charset=utf-8")
if r1 == r2 {
print("requests are equal")
}
else {
print("requests are not equal")
}
if r1.httpBody == r2.httpBody {
print("body is equal")
}
else {
print("body is not equal")
}
func makeBody(withParameters bodyParameters: [String : Any]?) -> Data? {
guard let bodyParameters = bodyParameters,
!bodyParameters.isEmpty else {
return nil
}
let body : Data?
do {
body = try JSONSerialization.data(withJSONObject: bodyParameters,
options: .prettyPrinted)
}
catch {
print("Error in creating Web Service Body = \(error)")
body = nil
}
return body
}
Output
requests are equal
body is not equal
Xcode 10
Swift Version: 4.2
Solution 1:[1]
If you've come here wondering why your identical URLRequests aren't equal to each other like I did I found the reason to be that URLRequest's equatable implementation differentiates between httpBody being set to nil or being defaulting to nil.
If we do the following:
let request = URLRequest(url: URL(string: "test.com"))
var expectedRequest = URLRequest(url: URL(string: "test.com"))
expectedRequest.httpBody = nil
Then:
request == expectedRequest //false
print(request.httpBody) // nil
request.httpBody = nil
request == expectedRequest //true
Explicitly settings the httpBody to nil will fix this issue. In fact what the body is doesn't matter, only that it has been explicitly set.
request.httpBody = Data()
request == expectedRequest //true
Potential explanation
As Martin rightly points out Swift's source code does not include httpBody. However all of the properties (in the link) being equal (and both being castable as NSURLRequests) does not return true (see lldb output below). I can only presume the linked code is overridden to include another property and this is modified when didSet or willSet is called on httpBody

Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
