iOSの読み上げ機能の言語設定画面を、ChatGPTを用いて実装

Speechフレームワーク（読み上げ機能）でローカライズ＋設定画面の作成が面倒だったので、ChatGPTを使ってローカライズファイルを作成し、設定画面を実装したので、コピペして使用できるように記しておく。

####  1.Localizable.stringsに、コードを作成　（英語、日本語対応のみ）
####  2.CountryModel.swiftを作成
####  3.SpeechLocalizeSettingViewを作成
####  4.保存した@AppStorage("keySpeechCountry")を用いて、設定する。

#  1.Localizable.stringsに、コードを作成　（英語、日本語対応のみ）
下記の文章を、Localizable.stringsにコピペしてください。

```swift:Localizable.strings
"Netherlands" = "Netherlands";
"Mexico" = "Mexico";
"Taiwan" = "Taiwan";
"France" = "France";
"Italy" = "Italy";
"Vietnam" = "Vietnam";
"South Africa" = "South Africa";
"Catalonia" = "Catalonia";
"Chile" = "Chile";
"South Korea" = "South Korea";
"Romania" = "Romania";
"French-speaking Switzerland" = "French-speaking Switzerland";
"Philippines" = "Philippines";
"Canada" = "Canada";
"Singapore" = "Singapore";
"India" = "India";
"New Zealand" = "New Zealand";
"Italian-speaking Switzerland" = "Italian-speaking Switzerland";
"French-speaking Canada" = "French-speaking Canada";
"Denmark" = "Denmark";
"Austria" = "Austria";
"Brazil" = "Brazil";
"Cantonese (China)" = "Cantonese (China)";
"China" = "China";
"Sweden" = "Sweden";
"Spain" = "Spain";
"Saudi Arabia" = "Saudi Arabia";
"Hungary" = "Hungary";
"French-speaking Belgium" = "French-speaking Belgium";
"United Kingdom" = "United Kingdom";
"Japan" = "Japan";
"Hong Kong" = "Hong Kong";
"Finland" = "Finland";
"Turkey" = "Turkey";
"Norway" = "Norway";
"Indonesia" = "Indonesia";
"English-speaking Saudi Arabia" = "English-speaking Saudi Arabia";
"Poland" = "Poland";
"Indonesia" = "Indonesia";
"Malaysia" = "Malaysia";
"Greece" = "Greece";
"Czechia" = "Czechia";
"Croatia" = "Croatia";
"United Arab Emirates" = "United Arab Emirates";
"Israel" = "Israel";
"Russia" = "Russia";
"German-speaking Switzerland" = "German-speaking Switzerland";
"Australia" = "Australia";
"Germany" = "Germany";
"Dutch-speaking Belgium" = "Dutch-speaking Belgium";
"Thailand" = "Thailand";
"Portugal" = "Portugal";
"Slovakia" = "Slovakia";
"United States" = "United States";
"Ireland" = "Ireland";
"Colombia" = "Colombia";
"Ukraine" = "Ukraine";
"Spanish-speaking United States" = "Spanish-speaking United States";
```

