Равенство URLRequest не включает httpBody - PullRequest
0 голосов
/ 21 сентября 2018

Обзор

Есть 2 URLRequest с, один с httpBody и один без httpBody.
Однако при сравнении он показывает, что оба равны.

Вопрос

Это ожидаемое поведение или я что-то упустил?

Код

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" : "a@b.com"])

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
}

Вывод

requests are equal
body is not equal

Xcode10
Swift Версия: 4.2

Ответы [ 2 ]

0 голосов
/ 16 апреля 2019

Если вы пришли сюда, задаваясь вопросом, почему ваши идентичные URLRequest не равны друг другу, как я, я нашел причину в том, что эквивалентная реализация URLRequest различает существо httpBodyустанавливается в ноль или по умолчанию в ноль.

Если мы делаем следующее:

let request = URLRequest(url: URL(string: "test.com"))
var expectedRequest = URLRequest(url: URL(string: "test.com"))
expectedRequest.httpBody = nil

Тогда:

request == expectedRequest //false
print(request.httpBody) // nil
request.httpBody = nil
request == expectedRequest //true

Явно устанавливает httpBodynil исправит эту проблему.На самом деле, что это за тело, не имеет значения, только то, что оно было явно установлено.

request.httpBody = Data()
request == expectedRequest //true

Потенциальное объяснение

Как справедливо указывает Мартин Исходный код Swift не включает httpBody.Однако все свойства (в ссылке), равные (и оба из которых могут быть преобразованы как NSURLRequests), не возвращают true (см. Вывод lldb ниже).Я могу только предположить, что связанный код переопределен, чтобы включить другое свойство, и это изменяется, когда didSet или willSet вызывается httpBody lldb Terminal Log

0 голосов
/ 21 сентября 2018

URLRequest - это тип оверлея Swift для типа Foundation NSURLRequest, так что == в конечном итоге вызывает isEqual() метод NSURLRequest.

Библиотека Foundation с открытым исходным кодомдля платформ, не принадлежащих Apple, и по адресу NSURLRequest.swift # L245 мы находим:

open override func isEqual(_ object: Any?) -> Bool {
    //On macOS this fields do not determine the result:
    //allHTTPHeaderFields
    //timeoutInterval
    //httBody
    //networkServiceType
    //httpShouldUsePipelining
    guard let other = object as? NSURLRequest else { return false }
    return other === self
        || (other.url == self.url
            && other.mainDocumentURL == self.mainDocumentURL
            && other.httpMethod == self.httpMethod
            && other.cachePolicy == self.cachePolicy
            && other.httpBodyStream == self.httpBodyStream
            && other.allowsCellularAccess == self.allowsCellularAccess
            && other.httpShouldHandleCookies == self.httpShouldHandleCookies)

Так что это выглядит намеренно.

...