I'm trying to implement support for grpc http/2 streams using NSURLSession. Almost everything works fine, data streaming is flowing from the server and from the client and responses are coming through my NSURLSessionTaskDelegate. I'm getting the responses and streamed data through the appropriate handlers (didReceiveData, didReceiveResponse).
However, I cannot seem to find an API to access the trailers expected by grpc. Specifically, the expected trailer "grpc-status: 0" is in the response, but after the data. Is there no way to gain access to trailers in the NSURLSession Framework?
URLSession doesn’t support HTTP trailers (r. 26845013). That leaves you with a couple of options:
- You can rework your on-the-wire protocol to avoid the need for them.
- You can write or acquire your own HTTP stack that includes this support.
If you do the latter, make sure to use Network framework as your underlying transport, because that ensures that your app will do all the usual things expected on Apple platforms (proxy support, VPN On Demand, and so on). TN3151 Choosing the right networking API talks more about this; see the HTTP alternatives and BSD Sockets best practices sections.
Note For gRPC specifically, there’s gRPC Swift and you should be able to combine that with SwiftNIO Transport Services.
Normally at this point I’d suggest that you file an enhancement request against URLSession for trailer support, but I don’t think that’d be productive. URLSession is a high-level API and this is a pretty low-level feature. I think you’re more likely to see trailer support land in a low-level framework, with Network framework being the obvious candidate. However, Network framework doesn’t currently support HTTP [1], so there’s nothing to file an ER against.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] Although if you rummage around in the debugger, you’ll see that URLSession delegates the HTTP heavy lifting to Network framework (assuming that you clear the usesClassicLoadingMode property).