LoginSignup
0
2

More than 1 year has passed since last update.

【Swift,iOS】いい感じのアドバイスをくれるアプリを作ってみた

Posted at

やりたいこと

  • いい感じのアドバイスをくれるAPIを使って、いい感じのアドバイスを画面に表示させたい

    1. Advice Slip JSON API というものを使っていい感じのアドバイスを英語で取得
    2. 取得した英語のアドバイスをDeepLのAPIを使って翻訳
    3. 画面に表示
    この流れでやっていきます。

完成図

画面をタップするとアドバイスが更新されます。

やってみる

アドバイスのURLにアクセスすると、このようなJSONが帰ってくるので、それに対応した構造体を作ります。

AdviceData.swift
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に上げてみました。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2