SwiftUI Style, iPhone App Development: Adding Playback Status Images to an Audio App

In recent years, SwiftUI has played a significant role in Apple’s app development ecosystem. SwiftUI provides an intuitive way to build UI with a declarative syntax, similar to Flutter. Today, we will explore how to create an audio app using SwiftUI and add images that change dynamically based on the playback state.

1. Basic Concepts of SwiftUI and Audio Player

SwiftUI is Apple’s latest UI framework designed to create UIs more simply and intuitively than previous UIKit. However, to directly handle audio, the AVFoundation framework must be used. Combining these two allows developers to create powerful multimedia-supported apps.

1.1 Overview of AVFoundation

AVFoundation is a powerful framework for handling audio and video content. It allows for easy implementation of features such as playing, pausing, and stopping audio files.

1.2 Overview of SwiftUI

SwiftUI is a framework that allows UIs to be constructed declaratively, easily reflecting gestures such as clicks and swipes to respond to state changes. A SwiftUI view maintains its own state and is updated immediately whenever that state changes.

2. Setting Up the Project

Let’s set up a basic structure for a simple audio app using SwiftUI. Open Xcode and create a new SwiftUI project. Select “App” and give it an appropriate name.

2.1 Adding Essential Libraries

To use the AVFoundation framework, you need to add a description requesting permission for audio playback in the project’s Info.plist file. Add the following key-value pair:


NSMicrophoneUsageDescription
Microphone access is required to play audio.

2.2 Building the Basic UI

To build a simple UI, let’s use SwiftUI’s VStack and Button. Below is the code for the basic UI:


struct ContentView: View {
    var body: some View {
        VStack {
            Text("Audio Player")
                .font(.largeTitle)
                .padding()
            
            Button(action: {
                // Add play function
            }) {
                Text("Play")
                    .font(.title)
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
            
            Button(action: {
                // Add pause function
            }) {
                Text("Pause")
                    .font(.title)
                    .padding()
                    .background(Color.red)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
    }
}

3. Implementing Audio Playback Logic

We will use AVAudioPlayer to play audio files. First, import the AVFoundation framework and initialize the audio player.

3.1 Creating the Audio Player Class


import AVFoundation

class AudioPlayer: ObservableObject {
    var player: AVAudioPlayer?
    @Published var isPlaying: Bool = false
    
    func playAudio() {
        guard let url = Bundle.main.url(forResource: "audio_file", withExtension: "mp3") else { return }
        
        do {
            player = try AVAudioPlayer(contentsOf: url)
            player?.play()
            isPlaying = true
        } catch {
            print("Error playing audio: \(error.localizedDescription)")
        }
    }
    
    func pauseAudio() {
        player?.pause()
        isPlaying = false;
    }
}

3.2 Connecting UI

Now we’ll connect the AudioPlayer class with the SwiftUI view to enable the play button and state functionality.


struct ContentView: View {
    @ObservedObject var audioPlayer = AudioPlayer()
    
    var body: some View {
        VStack {
            Text("Audio Player")
                .font(.largeTitle)
                .padding()
            
            Button(action: {
                if audioPlayer.isPlaying {
                    audioPlayer.pauseAudio()
                } else {
                    audioPlayer.playAudio()
                }
            }) {
                Text(audioPlayer.isPlaying ? "Pause" : "Play")
                    .font(.title)
                    .padding()
                    .background(audioPlayer.isPlaying ? Color.red : Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
        .onChange(of: audioPlayer.isPlaying) { newValue in
            // Add logic to change image based on state change
        }
    }
}

4. Adding Playback State Images

Enhance the user experience by adding images that display differently based on the audio playback state, helping users easily understand the current status visually.

4.1 Adding Images

First, you need to add images for the play and pause buttons to your project. Go to Assets.xcassets and add appropriate images. Name the two images “play” and “pause”, then link them for use in SwiftUI.

4.2 Managing Image States

To update the playback state images according to state changes, add a property in ContentView to display the images.


struct ContentView: View {
    @ObservedObject var audioPlayer = AudioPlayer()
    
    var body: some View {
        VStack {
            Text("Audio Player")
                .font(.largeTitle)
                .padding()
            
            Image(audioPlayer.isPlaying ? "pause" : "play")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 100, height: 100)
                .padding()
            
            Button(action: {
                if audioPlayer.isPlaying {
                    audioPlayer.pauseAudio()
                } else {
                    audioPlayer.playAudio()
                }
            }) {
                Text(audioPlayer.isPlaying ? "Pause" : "Play")
                    .font(.title)
                    .padding()
                    .background(audioPlayer.isPlaying ? Color.red : Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
    }
}

5. Conclusion

We have now implemented the functionality of dynamically changing images based on playback state in our simple SwiftUI-based audio app. By leveraging the powers of SwiftUI and AVFoundation, you can create an audio app with many features.

Consider adding more features to create your own audio player. For example, you can add playlist support, display playback time, or incorporate UI elements that show song information. We hope this process has deepened your understanding of SwiftUI, and we will return with more useful information next time.