Airplay mirroring in iOS apps - ios

I have looked several links and read the Apple Documentation but I don't get any step-wise instructions to mirror the content of app on an external device. All they explain is how to display a new window for an external screen if recognized.
In my app, I just need to display the current screen being shown in the app on an airplay enabled device. There is a airplay button, clicking on which will check for available external screens and display the content present on the device on that screen.

Well the reason is simple. AirPlay mirroring is enabled by the user from the settings as #Meera mentioned below. The idea to use in code app is to either display selective things (audio/video) on the TV via AirPlay or to use it as a second Window, where the user does see other things. However if you want you can simply send the whole view to the external screen using this code:
// Check for external screen and if found send output there
if ([[UIScreen screens] count] > 1) {
UIScreen *externalScreen = [[UIScreen screens] objectAtIndex:1];
NSArray *screenModes = externalScreen.availableModes;
//set max resolution
externalScreen.currentMode = [screenModes lastObject];
self.window.screen = externalScreen;
}

Related

Get UIWindow of AirPlay mirroring screen

I'm trying to get the UIWindow object of the external screen (such as a television) when using AirPlay mirroring. The tricky part: it really is AirPlay mirroring, not a separate display, as we're using the built-in functionality of AirPlay rather than setting up a new UIWindow object and assigning it to the new screen. My boss wants the app to mirror the device in every way, but to be able to add subviews (tutorial overlays) to the external window exclusively, by adding them to the secondary screen's UIWindow.
What I've Tried:
I can get the secondary UIScreen object easily, either from UIScreenDidConnectNotification or [UIScreen screens], but as far as I know UIScreens don't have references to the UIWindow being shown.
Since we're just using the display that AirPlay auto-generates, I can't save a reference to the UIWindow during its creation.
I've checked [[UIApplication sharedApplication] windows], and it doesn't seem to include the UIWindow associated with the external display. (At least, none of the window.screen objects match the UIScreen object I get from UIScreenDidConnectNotification when the TV first connects, and while [[UIScreen screens] count] goes up by 1 when a TV is connected, the count of windows remains static.)
Is there a way to access the window for a secondary screen using AirPlay mirroring? Or alternatively, is there a way to efficiently implement app-wide mirroring of the device, that allows greater control of the UIWindow object associated with the TV?
This document from Apple:
https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/WindowAndScreenGuide/UsingExternalDisplay/UsingExternalDisplay.html
states that:
To re-enable mirroring after displaying unique content, simply remove
the window you created from the appropriate screen object.
This means that when mirroring is active, there is no window linked to it, and the mirroring just uses the window of the main screen.
There is only a single window, and I don't think it's possible to show different content in this mode.
If you want to show different content, you'll have to create a new window and assign it to that screen.

Not able to push a custom view to external display using airplay (Apple TV)

