Обнаружение плагина/выхода наушников в Swift

Я работаю над приложением для iPhone для iOS 8.1, которое работает с основным звуком для генерации частот и регулировки интенсивности. В контроллере представления, который я генерирую частоты, которые мне нужно контролировать, если наушники подключены в какой-то момент, я уже контролирую, подключены ли наушники, прежде чем перейти к моему представлению генератора частот со следующей функцией:

- (BOOL)isHeadsetPluggedIn {
    AVAudioSessionRouteDescription* route = [[AVAudioSession sharedInstance]   currentRoute];
    for (AVAudioSessionPortDescription* desc in [route outputs]) {
        if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones])
            return YES;
    }
    return NO;
}

эта функция находится в C, потому что я работаю с core-audio для генерации частот, но в контроллерах представления я работаю с быстрым, поэтому нужен способ реализовать прослушиватель для обнаружения события отключения наушников и возврата пользователю к предыдущий вид, я не знаю, могу ли я использовать свою функцию isHeadsetPluggedin() с прослушивателем событий или я должен создать новый. В моем MenuViewController я контролирую, подключены ли наушники, используя следующую функцию:

func isHeadsetPluggedIn() -> Bool {
    return freqController.isHeadsetPluggedIn();
}     

person DrCachetes    schedule 18.11.2014    source источник
comment
this function is in C Цель-С ;)   -  person EmilioPelaez    schedule 28.06.2016


Ответы (3)


Вы можете отслеживать изменения маршрута, наблюдая за AVAudioSessionRouteChangeNotification уведомлением.

//Observe for route changing notification
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleRouteChange:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];

   -(void)handleRouteChange:(NSNotification *)notif
    {
       NSDictionary *dict = notif.userInfo;
       AVAudioSessionRouteDescription *routeDesc = dict[AVAudioSessionRouteChangePreviousRouteKey];
       AVAudioSessionPortDescription *prevPort = [routeDesc.outputs objectAtIndex:0];
       if ([prevPort.portType isEqualToString:AVAudioSessionPortHeadphones]) {
            //Head phone removed
          }
     }
person Clement Prem    schedule 04.12.2014

В Swift 4

    func activateHeadPhonesStatus(){
     NotificationCenter.default.addObserver(self, selector: #selector(audioRouteChangeListener(_:)), name: AVAudioSession.routeChangeNotification, object: nil)
    }

    @objc func audioRouteChangeListener(_ notification:Notification) {
            guard let userInfo = notification.userInfo,
                let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
                let reason = AVAudioSession.RouteChangeReason(rawValue:reasonValue) else {
                    return
            }
            switch reason {
            case .newDeviceAvailable:
                let session = AVAudioSession.sharedInstance()
                for output in session.currentRoute.outputs where output.portType == AVAudioSession.Port.headphones {
                    headphonesConnected = true
                    print("headphone plugged in")
                    break
                }
            case .oldDeviceUnavailable:
                if let previousRoute =
                    userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription {
                    for output in previousRoute.outputs where output.portType == AVAudioSession.Port.headphones {
                        headphonesConnected = false
                        print("headphone pulled out")
                        break
                    }
                }
            default: ()
            }

        }
person Sai kumar Reddy    schedule 27.12.2018
comment
это не сработало со мной, пока я не передал AVAudioSession.sharedInstance() в качестве объекта параметра для центра уведомлений вместо nil, т.е. `NotificationCenter.default.addObserver(self, selector: #selector(audioRouteChangeListener(_:)), name: AVAudioSession.routeChangeNotification, объект: AVAudioSession.sharedInstance())` - person Alaeddin AL Zeybek; 07.02.2020
comment
Это сработало для меня. Первоначально я установил наушникиConnected в --> fileprivate varнаушникиConnected : Bool = AVAudioSession.isHeadphonesConnected extension AVAudioSession { static var isHeadphonesConnected: Bool { return sharedInstance().isHeadphonesConnected } var isHeadphonesConnected: Bool { return !currentRoute.outputs.filter { $0.isHeadphones }.isEmpty } } extension AVAudioSessionPortDescription { var isHeadphones: Bool { return portType == AVAudioSession.Port.headphones } } - person Zeeshan; 13.02.2020

Это статья сработала для меня. Существует также репозиторий GitHub с решением. Если не хотите читать, вот мой код:

Поместите это в свой метод INIT:

    self.session = AVAudioSession.sharedInstance()
    let currentRoute = self.session.currentRoute
    if currentRoute.outputs.count != 0 {
        for description in currentRoute.outputs {
            if description.portType == AVAudioSessionPortHeadphones {
                print("headphone plugged in")
            } else {
                print("headphone pulled out")
            }
        }
    } else {
        print("requires connection to device")
    }

    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: #selector(YOUR_VIEW_CONTROLLER_OR_VIEW.audioRouteChangeListener(_:)),
        name: AVAudioSessionRouteChangeNotification,
        object: nil)

И поместите это в любом месте вашего класса:

 dynamic private func audioRouteChangeListener(notification:NSNotification) {
    let audioRouteChangeReason = notification.userInfo![AVAudioSessionRouteChangeReasonKey] as! UInt

    switch audioRouteChangeReason {
    case AVAudioSessionRouteChangeReason.NewDeviceAvailable.rawValue:
        print("headphone plugged in")
    case AVAudioSessionRouteChangeReason.OldDeviceUnavailable.rawValue:
        print("headphone pulled out")
    default:
        break
    }
}

Заботиться!

person Boris Nikolic    schedule 28.06.2016