8

I've been searching round for a while to find a way to determine if an iOS external screen is cable connected OR over the air and can't find any obvious way.

I've seen the unofficial AirPlay specs HERE, but can't see any obvious way of detecting it. Does anybody know if this can be done using legit / 'public' API.

Herwr
  • 494
  • 2
  • 7
  • 1
    Why do you want to know? The "hardwired" TV out is actually AirPlay-over-a-wire anyway. What exactly are you trying to detect? – Jesse Rusak Jan 08 '14 at 03:03
  • 1
    Yes I know it's essentially the same protocol over wire, but we develop a security sensitive app that some clients wish to restrict to only allow Airplay mirroring over a hard-wired connection - Due to the well publicised insecurity of broadcasting Airpay displays over wifi and the potential for unauthorised parties to view it. – Herwr Jan 08 '14 at 03:22

2 Answers2

6

Yes, there actually is a way.

Somewhere in your app, create an instance of MPVolumeView. Hold on to in in some instance variable. You don't have to add it as a subview to anything, it simply has to exist.

Then subscribe to the MPVolumeViewWirelessRouteActiveDidChangeNotification like so:

  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(handleWirelessRouteActiveDidChangeNotification:)
                                               name:MPVolumeViewWirelessRouteActiveDidChangeNotification
                                             object:nil];

Add these methods to find out about the state of external displays:

- (BOOL)isAirPlayConnected
{
    return _volumeView.isWirelessRouteActive;
}

- (BOOL)isAirPlayMirroringActive
{
    if ([self isAirPlayConnected]) {
        NSArray *screens = [UIScreen screens];

        if ([screens count] > 1) {
            return [screens[1] mirroredScreen] == [UIScreen mainScreen];
        }
    }

    return NO;
}

- (BOOL)isAirPlayPlaybackActive
{
    return [self isAirPlayConnected] && ![self isAirPlayMirroringActive];
}

- (BOOL)isExternalPlaybackActive
{
    if ([self isAirPlayPlaybackActive]) {
        return YES;
    } else {
        NSArray *screens = [UIScreen screens];

        if ([screens count] > 1) {
            return [screens[1] mirroredScreen] != [UIScreen mainScreen];
        }
    }

    return NO;
}

Additionally you can check for the UIScreenDidConnectNotification and UIScreenDidDisconnectNotification notifications. Armed with all of this, you can tell if you are connected to AirPlay, if AirPlay Mirroring is active, if you AirPlay playback (not mirroring) is active or if you are using any external screen without mirroring.

Johannes Fahrenkrug
  • 42,912
  • 19
  • 126
  • 165
  • isAirPlayMirroringActive not working but others work like a charm, thanks. it's because [UIScreen screens] count is always 1, maybe it was different before. – MGY Aug 23 '17 at 11:08
2

I don't believe there is any public API for this. I would guess that, in Apple's view, this is not your app's concern. It's up to the user what they do with your app's screen: they can screenshot it and email it to everyone, or just plug a wire into a projector and show it on the side of a building. Trying to prevent these from within an app isn't likely to be possible.

You can achieve some of this, however, with Apple's Configurator tool. It allows you to configure, say, a company-owned iOS device to allow AirPlay only to certain hosts. It can also prevent screenshots and other things that might be helpful. I don't know if you can get exactly what you're looking for, but it might be something to look in to if you have some level of control over the devices this app is going to be installed on.

Jesse Rusak
  • 56,530
  • 12
  • 101
  • 102
  • Thanks for the replay - Yea we do something similar through the App already, which allows the client company to restrict certain features including AirPlay, however there is a requirement to allow direct wired displays only (as opposed to over-air). Note we are dealing with potentially highly sensitive information contained on the devices, so unfortunately in this case it doesn't necissarily fit in with the default 'user should be able to do what they want' scenario. – Herwr Jan 08 '14 at 20:49
  • Also, I'm not necessarily after a public API, just an 'Apple legal' way of detecting it - As in, it will pass Apple's code review process. – Herwr Jan 08 '14 at 20:52