Ios 在swift 3.0中URLProtocol的startLoading()方法中,URlRequest.httpBody为零

Ios 在swift 3.0中URLProtocol的startLoading()方法中,URlRequest.httpBody为零,ios,swift,cocoa-touch,nsurlsession,nsurlrequest,Ios,Swift,Cocoa Touch,Nsurlsession,Nsurlrequest,我有我的自定义URLProtocol,它有一些自定义响应生成。现在我有一个需求,在获得实际响应之前,我需要通过httpBody(可以是json/String作为数据)向服务器发送一些信息 我的问题是,当我用httpBody创建urlRequest时,然后通过使用URLSession和一些会话配置(这里包括自定义URLProtocol来启动服务) 这将调用第一个canInit->canonical->startLoading->stopLoading,在这些方法中request.httpBody为

我有我的自定义
URLProtocol
,它有一些自定义响应生成。现在我有一个需求,在获得实际响应之前,我需要通过httpBody(可以是json/String作为数据)向服务器发送一些信息

我的问题是,当我用httpBody创建urlRequest时,然后通过使用
URLSession
和一些会话配置(这里包括自定义
URLProtocol
来启动服务)

这将调用第一个canInit->canonical->startLoading->stopLoading,在这些方法中request.httpBody为nil


当协议看到请求对象时,主体数据对象已经标准化为主体流对象。打开body流并从那里读取数据。

我也检查过了。我在流实例上没有任何可用字节通常,如果您不必修改主体数据,而不是打开流,那么您将在传递给NSURLSession/NSURLConnection实例以执行实际工作的新请求中使用它作为主体流值。但是,在您的情况下,由于您自己实际上正在读取数据,我认为您必须异步执行该操作,因为编写器可能与您的读取器在同一线程上异步运行,因此在您打开流并放弃对运行循环的控制之前,数据是不可用的。
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)
    }