在Swift 3 iOS中实现Google翻译API

5

你好,我是iOS开发的新手,正在尝试在我的应用程序中实现谷歌翻译API。我从GitHub上找到了一些示例代码https://github.com/prine/ROGoogleTranslate。我下载了示例代码,并按照提供的说明从谷歌云翻译获取了API密钥并将其放置在代码中,但是代码无法正常工作。我查看了GitHub网站上的评论,并发现它已经为其他开发人员工作过。我真的不知道我在代码中做错了什么。

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字节
感谢您的帮助。代码可从提供的网址下载。 谢谢。

2
不要发布你的 API 密钥! - CodeBender
还有其他原因导致 403 错误吗?我的凭据似乎没问题,而且我已经输入了我的银行信息。 - ICL1901
2个回答

6

我是你提到的那个库的作者 :). 我猜你收到403错误是因为你的Google Api账号还没有正确激活。Google已经改变了翻译API的政策,它不再是免费的了。所以你可能没有在API帐户中添加信用卡信息,因此才会收到403错误?


你们也有Objective-C的库吗? - Syed Ali Salman
@aneey123,请不要忘记接受答案(勾选绿色对勾),如果它解决了你的问题。 - Ahmad F

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()
        }
}

请看一下另一个答案 - L. Guthardt
1
@L.Guthardt 我已经查看了其他答案和问题。我也遇到过这个问题,并通过更改API调用结构找到了解决方案。 - Rahul Singha Roy
1
但是答案的目的不仅仅是解决“一个问题”,而是只解决“OP的问题”。问题已经得到解决,因为Prine解释了问题的原因:“账户尚未正确激活[...]在Api账户中添加信用卡信息”。所以这个问题已经得到解决。 - L. Guthardt
“账户尚未正确激活”并不是问题的真正原因! - Rahul Singha Roy
“账户尚未正确激活”只是因为“API账户中未添加信用卡信息”的结果。而账户未正确激活会导致403错误。毫无疑问,这是因为Prine是该库的作者,他知道这些事情背后的情况。” - L. Guthardt
1
@RahulSinghaRoy 1+ .. 对我来说很有效,谢谢你,需要实现POST方法。 - Jaywant Khedkar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接