3

I am trying to build iOS client side of Alexa Voice Services. I am stuck at the networking layer.

Interaction with Alexa Server requires creation of mainly two streams over a single connection. After creating connection with server, you open a stream downchannel which will be in half closed state. downchannel will be used by server to send directives such as notifications, alarms etc.(for e.g. if you ask Alexa to set a alarm after 5 mins, you will get directive to play alarm on this channel after 5 mins). downchannel will be open as long as the session with Alexa is active. Another stream will be started whenever user starts an audio session with Alexa. This stream will be used to send audio chunks until we get end directive.Then this stream will be closed. More Details here

I am trying to implement this using streamTaskWithHostName(:portNumber:) of URLSession. So for simple HTTP request if I am sending HTTP request, I can read the response and I just need to parse header and body as per the standards.

let request = "GET / HTTP/1.1 \r\nHost: localhost\r\n\r\n"
streamTask = session.streamTask(withHostName: "localhost", port: 8080)
let getRequest = request.data(using: .utf8)!
streamTask.write(getRequest, timeout: 60) {
        error in
         debugPrint("Error is \(error?.localizedDescription)  )")
        if error == nil {
            self.streamTask.readData(ofMinLength: 4096, maxLength: 4096, timeout: 20) {
                data, bool, error in
                if let extractedData = data {
                    let dataString = String(data: extractedData, encoding: .utf8)
                    debugPrint("Data received is \(dataString!)")
                }
                debugPrint("Bool = \(bool)  error = \(error?.localizedDescription)")
            }
        }
    }


    streamTask.resume()

Data what I am reading is

  Data received is HTTP/1.1 200 \r\nDate: Tue, 26 Mar 2019 06:08:33 GMT\r\nServer: Apache/2.4.38 (Unix)\r\nContent-Length: 226\r\nConnection: close\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>it works</title>\n</head><body>\n<h1>it workst</h1>\n<p>it works.<br />\n</p>\n</body></html>\n"

But when i am trying to create http2 stream task, I can read nothing.

  :method = GET  
  :scheme = https  
  :path = /{{API version}}/directives
  authorization = Bearer {{YOUR_ACCESS_TOKEN}}  

1.Is it because of the http2 is a binary protocol instead of plain text and header is compressed using HPACK?

2.If yes, then Will I need to implement header compression, frame creation and writing to stream as per documentation myself or is there some configuration in URLSessionConfiguration which will do this for me even if I specify plain headers as in URLRequests?

3.Can you help me with some libraries which can help me in achieving the same.

Keshav Raj
  • 376
  • 1
  • 7

0 Answers0