当サイトではPRを含む商品リンクを使用しております。

Swiftで翻訳機能を実装するAppleのAPI、Translationの実装方法例コード配布iOS18+

Swift

iOS18+のアプリで翻訳機能を追加する際、TranslationというAPIを使用することで

iOSに搭載されている翻訳機能のメニューを呼び出すことができ、言語パックがダウンロードされていればオフラインで翻訳可能です。

言語パックは、iPhone純正の翻訳アプリのプロパティからダウンロードしたり削除ができますし、自作アプリにて、ダウンロードを促すこともできます。

翻訳メニューを表示しない即時翻訳には、あらかじめ翻訳言語ペアがダウンロードされている必要があります。

おすすめすぎる⇨Swiftの教本

ボタンで基本の翻訳機能を呼び出す、Swiftで翻訳するAPIのTranslationのコード

コンテンツビューの内容を下記ファイルの内容で上書きすることで動作可能です。

Translation_test/trans_kihon.swift at main · KidaiRinboku/Translation_test
Contribute to KidaiRinboku/Translation_test development by creating an account on GitHub.

このコードで呼び出した翻訳機能の動作は下動画の通りです。

言語の選択、翻訳結果のコピー、再生ボタンを押すことで読み上げをしてくれます。

iOS本体に言語パックがダウンロードされている言語同士の組み合わせであれば、オフラインで翻訳可能です。

翻訳機能をインポートして、

import Translation

翻訳機能起動フラグと翻訳文章を準備します。

    //翻訳機能の立ち上げを管理するフラグ
    @State private var showTranslation = false
    //翻訳元のテキスト
    @State var originalText = "Hallo, Welt!"

ボタンでフラグを管理し、親要素Vstackのモディファイア部分にフラグ監視による翻訳機能呼び出しの処理が書いてあります。

VStack {
            //テキスト表示
            Text(verbatim: originalText)
            //翻訳機能立ち上げのフラグを切り替えるボタン
      Button("Translate") {
         showTranslation.toggle()
      }
}.translationPresentation(isPresented: $showTranslation,
text: originalText)
.navigationTitle("Translate")

ボタンで置き換え機能つき翻訳機能を呼び出す、Swiftで翻訳するAPIのTranslationのコード

コンテンツビューの内容を下記ファイルの内容で上書きすることで動作可能です。

Translation_test/trans_okikae.swift at main · KidaiRinboku/Translation_test
Contribute to KidaiRinboku/Translation_test development by creating an account on GitHub.

先ほどの機能に加えて、置き換え機能を呼び出したことで、翻訳機能に「翻訳して置き換え」機能が表示されました。

{
            //置き換えアクションここから
            translatedText in
            originalText = translatedText
            //置き換えアクションここまで
}

メニューではなく、即時翻訳機能を動かす、Swiftで翻訳するAPIのTranslationのコード ⚠️言語コードDL必要

注意点としては、iPhone本体に翻訳で使用する言語パックがあらかじめダウンロードされている必要があります。

また、この機能はシミューレータやCanvasでは実行できません。(2024/10現在)

今回はenとjaで指定しています。

Translateボタンを押すと、テキスト入力されている言葉を翻訳します。

Translation_test/trans_sokuji.swift at main · KidaiRinboku/Translation_test
Contribute to KidaiRinboku/Translation_test development by creating an account on GitHub.

ボタンで呼び出される下記の関数では、翻訳タスクの設定を指定しています。

  • configuration という翻訳タスクの設定を保持する変数にnilを代入、情報が入っていたら一旦無効化
  • その後、翻訳元言語と翻訳先言語を指定(今回は英語en⇨日本語ja)
            private func triggerTranslation() {
                guard configuration == nil else {
                    configuration?.invalidate()
                    return
                }
                configuration = .init(source: Locale.Language(identifier: "en"),
                                       target: Locale.Language(identifier: "ja"))
            }

ボタンを押されると、@Stateで定義されているconfigurationが書き換わる為VStackが再描画され

VStackにぶら下がっている翻訳機能が動きます。

                .translationTask(configuration) { session in
                    do {
                        let response = try await session.translate(sourceText)
                        targetText = response.targetText
                    } catch {

                    }
                }

配列の構造を一括で翻訳表示する Swiftで翻訳するAPIのTranslationのコード ⚠️言語コードDL必要

ビューに、食べ物の英語名が入った配列を表示しています。

translationボタンを押すと、配列の中身をいっぺんに翻訳後に置き換えます。いっぺんに置き換えるので、配列が長ければ長いほど表示にラグが表示ます。

リセットを押すと、元の初期言語の配列に戻します。

Translation_test/trans_kouzzouikki.swift at main · KidaiRinboku/Translation_test
Contribute to KidaiRinboku/Translation_test development by creating an account on GitHub.

言語パックダウンロードが必要ですが、その分オフラインでも翻訳が可能ということになります。

