Search code examples
swiftrestapiswift3voice-recognition

RESTful API Calls to Snowboy API with Swift 3


I'm a mobile app noobie currently trying to send 3 wav voice samples with Swift3 to the Snowboy API server. Per their documentation Link Here, the request needs to have the following elements:

  • Endpoint: https://snowboy.kitt.ai/api/v1/train/
  • Type: POST
  • Content-Type: application/json
  • Required Parameter - token: Secret user token
  • Required Parameter - name: name of the recorded hotword that's mentioned in the voice samples
  • Required Parameter - voice_samples: A list of 3 voice samples in .wav format encoded as base64 strings

An example of the json they're expecting would look like this:

data = {
    "name": "nameOfSample",
    "language": "en",
    "token": "token",
    "voice_samples": [
        {"wave": voicesample1asBase64String},
        {"wave": voicesample2asBase64String},
        {"wave": voicesample3asBase64String}
    ]
}

With the following code, I get a 400 status code. Meaning that it recognized the token parameter and authenticated my request but the latter is somehow malformatted:

lazy var session: URLSession = URLSession(configuration: self.conf)

let url: URL

init(url: URL){
    self.url = url
}

func sendDataToURL (completion: @escaping JSONDictionaryHandler)
{
    var request = URLRequest(url: self.url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let path1 = Bundle.main.path(forResource: "voicesample1", ofType: "wav")!
    let path2 = Bundle.main.path(forResource: "voicesample2", ofType: "wav")!
    let path3 = Bundle.main.path(forResource: "voicesample3", ofType: "wav")!
    let paths = [path1, path2, path3]

    let audioFileStrings = paths.map { (path: String) -> [String:String] in
        let audioURL = URL(fileURLWithPath: path)
        let filename = audioURL.lastPathComponent
        if let base64String = try? Data(contentsOf: audioURL).base64EncodedString(){
            //print(base64String)
            return ["wave":base64String]
        }else{return ["":""]}
    }

    let parameters = ["token": "XXXXXXXXXXXXXXX",
                      "name": "nameOfSample",
                      "language": "en",
                      "voice_samples": audioFileStrings
        ] as [String : Any]
    guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {return}
    print("sending\(parameters)")
    request.httpBody = httpBody

    let uploadTask = session.dataTask(with: request) { (data, response, error) in

        if error == nil {

            if let httpResponse = response as? HTTPURLResponse{
                print(httpResponse)
                switch httpResponse.statusCode{
                case 200: //successful
                    if let receiveddata = data{
                    print("YAAAY! DATA! \(receiveddata)")
                        do{
                            let json = try JSONSerialization.jsonObject(with: receiveddata, options: [])
                            print(json)
                        }
                        catch{
                            print(error)
                        }
                    }
                default:
                    print("Bad HTTP response code: \(httpResponse.statusCode)")
                }
            }
            if let receivedData = data{

            }

        }
        else {
            print("Error \(error?.localizedDescription)")
        }



    }
    uploadTask.resume()

}

I think it's the voice_samples list that isn't well inserted in the son. Does anybody know how I can construct the request so the Snowboy server accepts it? Thanks!


Solution

  • You need a complete list of parameters. Add these:

    • age_group
    • gender
    • microphone

    This these parameters i got 201 error. But i used bad wav files.

    let parameters = ["token": "XXXXXXXX",
                          "name": "nameOfSample123123123",
                          "language": "en",
                          "voice_samples": audioFileStrings,
                          "age_group": "0_9",
                          "gender": "M",
                          "microphone": "test"