やりたいこと
-
いい感じのアドバイスをくれるAPIを使って、いい感じのアドバイスを画面に表示させたい
1. Advice Slip JSON API というものを使っていい感じのアドバイスを英語で取得
2. 取得した英語のアドバイスをDeepLのAPIを使って翻訳
3. 画面に表示
この流れでやっていきます。
完成図
画面をタップするとアドバイスが更新されます。
やってみる
アドバイスのURLにアクセスすると、このようなJSONが帰ってくるので、それに対応した構造体を作ります。
import Foundation
struct AdviceData: Decodable {
let slip: Advice
}
struct Advice: Decodable {
let advice: String
}
次に、URLにアクセスし、帰ってきたJSONをデコードします。
func fetchAdviceData() {
if let url = URL(string: self.adviceUrlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { data, response, error in
if let error = error {
print(error)
}
if let safeData = data {
let decoder = JSONDecoder()
do {
let decodeData = try decoder.decode(AdviceData.self, from: safeData)
let advice = decodeData.slip.advice
delegate?.didUpdateAdvice(self, advice: advice)
} catch {
delegate?.didFailWithError(error: error)
}
}
}
task.resume()
}
そして取得したアドバイスをDeepLのAPIに投げて翻訳してもらいます。
func translate(advice: String) {
let parameters: [String: String] = [
"text": advice,
"target_lang": "JA",
"auth_key": authKey
]
let headers: HTTPHeaders = [
"Content-Type": "application/x-www-form-urlencoded"
]
let decoder = JSONDecoder()
AF.request("https://api-free.deepl.com/v2/translate", method: .post, parameters: parameters, encoder: URLEncodedFormParameterEncoder.default, headers: headers).responseDecodable(of: DeepLResult.self, decoder: decoder) { response in
if case .success = response.result {
do {
let result = try decoder.decode(DeepLResult.self, from: response.data!)
let translatedText = result.translations[0].text
delegate?.adviceDidTranslate(advice: translatedText)
} catch {
debugPrint("デコード失敗")
}
} else {
debugPrint("APIリクエストエラー, \(response.error)")
}
}
}
これで翻訳されたアドバイスが取得できるので、あとはラベルに表示するだけですが
名言ぽくしたかったのでCLTypingLabelというライブラリを使ってみました。
ラベルにテキストを設定するだけなので簡単に使えます。
一文字ずつ文字が入力されていくアニメーションが名言らしい雰囲気を出してくれます。
今回はこの記事を参考にしました。
ただ記事の通りに実装してもDeepLのAPIを使うときに、Alamofireでエラーが出てしまいます。
responseDecodable(of: DeepLResult.self)
この部分を
responseDecodable(of: DeepLResult.self, decoder: decoder)
このように修正してあげるとうまくいきました。詳しくは上のコードを見てみてください。
Githubに上げてみました。