下記動画では、機内モードで実行しています。

ContentViewでは各要素の表示と翻訳のコンフィグを設定し、ViewModelで定義した翻訳系の処理を呼び出しています。

下記の部分で、配列に対して翻訳をしており、今回の例では全ての翻訳が終わってからいっぺんに表示しています。

            let responses = try await session.translations(from: requests)
            foodItems = responses.map {
                $0.targetText
            }

配列の構造を一括で翻訳表示する Swiftで翻訳するAPIのTranslationのコード ⚠️言語コードDL必要

↑は配列全てが翻訳されたからのビュー更新という挙動でしたが、

以下は配列の内容を1個ずつ翻訳、ビューに反映していく挙動になります。

Translation_test/trans_junban.swift at main · KidaiRinboku/Translation_test
Contribute to KidaiRinboku/Translation_test development by creating an account on GitHub.

下記の部分でインデックス番号ごとに翻訳処理を反映していくことで、配列を順番にリアルタイムで翻訳しています。

        Task { @MainActor in
            let requests: [TranslationSession.Request] = foodItems.enumerated().map { (index, string) in
                                .init(sourceText: string, clientIdentifier: "\(index)")
                        }
            do {
                for try await response in session.translate(batch: requests) {
                    guard let index = Int(response.clientIdentifier ?? "") else { continue }
                    foodItems[index] = response.targetText
                    print(response.targetText)
                }
            } catch {
                //エラーハンドリング
            }
        }

翻訳で使用としている言語ペアで正常に翻訳できるかの確認

言語の組み合わせが翻訳可能かをチェックする方法です。

Translation_test/trans_peatyekku.swift at main · KidaiRinboku/Translation_test
Contribute to KidaiRinboku/Translation_test development by creating an account on GitHub.

例えばソースコードを少しいじり、翻訳言語をイギリス英語⇨アメリカ英語にしてみると、

            configuration = .init(source: Locale.Language(identifier: "en-GB"),
                                  target: Locale.Language(identifier: "en-US"))

アプリ画面では何も動きがなく、コンソール側で言語ペアが不正なことによるエラーが発生します。

Client requested pair with valid source and target, but the pairing isn't supported: en_GB-en_US
Resolved source and target languages don't match supported locale pair, can't proceed with translation: Error Domain=TranslationErrorDomain Code=11 "(null)" UserInfo={sourceLocale=<_NSSwiftLocale: 0x301cbc4e0>, targetLocale=<_NSSwiftLocale: 0x301cbc460>}
Failed to determine all preflight information, won't proceed with translation: Error Domain=TranslationErrorDomain Code=11 "(null)" UserInfo={sourceLocale=<_NSSwiftLocale: 0x301cbc4e0>, targetLocale=<_NSSwiftLocale: 0x301cbc460>}
Client requested pair with valid source and target, but the pairing isn't supported: en_GB-en_US
Resolved source and target languages don't match supported locale pair, can't proceed with translation: Error Domain=TranslationErrorDomain Code=11 "(null)" UserInfo={sourceLocale=<_NSSwiftLocale: 0x301cbc4e0>, targetLocale=<_NSSwiftLocale: 0x301cbc460>}
Failed to determine all preflight information, won't proceed with translation: Error Domain=TranslationErrorDomain Code=11 "(null)" UserInfo={sourceLocale=<_NSSwiftLocale: 0x301cbc4e0>, targetLocale=<_NSSwiftLocale: 0x301cbc460>}

翻訳で使用としている言語ペアのダウンロードをユーザに促すメニューの表示

try await session.prepareTranslation()

↑の命令を実行すると、翻訳セッションの言語ペアのダウンロードを開始できるメニューをアプリに表示します

Translation_test/trans_daunro-doyoukyuu.swift at main · KidaiRinboku/Translation_test
Contribute to KidaiRinboku/Translation_test development by creating an account on GitHub.

iPhone本体の言語パックを削除したりダウンロードする方法

アプリ「設定」起動 > メニュー「アプリ」 > 一覧からアプリ「翻訳」 > メニュー「ダウンロードされた言語」

質問窓口

ココナラにて、質問やご相談を受け付けしております。

ジャンルにかかわらずお気軽にメッセージをください。

ジャンルや内容を設定した専用出品を作成いたします。

リンボクさんのプロフィール | ココナラ
ココナラは「知識・スキル・経験」など、みんなの得意を気軽に売り買いできるスキルマーケットです。友達に聞かれたり、お願いされるような「あなたの得意」を簡単出品。恋愛の相談から本格占い、キャッチコピー・ロゴ・イラスト作成まで何でも売り買いできま...

参考文献

SwiftUI | Apple Developer Documentation
Declare the user interface and behavior for your app on every platform.

おすすめすぎる⇨Swiftの教本

コメント

タイトルとURLをコピーしました