Как передать массив строк из модели просмотра для воспроизведения песни в SwiftUI

#ios #arrays #swift #swiftui #swiftui-environment

#iOS #массивы #swift #swiftui #swiftui-среда

Вопрос:

Я создал модель и добавил вложенную структуру. создан массив на основе одной из деталей структуры, и я хочу получить детали из модели для просмотра модели для воспроизведения музыки.

Я хочу получить эти строки «aURL» и вставить их в функцию воспроизведения для воспроизведения музыки.

 class myViewModel: ObservableObject {
@Published var isPlaying = false
var player = AVAudioPlayer()

func play(){
    do{
        player = try AVAudioPlayer(contentsOf: Array[0] as URL )
        if player.isPlaying{player.pause()}
        else{player.play()}
        isPlaying = player.isPlaying
        
    }catch{print("error")}
}
}
 

Ответ №1:

Сделать var feelSongs: [myModel.M.A] статическим, как

 static var feelSongs: [myModel.M.A] 
 

И использовать его внутри модели просмотра следующим образом

 class MyViewModel: ObservableObject {
    @Published var isPlaying = false
    var player = AVAudioPlayer()
    var arrData = myModel.M.feelSongs
    func play(with url: URL?){
        guard let url = url else {
            return
        }
        do{
            player = try AVAudioPlayer(contentsOf: url )
            if player.isPlaying{player.pause()}
            else{player.play()}
            isPlaying = player.isPlaying
            
        }catch{print("error")}
    }
}
 

Примечание: имя класса и имя структуры начинаются с заглавной буквы latter.

Комментарии:

1. спасибо за ответ. но var arrData = MyModel.feelSongs , в этой строке он не извлек переменную feelSongs для просмотра модели, хотя я изменил ее на статическую переменную.

2. тем не менее, это не сработало со статическим ключевым словом, но когда я использую только ключевое слово var, например (var arrData = MyModel.feelSongs), оно появляется, но я получаю сообщение «Невозможно использовать элемент экземпляра ‘MyModel’ в инициализаторе свойства; инициализаторы свойств запускаются до того, как будет доступно ‘self'»

Ответ №2:

Ваша структура, вложенная в struct, вложенная в struct, странная, во всяком случае, я не знаю вашей идеи.

пожалуйста, проверьте это:

 class MyModel: Codable {

    var feelSongs: [MyModel.M.A] = [
        MyModel.M.A.init(id: 1, afcontent: "Feeling Happy", aURL: "a1.mp3", isOn: true),
        MyModel.M.A.init(id: 2, afcontent: "Feeling Sad", aURL: "a2.mp3", isOn: true),
        MyModel.M.A.init(id: 3, afcontent: "Feeling Positive", aURL: "a3.mp3", isOn: true),
        MyModel.M.A.init(id: 4, afcontent: "Feeling Healthy", aURL: "a4.mp3", isOn: true)
    ]
    struct M: Codable{
        var mURL: String
        var bgMusic : String
        var bgVol : Double

        struct A : Codable, Identifiable {
            var id : Int
            var afcontent : String
            var aURL : String
            var isOn : Bool
            
            
        }
    }
}


class MyViewModel: ObservableObject {
    @Published var isPlaying = false
    var player = AVAudioPlayer()

    var theModel = MyModel()
    
    **//ADDED THIS**
    var playNow = 0

    func play(){

        if playNow >= theModel.feelSongs.count {
            return
        }
        let url = theModel.feelSongs[playNow]
        guard let url = URL(string: url) else {
            return
        }
        
        **//ADDED THIS**
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: item) 
        do {
            player = try AVAudioPlayer(contentsOf: url )
            if player.isPlaying{player.pause()}
            else{player.play()}
            isPlaying = player.isPlaying

        }
        catch{print("error")}
    }

    **//ADDED THIS**
    func playerDidFinishPlaying(note: NSNotification) {
        play()
    }
}
//
struct ContentView: View {
    var mymodel = MyViewModel()
    
    var body: some View {
        //Text("3")
        List(mymodel.theModel.feelSongs) { song in
            Text(song.afcontent)                    
        }
        .onAppear {
             mymodel.play()
        }
    }
}



struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
 

Комментарии:

1. большое спасибо за ответ. но как воспроизводить песни одну за другой, но через кнопку воспроизведения, а не со списком.

2. Я хочу, чтобы песни воспроизводились одна за другой автоматически. использование не может выбрать, какой из них воспроизводить

3. @binavol329 Я отредактировал ответ, в любом случае измените заголовок, теперь ваш запрос другой