【问题标题】:Implementing google translation api in swift 3 iOS在 swift 3 iOS 中实现谷歌翻译 api
【发布时间】:2017-07-15 22:11:35
【问题描述】:

您好,我是 iOS 开发新手,我正在尝试在我的应用程序中实现谷歌翻译 API。我从 GitHub https://github.com/prine/ROGoogleTranslate 在线找到了一些示例代码。我下载了示例代码并按照从谷歌云翻译获取 api 密钥并将其放置在代码中的说明进行操作,但是代码不起作用,iv 查看了 GitHub 站点上的 cmets,发现它有 为其他开发人员工作。我真的不知道我在代码中做错了什么。

ROGoogleTranslateParams.swift

import Foundation

public struct ROGoogleTranslateParams {

    public init() {

    }

    public init(source:String, target:String, text:String) {
        self.source = source
        self.target = target
        self.text = text
    }

    public var source = "de"
    public var target = "en"
    public var text = "Hallo"
}


/// Offers easier access to the Google Translate API
open class ROGoogleTranslate {

    /// Store here the Google Translate API Key
    public var apiKey = "YOUR_API_KEY"

    ///
    /// Initial constructor
    ///
    public init() {

    }

    ///
    /// Translate a phrase from one language into another
    ///
    /// - parameter params:   ROGoogleTranslate Struct contains all the needed parameters to translate with the Google Translate API
    /// - parameter callback: The translated string will be returned in the callback
    ///
    open func translate(params:ROGoogleTranslateParams, callback:@escaping (_ translatedText:String) -> ()) {

        guard apiKey != "" else {
            print("Warning: You should set the api key before calling the translate method.")
            return
        }

        if let urlEncodedText = params.text.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) {
            if let url = URL(string: "https://translation.googleapis.com/language/translate/v2?key=\(self.apiKey)&q=\(urlEncodedText)&source=\(params.source)&target=\(params.target)&format=text") {

                let httprequest = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
                    guard error == nil else {
                        print("Something went wrong: \(error?.localizedDescription)")
                        return
                    }

                    if let httpResponse = response as? HTTPURLResponse {

                        guard httpResponse.statusCode == 200 else {

                            if let data = data {
                                print("Response [\(httpResponse.statusCode)] - \(data)")
                            }

                            return
                        }

                        do {
                            // Pyramid of optional json retrieving. I know with SwiftyJSON it would be easier, but I didn't want to add an external library
                            if let data = data {
                                if let json = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary {
                                    if let jsonData = json["data"] as? [String : Any] {
                                        if let translations = jsonData["translations"] as? [NSDictionary] {
                                            if let translation = translations.first as? [String : Any] {
                                                if let translatedText = translation["translatedText"] as? String {
                                                    callback(translatedText)
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        } catch {
                            print("Serialization failed: \(error.localizedDescription)")
                        }
                    }
                })

                httprequest.resume()
            }
        }
    }
}

ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet var text:UITextField!
    @IBOutlet var fromLanguage:UITextField!
    @IBOutlet var toLanguage:UITextField!
    @IBOutlet var translation:UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func translate(_ sender: UIButton) {



        let translator = ROGoogleTranslate()
        translator.apiKey = "YOUR_API_KEY" // Add your API Key here

        var params = ROGoogleTranslateParams()
        params.source = fromLanguage.text ?? "de"
        params.target = toLanguage.text ?? "en"
        params.text = text.text ?? "Hallo"

        translator.translate(params: params) { (result) in
            DispatchQueue.main.async {
                self.translation.text = "\(result)"
            }
        }
    }
}

这些是使用的类。 当我按下“翻译”按钮时,我得到的结果如下: 响应 [403] - 355 字节

感谢您的帮助。代码可从提供的 url 下载 谢谢

【问题讨论】:

  • 不要发布您的 API 密钥!
  • 出现 403 错误还有其他原因吗?我的凭据似乎没有问题,并且我已经输入了我的银行信息。

标签: ios google-api swift3 google-translate


【解决方案1】:

试试这个“POST”方法函数而不是你实现的“Get”方法-

open func translateTest(params: GoogleAITranslateParams, targetLanguage: String, callback:@escaping (_ translatedText:String) -> ()) {

    guard apiKey != "" else {
        return
    }

    var request = URLRequest(url: URL(string: "https://translation.googleapis.com/language/translate/v2?key=\(self.apiKey)")!)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue(Bundle.main.bundleIdentifier ?? "", forHTTPHeaderField: "X-Ios-Bundle-Identifier")

        let jsonRequest = [
            "q": params.text,
            "source": "en",
            "target": targetLanguage,
            "format": "text"
            ] as [String : Any]

        if let jsonData = try? JSONSerialization.data(withJSONObject: jsonRequest, options: .prettyPrinted) {
            request.httpBody = jsonData
            let task: URLSessionDataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
                guard error == nil else {
                    print("Something went wrong: \(String(describing: error?.localizedDescription))")
                    return
                }

                if let httpResponse = response as? HTTPURLResponse {

                    guard httpResponse.statusCode == 200 else {
                        if let data = data {
                            print("Response [\(httpResponse.statusCode)] - \(data)")
                        }
                        return
                    }

                    do {
                        if let data = data {
                            if let json = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary {
                                if let jsonData = json["data"] as? [String : Any] {
                                    if let translations = jsonData["translations"] as? [NSDictionary] {
                                        if let translation = translations.first as? [String : Any] {
                                            if let translatedText = translation["translatedText"] as? String {
                                                callback(translatedText)
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } catch {
                        print("Serialization failed: \(error.localizedDescription)")
                    }
                }
            }

            task.resume()
        }
}

【讨论】:

  • 请看the other answer
  • @L.Guthardt 我已经检查了其他答案和问题。我也遇到过这个问题,通过改变API调用结构得到了解决方案。
  • 但回答的目的不仅仅是解决一个问题。但只有 OP 的问题。并且问题已经解决,因为 Prine 解释了问题的原因:Account is not yet activated correctly [...] add the credit card informations in the Api account。所以这个问题的问题已经解决了。
  • “帐户尚未正确激活”不是问题的真正原因!
  • Account is not yet activated correctly 只是didn't add the credit card informations in the Api account 的结果。并且帐户未正确激活会导致 403 错误。这是肯定的,因为 Prine 是 lib 的作者,他是知道背后内容的人。
【解决方案2】:

我是您上面提到的库的作者 :)。我猜您收到 403 是因为您的 Google Api 帐户尚未正确激活。 Google 更改了 Translation api 的政策,不再免费。所以你可能没有在Api帐户中添加信用卡信息,因此得到403错误?

【讨论】:

  • 你也有 Objective-c 的库吗?
  • @aneey123 如果它解决了您的问题,请不要忘记接受答案(绿色勾号)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
  • 2010-10-10
  • 2016-04-11
  • 2017-02-11
相关资源
最近更新 更多