detect up volume change swift
Asked Answered
M

2

5

I'm having problems detecting when someone presses up or down volume button. For the moment I just play a file but I want to know when the user presses the button to show an alert when the volume changes. I'm developing in Swift and I'm using AVFoundation to create this player. For the moment I can't find something that works in Swift. I'm very new to this language.

import UIKit
import AVFoundation

class ViewController: UIViewController {
    var backgroundMusicPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        playBackgroundMusic("IronBacon.mp3")
    }

    func playBackgroundMusic(filename:String){
        let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
        print(url)
        guard let newUrl = url else{
            print("couldn't find file: \(filename)")
            return
        }
        do{
            backgroundMusicPlayer = try AVAudioPlayer(contentsOfURL: newUrl)
            backgroundMusicPlayer.numberOfLoops = -1
            backgroundMusicPlayer.prepareToPlay()
        }catch let error as NSError{
            print(error.description)
        }
    }

    @IBAction func playPauseAction(sender: UIButton) {
        sender.selected = !sender.selected
        if sender.selected {
            backgroundMusicPlayer.play()
        } else {
            backgroundMusicPlayer.pause()
        }
    }

    func ShowAlert(title: String, message: String, dismiss: String) {
        let alertController = UIAlertController(title: title, message:
            message, preferredStyle: UIAlertControllerStyle.Alert)
        alertController.addAction(UIAlertAction(title: dismiss, style: UIAlertActionStyle.Default,handler: nil))
        self.presentViewController(alertController, animated: true, completion: nil)
    }

    func volumeUp(){
        ShowAlert( "example", message: "example", dismiss: "close")
    }

    func volumeDown(){
        ShowAlert( "example", message: "example", dismiss: "close")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
Mezzo answered 9/9, 2016 at 0:51 Comment(4)
Here's a good cocoapod that should do the trick github.com/jpsim/JPSVolumeButtonHandlerRoehm
that look nice...amm but you have a example in swift ?Mezzo
Just posted a new answer that doesn't require a pod.Roehm
For those does not have event-triggered, #64641056Leto
R
7

This should do the trick.

class ViewController: UIViewController {

    // MARK: Properties

    let notificationCenter = NSNotificationCenter.defaultCenter()

    // MARK: Lifecycle

    override func viewDidAppear(animated: Bool) {

        super.viewDidAppear(animated)

        notificationCenter.addObserver(self,
            selector: #selector(systemVolumeDidChange),
            name: "AVSystemController_SystemVolumeDidChangeNotification",
            object: nil
        )
    }

    override func viewDidDisappear(animated: Bool) {

        super.viewDidDisappear(animated)

        notificationCenter.removeObserver(self)
    }

    // MARK: AVSystemPlayer - Notifications

    func systemVolumeDidChange(notification: NSNotification) {

        print(notification.userInfo?["AVSystemController_AudioVolumeNotificationParameter"] as? Float)
    }
}
Roehm answered 9/9, 2016 at 1:34 Comment(1)
Thanks for your help, was needed make some investigation but at the end it works, thanks againMezzo
A
1

For some reason, the accepted answer does not work. Here is how you can do it in latest iOS versions -

func addObserver() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(systemVolumeDidChange),
                                           name: Notification.Name("SystemVolumeDidChange"),
                                           object: nil)
}
                                           
func systemVolumeDidChange(notification: NSNotification) {
    Log.msg("New Volume = \(notification.userInfo?["Volume"] as? Float)")
}

There are a few more fields in user info that can determine the volume change reason etc.

Algid answered 26/8, 2022 at 14:25 Comment(3)
Thank you! This code working fine on iOS 16. Is this a private API?Walli
No, this is not private API.Algid
Looks like it's not working with iOS 16.3... or did I miss something? Also, it's not documented in the list of Apple Notification.Name here: developer.apple.com/documentation/foundation/nsnotification/…, so I wonder if this is a reliable solution.Bosun

© 2022 - 2024 — McMap. All rights reserved.