0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NCMBのSwift SDKとDeepL APIを使って翻訳アプリを作る(その2:翻訳処理とデータの保存)

Last updated at Posted at 2022-07-06

NCMBのSwift SDKを使ってデモアプリを作ってみます。今回はDeepL APIを使った翻訳アプリです。翻訳結果をNCMBのデータストアに保存し、後で確認できるようにします。データストアにデータを保存したり、逆に取り出すのはよくあるケースなので、様々な場面で応用できるはずです。

前回は画面の説明とSDKの導入までを解説しましたので、今回は翻訳処理とデータ保存について解説します。

コードについて

今回のコードはNCMBMania/Swift_DeepL_App: Swift NCMB SDKとDeepL APIを組み合わせた翻訳アプリのデモですにアップロードしてあります。実装時の参考にしてください。

翻訳処理について

翻訳処理はDeepL APIを用いて行います。まず、DeepL APIのレスポンスに合わせた構造体を定義します。

// DeepL APIのレスポンス用構造体
struct DeepLResult: Codable {
    let translations: [Translation]
    struct Translation: Codable {
        var detected_source_language: String
        var text: String
    }
}

Alamofireの追加

ネットワークアクセスはAlamofireを利用します。Swift Package Mangerにて https://github.com/Alamofire/Alamofire.git を指定してインストールします。

インストールしたら、インポートします。

import Alamofire

翻訳画面について

前の記事でも紹介しました、翻訳画面 TranslateView は次のようになっています。

// 翻訳用ビュー
struct TranslateView: View {
    // 日本語のテキスト
    @State private var originalText = ""
    // 翻訳結果のテキスト
    @State private var translatedText = ""
    // 保存完了した際のアラート制御用
    @State private var uploaded = false
    // JSONデコード用
    let decoder: JSONDecoder = JSONDecoder()
    
    // 翻訳実行
    func translation() {
    }
    
    // 翻訳結果をNCMBに保存する処理
    func saveResult() {
    }
    
    // 画面表示
    var body: some View {
        NavigationView{
            VStack(spacing:0){
                ZStack{
                    VStack(spacing:20){
                        // 日本語入力欄
                        TextEditor(text: $originalText)
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                            .frame(maxWidth: 280, maxHeight: 100)
                        // 翻訳結果があれば表示
                        if translatedText != "" {
                            Text(translatedText).padding()
                        }
                        // 翻訳実行するボタン
                        Button(action: {
                            translation()
                        }, label: {
                            Text("翻訳する")
                        })
                    }
                }
            }
            .navigationBarTitle("翻訳", displayMode: .inline)
            // 保存完了時のアラート用
            .alert(isPresented: $uploaded, content: {
                Alert(
                    title: Text("保存完了"),
                    message: Text("翻訳結果を記録しました"),
                    dismissButton: .default(Text("閉じる"))
                )
            })
                
        }
    }
}

翻訳処理の実装

翻訳処理は translation 関数に実装します。DeepL用のライブラリはないので、Alamofireで直接実行しています。結果が返ってきたら、正常終了しているか判定した上でJSONデータを解析しています。その処理がうまくいったら画面に翻訳結果を反映(translatedTextに文字列を適用)し、 saveResult 関数を実行しています。

// 翻訳実行
func translation() {
		// APIKey.plistに保存したDeepLの認証キーを取得
		let authKey = KeyManager().getValue(key: "DeepLAuthKey") as! String
		// APIリクエストするパラメータを作成
		let parameters: [String: String] = [
				"text": originalText,
				"target_lang": "EN-US",
				"auth_key": authKey
		]
		// ヘッダーを作成
		let headers: HTTPHeaders = [
				"Content-Type": "application/x-www-form-urlencoded"
		]
		// DeepL APIを実行
		AF.request("https://api-free.deepl.com/v2/translate", method: .post, parameters: parameters, encoder: URLEncodedFormParameterEncoder.default, headers: headers).responseDecodable(of: DeepLResult.self) { response in
				// リクエスト成功か判定
				if case .success = response.result {
						do {
								// 結果をデコード
								let result = try decoder.decode(DeepLResult.self, from: response.data!)
								// 結果のテキストを取得&画面に反映
								translatedText =  result.translations[0].text
								// 結果をNCMBに保存する処理を呼び出し
								saveResult()
						} catch {
								debugPrint("デコード失敗")
						}
				} else {
						debugPrint("APIリクエストエラー")
				}
		}
}

データをNCMBに保存

NCMBのSwift SDKをインポートします。

import NCMB

翻訳前の日本語と、翻訳結果をNCMBのデータストアに保存します。データストアのクラス名(DBで言うところのテーブル名相当)はTranslateとしています。

保存がうまくいったら、 updated フラグを有効にし、アラートダイアログを表示します。

// 翻訳結果をNCMBに保存する処理
func saveResult() {
		let translate = NCMBObject(className: "Translate")
		translate["original"] = originalText
		translate["translate"] = translatedText
		translate.saveInBackground(callback: { result in
                // 処理が成功しているか判定
				if case let .success(_) = result {
                    uploaded = true
                }
		})
}

translate-app-4.png

ここまででデータの保存が完了です。実際にデータストアを見ると、Translateクラスができあがり、データが追加されています。

image.png

まとめ

NCMBを使うとクラウドデータベースへの保存がわずか数行で書けます。今回は使っていませんが、ACL(アクセス権限)も指定できます。ぜひ試してください。

次回は保存したデータの取得と表示を行います

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?