```swift:Localizable.strings
"Netherlands" = "オランダ";
"Mexico" = "メキシコ";
"Taiwan" = "台湾";
"France" = "フランス";
"Italy" = "イタリア";
"Vietnam" = "ベトナム";
"South Africa" = "南アフリカ";
"Catalonia" = "カタルーニャ";
"Chile" = "チリ";
"South Korea" = "韓国";
"Romania" = "ルーマニア";
"French-speaking Switzerland" = "スイスのフランス語圏";
"Philippines" = "フィリピン";
"Canada" = "カナダ";
"Singapore" = "シンガポール";
"India" = "インド";
"New Zealand" = "ニュージーランド";
"Italian-speaking Switzerland" = "スイスのイタリア語圏";
"French-speaking Canada" = "カナダのフランス語圏";
"Denmark" = "デンマーク";
"Austria" = "オーストリア";
"Brazil" = "ブラジル";
"Cantonese (China)" = "広東語（中国）";
"China" = "中国";
"Sweden" = "スウェーデン";
"Spain" = "スペイン";
"Saudi Arabia" = "サウジアラビア";
"Hungary" = "ハンガリー";
"French-speaking Belgium" = "ベルギーのフランス語圏";
"United Kingdom" = "イギリス";
"Japan" = "日本";
"Hong Kong" = "香港";
"Finland" = "フィンランド";
"Turkey" = "トルコ";
"Norway" = "ノルウェー";
"Indonesia" = "インドネシア";
"English-speaking Saudi Arabia" = "サウジアラビアの英語圏";
"Poland" = "ポーランド";
"Indonesia" = "インドネシア";
"Malaysia" = "マレーシア";
"Greece" = "ギリシャ";
"Czechia" = "チェコ";
"Croatia" = "クロアチア";
"United Arab Emirates" = "アラブ首長国連邦";
"Israel" = "イスラエル";
"Russia" = "ロシア";
"German-speaking Switzerland" = "スイスのドイツ語圏";
"Australia" = "オーストラリア";
"Germany" = "ドイツ";
"Dutch-speaking Belgium" = "ベルギーのオランダ語圏";
"Thailand" = "タイ";
"Portugal" = "ポルトガル";
"Slovakia" = "スロバキア";
"United States" = "アメリカ合衆国";
"Ireland" = "アイルランド";
"Colombia" = "コロンビア";
"Ukraine" = "ウクライナ";
"Spanish-speaking United States" = "アメリカ合衆国のスペイン語圏";
```

#  2.CountryModel.swiftを作成
下記のファイルを作成。ローカライズ設定した単語を呼び出すためのファイルです。

```swift:CountryModel.swift
import Foundation

struct CountryModel {
    static let countries: [String] = [NSLocalizedString("Netherlands", comment: ""),NSLocalizedString("Mexico", comment: ""),NSLocalizedString("Taiwan", comment: ""),NSLocalizedString("France", comment: ""),NSLocalizedString("Italy", comment: ""),NSLocalizedString("Vietnam", comment: ""),NSLocalizedString("South Africa", comment: ""),NSLocalizedString("Catalonia", comment: ""),NSLocalizedString("Chile", comment: ""),NSLocalizedString("South Korea", comment: ""),NSLocalizedString("Romania", comment: ""),NSLocalizedString("French-speaking Switzerland", comment: ""),NSLocalizedString("Philippines", comment: ""),NSLocalizedString("Canada", comment: ""),NSLocalizedString("Singapore", comment: ""),NSLocalizedString("India", comment: ""),NSLocalizedString("New Zealand", comment: ""),NSLocalizedString("Italian-speaking Switzerland", comment: ""),NSLocalizedString("French-speaking Canada", comment: ""),NSLocalizedString("Denmark", comment: ""),NSLocalizedString("Austria", comment: ""),NSLocalizedString("Brazil", comment: ""),NSLocalizedString("Cantonese (China)", comment: ""),NSLocalizedString("China", comment: ""),NSLocalizedString("Sweden", comment: ""),NSLocalizedString("Spain", comment: ""),NSLocalizedString("Saudi Arabia", comment: ""),NSLocalizedString("Hungary", comment: ""),NSLocalizedString("French-speaking Belgium", comment: ""),NSLocalizedString("United Kingdom", comment: ""),NSLocalizedString("Japan", comment: ""),NSLocalizedString("Hong Kong", comment: ""),NSLocalizedString("Finland", comment: ""),NSLocalizedString("Turkey", comment: ""),NSLocalizedString("Norway", comment: ""),NSLocalizedString("Indonesia", comment: ""),NSLocalizedString("English-speaking Saudi Arabia", comment: ""),NSLocalizedString("Poland", comment: ""),NSLocalizedString("Indonesia", comment: ""),NSLocalizedString("Malaysia", comment: ""),NSLocalizedString("Greece", comment: ""),NSLocalizedString("Czechia", comment: ""),NSLocalizedString("Croatia", comment: ""),NSLocalizedString("United Arab Emirates", comment: ""),NSLocalizedString("Israel", comment: ""),NSLocalizedString("Russia", comment: ""),NSLocalizedString("German-speaking Switzerland", comment: ""),NSLocalizedString("Australia", comment: ""),NSLocalizedString("Germany", comment: ""),NSLocalizedString("Dutch-speaking Belgium", comment: ""),NSLocalizedString("Thailand", comment: ""),NSLocalizedString("Portugal", comment: ""),NSLocalizedString("Slovakia", comment: ""),NSLocalizedString("United States", comment: ""),NSLocalizedString("Ireland", comment: ""),NSLocalizedString("Colombia", comment: ""),NSLocalizedString("Ukraine", comment: ""),NSLocalizedString("Spanish-speaking United States", comment: "")]

    static let keySpeechCountries: [String] = ["nl-NL","es-MX","zh-TW","fr-FR","it-IT","vi-VN","en-ZA","ca-ES","es-CL","ko-KR","ro-RO","fr-CH","en-PH","en-CA","en-SG","en-IN","en-NZ","it-CH","fr-CA","da-DK","de-AT","pt-BR","yue-CN","zh-CN","sv-SE","es-ES","ar-SA","hu-HU","fr-BE","en-GB","ja-JP","zh-HK","fi-FI","tr-TR","nb-NO","en-ID","en-SA","pl-PL","id-ID","ms-MY","el-GR","cs-CZ","hr-HR","en-AE","he-IL","ru-RU","de-CH","en-AU","de-DE","nl-BE","th-TH","pt-PT","sk-SK","en-US","en-IE","es-CO","uk-UA","es-US"]
}
```

