0

I am trying to post some text for translation to the Yandex translation api using the following method but seem to be getting back invalid JSON. However, I can't read what I'm getting back. Is there a way to parse 'data'? Here is method

func getTranslated(text: String, lang: "en-fr", completion: @escaping (TranslationReturned?) -> Void) {
        guard var components = URLComponents(string: translationUrl) else { return }
        components.queryItems = [URLQueryItem(name: "key", value: translationKey),
                                 URLQueryItem(name: "text", value: text),
                                 URLQueryItem(name: "lang", value: lang),
                                 URLQueryItem(name: "format", value: "plain"),
                                 URLQueryItem(name: "options", value: String(1))]
        var request = URLRequest(url: components.url!)

          request.httpMethod = "POST"

        URLSession.shared.dataTask(with: request) { (data, response, error) in
            print("data in call to yandex is",data as Any)//79 bytes
            if let error = error {
                print("error is",error.localizedDescription)
                completion(nil)
                return
            }

            guard let data = data else {
                print("no data")
                completion(nil)
                return
            }

            do {
                let translation = try JSONDecoder().decode(TranslationReturned.self, from: data)
                completion(translation)
            } catch {
                print(error)
                completion(nil)
            }
            }.resume()
    }

The returned item is 79 bytes long and error is nil but I can't determine what data is. Here is what debugger shows:

data in call to yandex is Optional(79 bytes)
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "code", intValue: nil)], debugDescription: "Expected to decode String but found a number instead.", underlyingError: nil))
(lldb) po data

error: <EXPR>:3:1: error: use of unresolved identifier 'data'; did you mean 'Data'?
data

Edit:

This is what TransationReturned object looks like:

@objc public class TranslationReturned: NSObject, Codable {
    var code: String = ""
    var lang: String = ""
    var text: String = ""
}

Edit 2

JSON returned after casting to string as suggested by rmaddy:

{"code":200,"detected":{"lang":"en"},"lang":"en-fr","text":["Bonjour les ami"]}

I was able to solve errors by changing TranslationReturned to handle structure of JSON as follows:

 @objc public class TranslationReturned: NSObject, Codable {
        var code: Int = 0
        var lang: String = ""
        var text = [String]()
        }
user1904273
  • 4,562
  • 11
  • 45
  • 96
  • 1
    `data` is `Data`. If you want to know what the data actually is, try converting it to a string using `let str = String(data: data, encoding: .utf8)` then print `str`. – rmaddy Apr 09 '19 at 02:47
  • data prints as {"code":200,"detected":{"lang":"en"},"lang":"en-fr","text":["Bonjour les ami"]} the typeMismatch seems to be that it is failing on the '200' in code. I have added code above for TranslationReturned object. I would have thought anything from JSON would be a string – user1904273 Apr 09 '19 at 14:23
  • 1
    `code` needs to be `Int`, not `String`. And `text` needs to be a dictionary, not `String`. – rmaddy Apr 09 '19 at 14:25
  • And update your question to include the JSON result. – rmaddy Apr 09 '19 at 14:25
  • Please don't edit your question to include the solution. Post the solution as an actual answer below. – rmaddy Apr 09 '19 at 15:58
  • Also note that `TranslationReturned` doesn't need to extend `NSObject`, it doesn't need `@objc`, and it should be a struct, not a class. At least if you only need to conform to `Codable`. If you need to use `TranslationReturned` with Objective-C code then ignore my comment. – rmaddy Apr 09 '19 at 16:00

0 Answers0