Remote Control event in iOS with Swift

廉价感情. 提交于 2019-12-18 13:26:49

问题


Trying to figure out how to read the Apple headphone's volume buttons to use as a trigger for the camera shutter (as the Apple Camera app does).

From the documentation on Remote Control Events, Remote Control Received With Event, and this git repo, I've pieced together that I'll probably need an AVAudioPlayer object, .beginReceivingRemoteControlEvents(), and remoteControlReceivedWithEvent, along with making this view canBecomeFirstResponder() return true.

import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioPlayerDelegate {
    var player: AVAudioPlayer!
    override func viewDidLoad() {
        super.viewDidLoad()

        var session: AVAudioSession = AVAudioSession.sharedInstance()
        session.setActive(true, error: nil)
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        println("viewDidAppear worked...")
        self.becomeFirstResponder()
        UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
    }

    override func canBecomeFirstResponder() -> Bool {
        return true
    }

    override func remoteControlReceivedWithEvent(event: UIEvent) {
        let rc = event.subtype
        println("does this work? \(rc.rawValue)")
        //takePicture()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

I expected to get "does this work" when hitting the volume buttons on the headphones, instead I just see it adjust the headphone volume like normal. So I must be missing something, maybe with a delegate or AVSession?


回答1:


I cross-posted this on r/swift, where I was told it probably requires playing audio (quoted straight from the documentation).

So while this isn't the ideal solution, it works for my own private use.

import UIKit
import AVFoundation
import MediaPlayer

class ViewController: UIViewController, AVAudioPlayerDelegate {
    var testPlayer: AVAudioPlayer? = nil

    func loadSound(filename: NSString) -> AVAudioPlayer {
        let url = NSBundle.mainBundle().URLForResource(filename as String, withExtension: "caf")
        var error: NSError? = nil
        let player = AVAudioPlayer(contentsOfURL: url, error: &error)
        if error != nil {
            println("Error loading \(url): \(error?.localizedDescription)")
        } else {
            player.prepareToPlay()
        }
        return player
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.testPlayer = self.loadSound("silence")
        self.testPlayer?.numberOfLoops = -1
        self.testPlayer?.play()
    }

    override func canBecomeFirstResponder() -> Bool {
        return true
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        self.becomeFirstResponder()
        UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
    }

    override func remoteControlReceivedWithEvent(event: UIEvent) {
        let rc = event.subtype
        println("rc.rawValue: \(rc.rawValue)")
        // take photo
    }
}

I noticed that in Apple's camera app, the +/- volume buttons trigger the camera, and the microphone button pauses/plays any audio running in another app, but in this implementation the volume buttons still control the volume (and any audio has been paused when the app is launched).

An rc.rawValue: 103 corresponds to a single click of the microphone button, a double click returns 104, and a triple click returns 105, and then sometimes bumping a couple at a time returns a 108 or 109.




回答2:


Based on Cody's answer but updated for 2019 (Swift 5)

import UIKit
import AVFoundation
import MediaPlayer

class ViewController: UIViewController, AVAudioPlayerDelegate {
    var myPlayer: AVAudioPlayer? = nil

    func loadSound(filename: NSString) -> AVAudioPlayer? {
        let url = Bundle.main.url(forResource: filename as String, withExtension: "mp3")
        do {
            let player = try AVAudioPlayer(contentsOf: url ?? URL(fileURLWithPath: ""))
            player.prepareToPlay()
            return player
        }
        catch {
            print("Error : \(error)")
            return nil
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        guard let testPlayer = loadSound(filename: "silence") else {
            print("Not able to load the sound")
            return
        }
        testPlayer.delegate = self
        testPlayer.volume = 0.8
        testPlayer.numberOfLoops = -1
        myPlayer = testPlayer
        myPlayer?.play()
    }


    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.becomeFirstResponder()
        UIApplication.shared.beginReceivingRemoteControlEvents()
    }

    override func remoteControlReceived(with event: UIEvent?) {
        let rc = event?.subtype
        print("rc.rawValue: \(rc?.rawValue)")
        // Do your thing
    }
}


来源:https://stackoverflow.com/questions/30431782/remote-control-event-in-ios-with-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!