####  3.SpeechLocalizeSettingViewを作成
![](https://storage.googleapis.com/zenn-user-upload/95b17e107b00-20230409.png)
上画像のような設定画面を作成する実装する。

```swift:SpeechLocalizeSettingView.swift
import SwiftUI

struct SpeechLocalizeSettingView: View {
    @Environment(\.dismiss) var dismiss
    @AppStorage("keySpeechCountry") var keySpeechCountry = "en-US"
    @State private var selectedIndex: Int? = nil
    var countries = CountryModel.countries
    var keySpeechCountries = CountryModel.keySpeechCountries
    var selectCountryLanguage: String {
        if let index = CountryModel.keySpeechCountries.firstIndex(of: keySpeechCountry) {
            return CountryModel.countries[index]
        }
        return ""
    }

    var body: some View {
        VStack{
            Button(NSLocalizedString("back", comment: "")) {
                dismiss()
            }
            .frame(height: 50)
            Text(selectCountryLanguage)
            List(countries.indices, id: \.self) { index in
                ContentCell(content: countries[index])
                    .contentShape(Rectangle())
                    .onTapGesture {
                        selectedIndex = index
                        keySpeechCountry = keySpeechCountries[index]
                        print(keySpeechCountry)
                    }
            }
        }
    }
}
private struct ContentCell: View {
    let content: String
    var body: some View {
        HStack{
            Text(content)
            Spacer()
        }
    }
}

````

####  4.保存した@AppStorage("keySpeechCountry")を用いて、設定する。

下記は「Hello,World」を読み上げるだけのシンプルな実装を例に説明しています。
```swift:
import SwiftUI
import AVFoundation

struct ContentView: View {
    let synthesizer = AVSpeechSynthesizer()
    let textToSpeak = "Hello, World!"
    
    var body: some View {
        Button(action: {
            let utterance = AVSpeechUtterance(string: textToSpeak)
            utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
            synthesizer.speak(utterance)
        }) {
            Text("Speak")
        }
    }
}


```
上記の実装の
```swift:
utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
```
の言語設定の部分に、
上記で保存した@AppStorage("keySpeechCountry")　の値を実装してください。

以上です。

よかったら、いいねやTwitterのフォロー宜しくお願いします！！