title: AVSystemController_SystemVolumeDidChangeNotification triggers when device locked
body: <p>Using iOS 12, I am observing <code>AVSystemController_SystemVolumeDidChangeNotification</code> to detect volume presses to capture images:</p>
  <pre><code>let volumeView = MPVolumeView(frame: CGRect(x: 0, y: -40, width: 0, height: 0)) // override volume view
  view.addSubview(volumeView)
  
  NotificationCenter.default.addObserver(self, selector: #selector(captureImage), name: Notification.Name(rawValue: &quot;AVSystemController_SystemVolumeDidChangeNotification&quot;), object: nil)
  </code></pre>
  <p>However, I've noticed that the notification also fires, at least on an iPhone XS and XS Max, when the lock button (on the right side of the device) is pressed.</p>
  <p>Tried searching around and haven't seen anyone mentioning this issue or much discussion of this notification. Other similar attempts to listen to the volume buttons presses use AVAudionSessions / KVO, but I found that whenever I used that the observer did not get called when the volume was already at max/min. This <code>AVSystemController_SystemVolumeDidChangeNotification</code> seems to work just fine, except for this strange lock button issue. Don't see how, from the name of the notification, why it would respond to the lock button being pressed.</p>
  <p>When the lock button is pressed I get the following messages in the console:</p>
  <blockquote>
  <p>[avas] AVAudioSessionPortImpl.mm:56:ValidateRequiredFields: Unknown selected data source for Port Speaker (type: Speaker) // <em><strong>this appears four times</strong></em></p>
  <p>+[CATransaction synchronize] called within transaction // <em><strong>this appears twice</strong></em></p>
  </blockquote>
  <p>These logs do not appear when the volume button is pressed.</p>
  <p>Note also I don't plan to submit the App Store, so I am not concerned about whether Apple rejects this app on the basis of using this possibly private notification.</p>
  <p>If instead of <code>AVSystemController_SystemVolumeDidChangeNotification</code> I create an <code>AVAudioSession</code> and observe <code>outputVolume</code> like so:</p>
  <pre><code>let audioSession = AVAudioSession()
  try? audioSession.setActive(true)
  audioSession.addObserver(self, forKeyPath: &quot;outputVolume&quot;, options: NSKeyValueObservingOptions.new, context: nil)
  </code></pre>
  <p>… then it isn't hit when the device locks, but I'm still seeing the &quot;AVAudioSessionPortImpl.mm unknown selected data source for Port Speaker&quot; console errors. But then when the volume is muted it doesn't receive presses anymore. I guess what I'd need to do is manually change the volume so it doesn't hit the min or max?</p>
  <p>Thank you</p>