-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSwiftGoogleTranslate.swift
234 lines (200 loc) · 10.5 KB
/
SwiftGoogleTranslate.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
//
// SwiftGoogleTranslate.swift
// SwiftGoogleTranslate
//
// Created by Maxim on 10/29/18.
// Copyright © 2018 Maksym Bilan. All rights reserved.
//
import Foundation
/// A helper class for using Google Translate API.
public class SwiftGoogleTranslate {
/// Shared instance.
public static let shared = SwiftGoogleTranslate()
/// Language response structure.
public struct Language {
public let language: String
public let name: String
}
/// Detect response structure.
public struct Detection {
public let language: String
public let isReliable: Bool
public let confidence: Float
}
/// API structure.
private struct API {
/// Base Google Translation API url.
static let base = "https://translation.googleapis.com/language/translate/v2"
/// A translate endpoint.
struct translate {
static let method = "POST"
static let url = API.base
}
/// A detect endpoint.
struct detect {
static let method = "POST"
static let url = API.base + "/detect"
}
/// A list of languages endpoint.
struct languages {
static let method = "GET"
static let url = API.base + "/languages"
}
}
/// API key.
private var apiKey: String!
/// Default URL session.
private let session = URLSession(configuration: .default)
/**
Initialization.
- Parameters:
- apiKey: A valid API key to handle requests for this API. If you are using OAuth 2.0 service account credentials (recommended), do not supply this parameter.
*/
public func start(with apiKey: String) {
self.apiKey = apiKey
print("hello \(apiKey)")
}
/**
Translates input text, returning translated text.
- Parameters:
- q: The input text to translate. Repeat this parameter to perform translation operations on multiple text inputs.
- target: The language to use for translation of the input text.
- format: The format of the source text, in either HTML (default) or plain-text. A value of html indicates HTML and a value of text indicates plain-text.
- source: The language of the source text. If the source language is not specified, the API will attempt to detect the source language automatically and return it within the response.
- model: The translation model. Can be either base to use the Phrase-Based Machine Translation (PBMT) model, or nmt to use the Neural Machine Translation (NMT) model. If omitted, then nmt is used. If the model is nmt, and the requested language translation pair is not supported for the NMT model, then the request is translated using the base model.
*/
public func translate(_ q: String, _ target: String, _ source: String, _ format: String = "text", _ model: String = "base", _ completion: @escaping ((_ text: String?, _ error: Error?) -> Void)) {
guard var urlComponents = URLComponents(string: API.translate.url) else {
print("here1")
completion(nil, nil)
return
}
print("here2")
var queryItems = [URLQueryItem]()
queryItems.append(URLQueryItem(name: "key", value: apiKey))
queryItems.append(URLQueryItem(name: "q", value: q))
queryItems.append(URLQueryItem(name: "target", value: target))
queryItems.append(URLQueryItem(name: "source", value: source))
queryItems.append(URLQueryItem(name: "format", value: format))
queryItems.append(URLQueryItem(name: "model", value: model))
urlComponents.queryItems = queryItems
guard let url = urlComponents.url else {
print("here3")
completion(nil, nil)
return
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = API.translate.method
print("heree \(urlRequest)")
let task = session.dataTask(with: urlRequest) { (data, response, error) in
print("hello!")
print("data = \(String(describing: data))")
print("response = \(String(describing:response))")
print("error = \(String(describing: error))")
guard let data = data, // is there data
let response = response as? HTTPURLResponse, // is there HTTP response
(200 ..< 300) ~= response.statusCode, // is statusCode 2XX
error == nil else { // was there no error, otherwise ...
print("here4 \(String(describing: error))")
completion(nil, error)
return
}
guard let object = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any], let d = object["data"] as? [String: Any], let translations = d["translations"] as? [[String: String]], let translation = translations.first, let translatedText = translation["translatedText"] else {
print("here5")
completion(nil, error)
return
}
completion(translatedText, nil)
}
task.resume()
}
/**
Detects the language of text within a request.
- Parameters:
- q: The input text upon which to perform language detection. Repeat this parameter to perform language detection on multiple text inputs.
*/
public func detect(_ q: String, _ completion: @escaping ((_ languages: [Detection]?, _ error: Error?) -> Void)) {
guard var urlComponents = URLComponents(string: API.detect.url) else {
completion(nil, nil)
return
}
var queryItems = [URLQueryItem]()
queryItems.append(URLQueryItem(name: "key", value: apiKey))
queryItems.append(URLQueryItem(name: "q", value: q))
urlComponents.queryItems = queryItems
guard let url = urlComponents.url else {
completion(nil, nil)
return
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = API.detect.method
let task = session.dataTask(with: urlRequest) { (data, response, error) in
guard let data = data, // is there data
let response = response as? HTTPURLResponse, // is there HTTP response
(200 ..< 300) ~= response.statusCode, // is statusCode 2XX
error == nil else { // was there no error, otherwise ...
completion(nil, error)
return
}
guard let object = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any], let d = object["data"] as? [String: Any], let detections = d["detections"] as? [[[String: Any]]] else {
completion(nil, error)
return
}
var result = [Detection]()
for languageDetections in detections {
for detection in languageDetections {
if let language = detection["language"] as? String, let isReliable = detection["isReliable"] as? Bool, let confidence = detection["confidence"] as? Float {
result.append(Detection(language: language, isReliable: isReliable, confidence: confidence))
}
}
}
completion(result, nil)
}
task.resume()
}
/**
Returns a list of supported languages for translation.
- Parameters:
- target: The target language code for the results. If specified, then the language names are returned in the name field of the response, localized in the target language. If you do not supply a target language, then the name field is omitted from the response and only the language codes are returned.
- model: The translation model of the supported languages. Can be either base to return languages supported by the Phrase-Based Machine Translation (PBMT) model, or nmt to return languages supported by the Neural Machine Translation (NMT) model. If omitted, then all supported languages are returned. Languages supported by the NMT model can only be translated to or from English (en).
- completion: A completion closure with an array of Language structures and an error if there is.
*/
public func languages(_ target: String = "en", _ model: String = "base", _ completion: @escaping ((_ languages: [Language]?, _ error: Error?) -> Void)) {
guard var urlComponents = URLComponents(string: API.languages.url) else {
completion(nil, nil)
return
}
var queryItems = [URLQueryItem]()
queryItems.append(URLQueryItem(name: "key", value: apiKey))
queryItems.append(URLQueryItem(name: "target", value: target))
queryItems.append(URLQueryItem(name: "model", value: model))
urlComponents.queryItems = queryItems
guard let url = urlComponents.url else {
completion(nil, nil)
return
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = API.languages.method
let task = session.dataTask(with: urlRequest) { (data, response, error) in
guard let data = data, // is there data
let response = response as? HTTPURLResponse, // is there HTTP response
(200 ..< 300) ~= response.statusCode, // is statusCode 2XX
error == nil else { // was there no error, otherwise ...
completion(nil, error)
return
}
guard let object = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any], let d = object["data"] as? [String: Any], let languages = d["languages"] as? [[String: String]] else {
completion(nil, error)
return
}
var result = [Language]()
for language in languages {
if let code = language["language"], let name = language["name"] {
result.append(Language(language: code, name: name))
}
}
completion(result, nil)
}
task.resume()
}
}