2016-12-21 6 views
0

У меня есть свой пользовательский URLProtocol, который имеет определенное генерирование ответа. Теперь у меня есть требование, где в я нужно отправить информацию на сервер через httpBody (Может быть JSON/String в качестве данных) до получения фактического ответаURlRequest.httpBody - это нуль внутри startLoading() Метод URLProtocol в swift 3.0

Моя проблема, когда я создаю URLRequest с httpBody, затем огнь службы с помощью URLSession с некоторой конфигурацией сеанса (этот обычаем URLProtocol включен здесь)

Это будет вызывать первый canInit -> каноническое -> startLoading -> stopLoading внутри этих всех методов request.httpBody равен нулю.

override func startLoading() { 
     let request = self.request 
     var response: HTTPURLResponse? 
     let hasResponse: Bool = true 
     if request.httpMethod == "GET" || request.httpMethod == "POST" { 
      guard let url = request.url else { 
       return 
      } 
      let client = self.client 
      let statusCode = 200 
      if url.absoluteString.contains("/good") { 
       print(self.request.httpBody) //here its nil 
      } 
      response = hasResponse ? HTTPURLResponse(url: request.url!, statusCode: statusCode, httpVersion: "HTTP/1.1", headerFields: cannedHeaders) : nil 
      client?.urlProtocol(self, didLoad: responseData) 
      client?.urlProtocol(self, didReceive: response!, cacheStoragePolicy: URLCache.StoragePolicy.notAllowed) 
      client?.urlProtocolDidFinishLoading(self) 
     } 
    } 
func testCompressRequest() { 
     let expect = expectation(description: "testCompressRequest") 
     let urlRequest = URLRequest(url: URL(string:serverPath+"/good")!) 
     urlRequest.httpBody = "someMethodBodyasString".data(using: .utf8) 
     urlRequest.httpMethod = "POST" 
     urlRequest.allHTTPHeaderFields = ["Accept-Encoding": "gzip, deflate", "Content-Encoding":"gzip, deflate", "Content-Type":"application/json", "Accept":"application/json", "Content-Length":String(describing: urlRequest.httpBody?.count)] 
     let task = URLSession(configuration: sessionConfig).dataTask(with: urlRequest) { (data, response, error) in 
      expect.fulfill() 
     } 
     task.resume() 
     waitForExpectations(timeout: 10, handler: nil) 
    } 

ответ

0

К моменту, когда протокол видит объект запроса, объект данных тела уже был стандартизован в объект потока тела. Откройте поток тела и прочитайте вместо него данные.

+0

Я тоже проверил это. я не могу использовать любой экземпляр байта в потоке – Padalingam

+0

Обычно, если вам не нужно изменять данные тела, вместо того, чтобы открывать поток, вы должны использовать его как значение потока тела в новом запросе, который вы передаете в NSURLSession/NSURLConnection, который вы используете для выполнения фактической работы. В вашем случае, тем не менее, поскольку вы на самом деле сами читаете данные, я думаю, вы должны сделать это асинхронно, потому что сценарий, вероятно, работает асинхронно в том же потоке, что и ваш читатель, и, таким образом, не будет делать данные до тех пор, пока вы не откроете поток и не откажетесь от управления циклом запуска. – dgatwood