Trying to show a custom screen on an external display connected to apple tv using airplay. We are also trying to stream audio via AppleTV after the pairing. (Audio is optional here, it's good to have but not required).
The problem is, if we do audio playback (using AVAudioPlayer), it works fine as expected, but cannot display the custom screen. On the other hand, selecting it from the Control Center makes it work fine except that we don't want to mirror the screen, we want to display a custom view.
Any help in this regard is much appreciated.
Uploaded a sample code for the AirPlay issue in dropbox - https://dl.dropboxusercontent.com/u/1307156/AirplayDemo.zip
What you're trying to do is actually quite simple:
Once an external screen has been added you can create a new UIWindow, a new UIViewController, which will be controlling your custom view displayed to the external screen, and set that just created window to the external UIScreen.
// new window binding
newWindow.screen = externalScreen;
[newWindow makeKeyAndVisible];
You can observe changes over external screens (a screen added, removed, changes over screenModes) through the NSNotificationCenter and do something accordingly for your purposes.

Display one thing on iPad and another on Apple Tv?

I have an app idea, but I'm not sure if it's possible.
I was wondering if I'm able to display one thing on the iPad ( or iPhone )
screen, and something totally different on the Apple Tv at the same time.
For example, a quiz app, where the question is displayed on the Apple Tv, and the multiple choices are listed on the iPad for the user to pick.
I'm not sure if this is possible or if you can only Mirror the iPad screen onto the Apple Tv.
If there is some "Proof of Concept" example code, I'd love to take a look.
Thank you so much.
Chris
Turns out that is is pretty simple to support two screens: the primary screen of the iOS device and a secondary screen (either an external display or mirroring on an Apple TV).
Based on information from the blog post Creating a Dual-Screen AirPlay Experience for iOS and Apple TV, you don't need to do much.
Basically you need to check the screens property from UIScreen. There are also notifications you should listen for (UIScreenDidConnectNotification and UIScreenDidDisconnectNotification) so you know if the number of screens changes while your app is running.
Once you have a second screen, you need to create a new window for it. Code like the following can be used:
if ([UIScreen screens].count > 1) {
if (!_secondWin) {
UIScreen *screen = [UIScreen screens][1];
_secondWin = [[UIWindow alloc] initWithFrame:screen.bounds];
_secondWin.screen = screen;
}
}
where _secondWin is a UIWindow ivar.
Once the window is setup, create a view controller, make it the window's root view controller, and show the window:
SomeViewController *vc = [[SomeViewController alloc] init...];
_secondWin.rootViewController = vc;
_secondWin.hidden = NO;
This is pretty much it other than proper handling of the notifications. Keep in mind that you can't get any touch events on the 2nd display so make sure whatever you show is basically display-only.
Depending on your app, you might have the 2nd screen/window being used throughout the lifetime of the app (as long as the 2nd screen is available any way). Or you might only create and use the 2nd window/screen under certain circumstances. When you don't setup the 2nd window/screen, your app will simply be mirrored to the 2nd display or Apple TV.
The last piece is to turn on mirroring to the Apple TV. This is done on the iOS device, not in the app.
The blog post I linked has a few more details worth reviewing.

For iOS when would an App use more than one Window?

In the view programming guide for iOS, it states "Every iOS application needs at least one window—an instance of the UIWindow class—and some may include more than one window."
What are some examples Apps that would need more than one window?
Thanks
Apps that require to output video to a second screen might use more than one window.
Here you have a question about that particular topic.
You could also use more than one window to achieve other objectives, but that is not recommended by Apple. In general if you see that you need 2 windows or more, I'd suggest that something is wrong with your approach.
I've played around with 2 windows to integrate cocos2d and uikit in a test project, the code was pretty clean and the idea was to switch between windows, using the visibility and the key window, as necessary. It worked, but sometimes when sending the app to background, for some magical reason the active, key window would be made invisible.
Afaik the only case you'd need more than one window is if you connect another screen like a TV to your device. In that case you could provide a totally independent UI for the second screen. F.e. the Keynotes app on iPad does that when you connect another screen to the device.
You could register for the UIScreenDidConnectNotification and handle it like this:
- (void)screenDidChange:(NSNotification *)notification
{
if ([UIScreen screens] count] > 1)
{
UIScreen *extScreen = [[UIScreen screens] objectAtIndex:1];
UIWindow *extWindow = [[UIWindow alloc] initWithFrame:[extScreen bounds]];
//add some subviews to the window
extWindow.screen = extScreen;
[extWindow makeKeyAndVisible];
}
}

Where can I find iOS dual display for Apple TV documentation?

Would anyone know the whereabouts of the documentation on how to implement AirPlay dual-screen functionality into an app?
e.g. http://www.apple.com/uk/appletv/airplay/
This link has very brief, but from what I can see totally sufficient information if you scroll down to "Make the Most of a Second Display".
In short, you register for notifications on a connect to an external display to get a handle to it, and switch between drawing on the two displays by using setScreen(). Besides that, everything drawing related should be "the usual".
Overview
The user can connect additional screens to an iOS device at any time using AirPlay or a physical cable. Each additional screen represents new space on which to display your app’s content, and is managed by a UIScreen object. For example, a game might show its content on a connected display and show game controls on the iPhone screen, as illustrated in Figure 1. Displaying Content on a Connected Screen

Resources