ios - 在 Swift 中使用单例和解析 JSON
问题描述
我使用 yandex translate API 创建了一个翻译器应用程序。我创建单例类。
class TranslatorManager {
static let shared = TranslatorManager()
var translation: Translation?
let key = "mykey here"
let translateUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate"
func getTranslate(text: String, lang: String) {
guard let url = URL(string: translateUrl + "?key=\(key)&text=\(text)&lang=\(lang)&format=plain&options=1") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!.localizedDescription)
}
guard let data = data else { return }
do {
let translation = try JSONDecoder().decode(Translation.self, from: data)
DispatchQueue.main.async {
self.translation = translation
}
} catch {
print(error)
}
}.resume()
}
}
在 viewController 我创建了一些函数:
func getTranslate(text: String, lang: String) {
TranslatorManager.shared.getTranslate(text: text, lang: lang)
translate = TranslatorManager.shared.translation
self.translationLabel.text = self.translate?.text[0]
}
当我点击按钮时我调用它:
@IBAction func translateTapped(_ sender: UIButton) {
guard let text = originalText.text else { return }
getTranslate(text: text, lang: "en-ru")
}
在这种情况下,翻译仅在第二次按下按钮后才会显示在标签上。我究竟做错了什么?为什么它不能正常工作?
解决方案
您没有正确处理翻译在后台异步完成的事实。你需要重构你的TranslationManager
.
let key = "mykey here"
let translateUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate"
class TranslatorManager {
static let shared = TranslatorManager()
func getTranslate(text: String, lang: String, completion: @escaping (Translation?) -> Void) {
guard let url = URL(string: translateUrl + "?key=\(key)&text=\(text)&lang=\(lang)&format=plain&options=1") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
completion(nil)
return
}
guard let data = data else {
completion(nil)
return
}
do {
let translation = try JSONDecoder().decode(Translation.self, from: data)
completion(translation)
} catch {
print(error)
completion(nil)
}
}.resume()
}
}
然后更新您getTranslate
以处理新的完成处理程序:
func getTranslate(text: String, lang: String) {
self.translationLabel.text = "Translating..."
TranslatorManager.shared.getTranslate(text: text, lang: lang) { translation in
DispatchQueue.main.async {
if let translation = translation {
self.translationLabel.text = self.translate.text[0]
} else {
// failed, act accordingly
self.translationLabel.text = ""
}
}
}
}
推荐阅读
- c++ - 访问多层结构会导致错误
- sql - 加入时间间隔之间的事件并获得最佳时差?
- sql-server - 获取 ID 的 EF Core 差异会导致出现问题,而不是触发器和 Scope_Identity
- arduino - LoRa MBED 和 Arduino 库不兼容
- javascript - SVG圆图内的居中图标
- python - 使用 AppEngine GoogleCloud 部署 TensorFlow 应用程序时出错
- java - JavaFX 将图像拖放到 GridPane(FXML,控制器类)
- react-native - 在先前在 react-native 中创建的文件夹“Android”上编译 apk
- c - 权限被拒绝/文件太大
- c - 放大 API:重绘期间闪烁