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.
With the appropriate cable or adapter, you can connect your iPhone to a secondary display, like a computer monitor, TV, or projector. Plug a Lightning Digital AV Adapter or Lightning to VGA Adapter into the charging port on the bottom of iPhone. Connect an HDMI or VGA cable to the adapter.
Plug your Digital AV or VGA adapter into the charging port on the bottom of your iOS device. Connect an HDMI or VGA cable to your adapter. Connect the other end of your HDMI or VGA cable to your secondary display (TV, monitor, or projector). Turn on your secondary display.
You can connect your iPhone to a TV using an AV cable, AirPlay, or screen mirroring. To AirPlay or screen mirror your iPhone, you also need to have an Apple TV or AirPlay 2-compatible smart TV. With AirPlay, you can stream content directly from video apps like Hulu and HBO Max.
Stream video from your iPhone, iPad, or iPod touch to a TVConnect your device to the same Wi-Fi network as your Apple TV or AirPlay 2-compatible smart TV. Find the video that you want to stream. Tap AirPlay . In some apps, you might need to tap a different button first.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With