Playing music in SwiftUI application

In this short post, we’ll learn how to add the play function to our SwiftUI application. To test this functionality, we will add a Christmas song to our previous project (timer-and-shape-in-swiftui).

First, we need to create a player. We’ll do this by using the new Observable class annotation, which also works in the latest iOS 17. Some might wonder why I’m focusing on the latest features. The goal of my post is to update current iOS developers on the latest advancements and to help new developers, who usually start by using the most recent tools, create code effectively.

So, let’s take a look at the player:

import AVFoundation

@Observable
class AudioPlayerViewModel {
  var audioPlayer: AVAudioPlayer?

  var isPlaying = false

  init() {
    if let sound = Bundle.main.path(forResource: "silent", ofType: "mp3") {
      do {
        self.audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: sound))
      } catch {
        print("AVAudioPlayer can't be instantiated.")
      }
    } else {
      print("Audio file not found.")
    }
  }

  func playOrPause() {
    guard let player = audioPlayer else { return }

    if player.isPlaying {
      player.pause()
      isPlaying = false
    } else {
      player.play()
      isPlaying = true
    }
  }
}

First, we import the AVFoundation framework, as described in the official documentation at https://developer.apple.com/av-foundation/. As we can read there: “AVFoundation is the full featured framework for working with time-based audiovisual media on iOS, macOS, watchOS and tvOS. Using AVFoundation, you can easily play, create, and edit QuickTime movies and MPEG-4 files, play HLS streams, and build powerful media functionality into your apps”.

In the class, the player is defined as an optional, because it could be null for some reason. After that, we retrieve the path to the file we want to play and pass it to the player’s constructor. If something goes wrong, we’ll see an error message.

The method playOrPause, plays or stops the music depending the current playing state.

Regarding the audio file, it has not been added to the assets, but rather to the project structure.

Now add the player to the code:

.
.
@State var audioPlayerViewModel = AudioPlayerViewModel()
    
    var body: some View {
        ZStack {
            Color.black.frame(maxWidth: .infinity, maxHeight: .infinity).opacity(0.9).edgesIgnoringSafeArea(.all)
            VStack(spacing: 0) {
                Image(systemName: stars[indexStar])
                    .resizable()
                    .frame(width: 100, height: 100)
                    .foregroundStyle(.yellow)
                    .offset(y: 20)
                TriangleWidthDecoration(triangleWidth: 260, leftColorDecoration: currentColors[3], rightColorDecoration: currentColors[7])
                
            }.offset(y: -50)
            ForEach(Array(widths.enumerated()), id: \.offset) { index, leaf in
                TriangleWidthDecoration(triangleWidth: Double(leaf), leftColorDecoration: currentColors[index], rightColorDecoration: currentColors[index * 2])
                    .offset(y: 60 * Double( index + 1))
            }
            
            Rectangle()
                .frame(width: 20, height: 60)
                .foregroundStyle(.brown)
                .offset(y: 360)
        }.onReceive(timer) { _ in
            shuffleColor()
            self.indexStar = (self.indexStar + 1) % 2
        }.onAppear {
            audioPlayerViewModel.playOrPause()
        }.onTapGesture {
            audioPlayerViewModel.playOrPause()
        }
    }
    
    func shuffleColor() {
        for i in 0..<currentColors.count {
            currentColors[i] = colors[Int.random(in: 0..<9)]
        }
    }
}

The music starts when the tree appears. You can play or stop it by tapping on the tree.

You can obtain a free MP3 file from this source: https://www.freemusicpublicdomain.com/royalty-free-christmas-music/

The code is here

https://github.com/niqt/swift/tree/master/ChristmasTree

That’s all.

Note: English is not my native language, so I’m sorry for some errors. I appreciate if your correct me.

share this post with friends

Picture of Nicola De filippo

Nicola De filippo

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve

Leave a comment

Your email address will not be published. Required fields are marked *

Who I am

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve.

Follow Me Here

Get The Latest Updates

Periodically receive my super contents on coding and programming

join the family;)

Recent Posts