[SwiftUI] 構造体配列内の音声名と同一タイトルの音声を再生したい

実現したいこと

ここに実現したいことを箇条書きで書いてください。

前提

SwiftUIを使用し、ボタンを押す毎にランダムに全キャラクターから1名が選択され、
写真・名前・キャラクターの声が再生されるアプリを作成しています。

各キャラクターの情報はStruct Card(構造体Card)に入れ、
全キャラクター分を @State var card = [] で構造体配列として入れており、
ボタンを押すたびに構造体配列の要素数分の乱数を生成し、
前回と被りのない乱数が生成されたらその数値の場所にある
キャラクターの構造体の画像・名称等を表示させ、
キャラクターのボイスを再生するという内容です。

■コードの内容

●SoundView.swift

import UIKit import AVFoundation class SoundPlayer: NSObject { let audioData = NSDataAsset(name: card[cardPick].sound)!.data var audioPlayer: AVAudioPlayer! func audioPlay(){ do { audioPlayer = try AVAudioPlayer(data: audioData) audioPlayer.play() } catch { print("音楽再生エラー") } } }

●ContentView.swift

import SwiftUI struct ContentView: View { //SoundPlayerクラスをインスタンス化 let soundPlayer = SoundPlayer() //カードの構造体を定義 struct Card:Identifiable{ let id:UUID = UUID() let num:String let name:String let img:String let sound:String } //全カードパターンを構造体配列で定義 @State var card = [ Card(num:"0", name: "けんじ", img: "kenji", sound: "sound_kenji"), Card(num:"1", name: "たろう", img: "taro", sound: "sound_taro"), Card(num:"2", name: "はなこ", img: "hanako", sound: "sound_hanako"), Card(num:"3", name: "けんと", img: "kento", sound: "sound_kento"), Card(num:"4", name: "めぐみ", img: "megumi", sound: "sound_megumi") ] //めくったカードの配列の場所を変数に格納 @State var cardPick = 0 @State var newCardPick = 0 var body: some View { VStack{ Text("キャラクターカード") .font(.title) Spacer() Image(card[cardPick].img) .resizable() .scaledToFit() Text(card[cardPick].name) .font(.largeTitle) .padding(.bottom) Button("キャラクターをランダムに選ぶ"){ repeat{ newCardPick=Int.random(in: 0..<card.count) } while newCardPick == cardPick cardPick = newCardPick //このaudioPlayで再生される音声を card[cardPick].sound にしたい soundPlayer.audioPlay() } //Button end } //VStack end } //View end } //ContentView end struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }

発生している問題・エラーメッセージ

この中で、キャラクターの音声を出力する部分のみうまくいきません。
音声は SoundPlayer.swift 内に import AVFoundation を使ってaudioPlay関数を作成し、
乱数が生成された際に音声を鳴らす設定にしていますが、
サンプル例では固定の音声(String型)を入力しておく方法のため、プレイヤーごとに音声を変えようと
下記 "sound_kenji" 部分の文字列に変数 card[cardPick].sound を入れるとエラーが発生します。

変更前 let audioData = NSDataAsset(name: "sound_kenji")!.data
変更後 let audioData = NSDataAsset(name: card[cardPick].sound)!.data
エラー Cannot find 'card' in scope

試したこと

class SoundPlayer内で card:[] 配列が定義されていないのが原因だと思いますが、
audioPlayer()をContentViewに移動させたりしても大量のエラーが発生し解決できませんでした。
SoundPlayer.swift内の audioData に構造体配列の .sound の要素をタイトルとして指定する方法を
教えていただきたいです。

補足情報(FW/ツールのバージョンなど)

【開発環境】
XCode14.2
Swift5
MinimumDeployments iOS16.2
PC: Macbook Air 2020 M1 chip, MacOS Ventura 13.2

コメントを投稿

0 コメント