Наблюдение за системным объемом в SwiftUI - PullRequest
0 голосов
/ 07 мая 2020

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

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

import SwiftUI
import MediaPlayer

struct ContentView: View {
    @State var vol: Float = 1.0

    // Audio session object
    private let session = AVAudioSession.sharedInstance()
    // Observer
    private var progressObserver: NSKeyValueObservation!

    init() {
            do {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.ambient)
                try session.setActive(true, options: .notifyOthersOnDeactivation)
                self.vol = 1.0
            } catch {
                print("cannot activate session")
            }

            progressObserver = session.observe(\.outputVolume) { [self] (session, value) in
                print(session.outputVolume)
                self.vol = session.outputVolume
            }
        }

    var body: some View {
        Text(String(self.vol))
    }
}

// исправлено (установить категорию для окружающей среды) (обновлено в приведенном выше коде) Кроме того, каждый раз, когда приложение запускается, оно останавливает все воспроизводимые в данный момент musi c.

1 Ответ

1 голос
/ 07 мая 2020

Решено. Создан класс, соответствующий ObservableObject и использующий свойство ObservedObject в представлении. Кроме того, обозреватель тома не работает в симуляторе, только на устройстве.

VolumeObserver.swift

import Foundation
import MediaPlayer

final class VolumeObserver: ObservableObject {

    @Published var volume: Float = AVAudioSession.sharedInstance().outputVolume

    // Audio session object
    private let session = AVAudioSession.sharedInstance()

    // Observer
    private var progressObserver: NSKeyValueObservation!

    func subscribe() {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.ambient)
            try session.setActive(true, options: .notifyOthersOnDeactivation)
        } catch {
            print("cannot activate session")
        }

        progressObserver = session.observe(\.outputVolume) { [self] (session, value) in
            DispatchQueue.main.async {
                self.volume = session.outputVolume
            }
        }
    }

    func unsubscribe() {
        self.progressObserver.invalidate()
    }

    init() {
        subscribe()
    }
}

ContentView.swift

import SwiftUI
import MediaPlayer

struct ContentView: View {

    @ObservedObject private var volObserver = VolumeObserver()

    init() {
        print(vol.volume)
    }

    var body: some View {
        Text(String(vol.volume))
    }
}

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