问题
Where is the best place to put code for audio playback in a SwiftUI based app, i.e. not having UIViewController classes? The sound I want to play is initiated by a view, so I'm thinking of putting it into the corresponding view model class. But as a model class is about data, I think there should be a better option. What's the best architecture?
回答1:
Correct, the View shouldn't take care of data. And SwiftUI enforces this logic.
You could create a Player class which takes care of playing the audio. And add it as an EnvironmentObject
, so you can control it with your button in the View
. You can then do sweet things like binding your play button to show different images depending on whether the player is... playing :)
Update
Code has been updated for Xcode 11 beta 4 (willChange
instead of didChange
)
struct PlayerView : View {
@EnvironmentObject private var player: Player
var body: some View {
Button(action: {
self.player.pauseOrPlay()
}) {
Image(systemName: player.isPlaying ? "pause.circle.fill" : "play.circle.fill").font(.title).frame(minWidth: 44, minHeight: 44)
}
}
}
class Player: BindableObject {
let willChange = PassthroughSubject<Player, Never>()
var isPlaying: Bool = false {
willSet {
willChange.send(self)
}
}
func pauseOrPlay() {
// Code that toggles the audio on and off
}
}
回答2:
Altough the solution from Davide worked, I ended up using the singleton pattern to have global access to my sound player object and actually moved back the triggering of the sounds from the view to the model class.
It looks like this:
class Player {
static let shared = AudioPlayer()
func pauseOrPlay() {
// Code that toggles the audio on and off
}
}
I can now call it from anywhere:
Player.shared.pauseOrPlay()
来源:https://stackoverflow.com/questions/57068891/where-to-place-code-for-audio-playback-in-a-swiftui-app