iOS AirPlay Second Screen Tutorial

6.7k views Asked by At

I am looking at adding AirPlay capabilities to one of my ViewControllers. The View Controller just shows a UIWebView. What I want to do is add a button that will mirror this content to an Apple TV. I know system-wide mirroring can be done, but it doesn't fill up the entire screen, has black bars all around. I have been searching online, but most everything I have found is way back from iOS 5 and out of date. Could someone point me in the direction of a tutorial or drop-in library that would help out? I just need it to mirror the content of just one view to be full-screen on Apple TV.

So far, here is what I have done, but I believe it only creates the second Window, without putting anything on it.

In the AppDelegate, I create a property for it:

@property (nonatomic, retain) UIWindow *secondWindow;

In didFinish method of AppDelegate I run:

 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

    [center addObserver:self selector:@selector(handleScreenDidConnectNotification:)
                   name:UIScreenDidConnectNotification object:nil];
    [center addObserver:self selector:@selector(handleScreenDidDisconnectNotification:)
                   name:UIScreenDidDisconnectNotification object:nil];

Then in AppDelegate I have:

- (void)handleScreenDidConnectNotification:(NSNotification*)aNotification
{
    UIScreen *newScreen = [aNotification object];
    CGRect screenBounds = newScreen.bounds;

    if (!self.secondWindow)
    {
        self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        self.secondWindow.screen = newScreen;

        // Set the initial UI for the window.
    }
}

- (void)handleScreenDidDisconnectNotification:(NSNotification*)aNotification
{
    if (self.secondWindow)
    {
        // Hide and then delete the window.
        self.secondWindow.hidden = YES;
        self.secondWindow = nil;

    }

}

In the viewController in which I would like to allow to mirror the WebView on Apple TV, I have:

- (void)checkForExistingScreenAndInitializeIfPresent
{
    if ([[UIScreen screens] count] > 1)
    {
        // Get the screen object that represents the external display.
        UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
        // Get the screen's bounds so that you can create a window of the correct size.
        CGRect screenBounds = secondScreen.bounds;

       appDelegate.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        appDelegate.secondWindow.screen = secondScreen;

        // Set up initial content to display...
        // Show the window.
       appDelegate.secondWindow.hidden = NO;
        NSLog(@"YES");

    }
}

I got all this from here. However, that's all that it shows, so I'm not sure how to get the content onto that screen.

3

There are 3 answers

1
Noah Witherspoon On

Depending on what’s going on in your web view, you’ll either have to make a second one pointed at the same page or move your existing one to the new window. Either way, you treat the second window pretty much the same as you do your app’s main window—add views to it and they should show up on the second display.

2
NSSplendid On

There are only two options to do Airplay 'mirroring' at the moment: the system-wide monitoring and completely custom mirroring. Since the system-wide mirroring is not a solution for you, you'll have to go down the way you already identified in your code fragments.

As Noah pointed out, this means providing the content for the second screen, the same way as providing it for the internal display. As I understand you, you want to show the same data/website as before on the internal display, but display it differently in the remote view/webview (e.g. different aspect ratio). One way can be having one webview follow the other in a master/slave setup. You'd have to monitor the changes (like user scolling) in the master and propagate them to the slave. A second way could be rendering the original webview contents to a buffer and drawing this buffer in part in a 'dumb' UIView. This would be a bit faster, as the website would not have to be loaded and rendered twice.

0
livingtech On