Outputvolume of AVAudioSession returning rounded values

Using the hardware volume buttons on the iPhone, you have 16 steps you can adjust your volume to. I want to implement a volume control slider in my app. I am updating the value of the slider using AVAudioSession.sharedInstance().outputVolume. The problem is that this returns values rounded to the nearest 0 or 5. This makes the slider jump around. .formatted() is not causing this problem. You can recreate the problem using code below.

@main
struct VolumeTestApp: App {
    init() {
        try? AVAudioSession.sharedInstance().setActive(true)
    }
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State private var volume = Double()
    @State private var difference = Double()
    var body: some View {
        VStack {
            Text("The volume changed by \(difference.formatted())")
            Slider(value: $volume, in: 0...1)
        }
        .onReceive(AVAudioSession.sharedInstance().publisher(for: \.outputVolume), perform: { value in
            volume = Double(value)
        })
        .onChange(of: volume) { oldValue, newValue in // Only used to make the problem more obvious
            if oldValue > newValue {
                difference = oldValue - newValue
            } else {
                difference = newValue - oldValue
            }
        }
    }
}

Here is a video of the problem in action: https://share.icloud.com/photos/00fmp7Vq1AkRetxcIP5EXeAZA

What am I doing wrong or what can I do to avoid this?

Thank you

Answered by Engineer in 789988022

Although you can observe changes to the output volume on iOS, the outputVolume property of AVAudioSession is read-only, so you cannot change the output volume programmatically. To implement a volume control slider in your app, you can add an instance of MPVolumeView to your view hierarchy.

Although you can observe changes to the output volume on iOS, the outputVolume property of AVAudioSession is read-only, so you cannot change the output volume programmatically. To implement a volume control slider in your app, you can add an instance of MPVolumeView to your view hierarchy.

Outputvolume of AVAudioSession returning rounded values
 
 
Q