Migrate iOS Sender App From Cast SDK v2 to the Cast Application Framework (CAF)

The following procedure enables you to convert your iOS sender app from Cast SDK v2 to CAF Sender, which is based on the GCKCastContext singleton.

Introduction

  • CAF Sender is still distributed on the Google Cast developer website and CocoaPods, like v2.
  • New classes have been added that take on responsibility for complying with the Google Cast design checklist.
  • CAF Sender provides widgets that comply with the Cast UX requirements; v2 did not provide any UI components and required you to implement these widgets.
  • CAF Sender design is consistent with the Cast Android SDK design.
  • CAF Sender supports Bitcode, like v2.
  • Closed captioning in CAF is similar to v2.

Dependencies

CAF Sender supports iOS version 8 and later.

Initialization

In CAF, an explicit initialization step is required for the Cast framework. This involves initializing the GCKCastContext singleton, using an appropriate GCKCastOptions to specify the Web Receiver application ID and any other global options. This is typically done in the AppDelegate -[application:didFinishLaunchingWithOptions:] method:

GCKCastOptions *options = [[GCKCastOptions alloc]
    initWithReceiverApplicationID:applicationID];
[GCKCastContext setSharedInstanceWithOptions:options];

This step was not necessary in v2.

Device discovery

In CAF, the discovery process is started and stopped automatically by the framework when the app comes to the foreground and goes to the background, respectively. The GCKDeviceScanner and GCKFilterCriteria classes from v2 are deprecated and should not be used.

Cast button and Cast dialog

In CAF, the Cast button and dialog are provided by the framework. The Cast button can be instantiated and added to the navigation bar as follows:

GCKUICastButton *castButton =
    [[GCKUICastButton alloc] initWithFrame:CGRectMake(0, 0, 24, 24)];
castButton.tintColor = [UIColor whiteColor];
self.navigationItem.rightBarButtonItem =
    [[UIBarButtonItem alloc] initWithCustomView:castButton];

The Cast button can also be added to the storyboard.

When someone taps the button, the Cast dialog is presented automatically.

Device control

In CAF, device control is largely handled by the framework. The sender application does not need to handle connecting to the device and launching the Web Receiver application. The v2 class GCKDeviceManager is deprecated and should not be used. Interaction between sender and Web Receiver is now represented as a "session". The CAF GCKSessionManager class handles session lifecycle and automatically starts and stops sessions in response to user gestures: a session is started when the user selects a Cast device in the Cast dialog and is ended when the user taps the "Stop Casting" button in the Cast dialog or when the sender app itself terminates. The sender application can be notified of session lifecycle events by registering a GCKSessionManagerListener with the GCKSessionManager. The GCKSessionManagerListener protocol defines callback methods for all session lifecycle events.

The GCKCastSession class represents a session with a Cast device. The class has methods for controlling the device volume and mute states, which was previously done in v2 using methods on GCKDeviceManager.

In v2, the GCKDeviceManagerDelegate protocol provided notifications of changes to the device state, including volume, mute state, standby status, and so on. In CAF, volume/mute state change notifications are delivered via callback methods in the GCKSessionManagerListener protocol; these listeners are registered with the GCKSessionManager. All of the remaining device state notifications are delivered via a GCKCastDeviceStatusListener protocol; these listeners are registered with the GCKCastSession.

Reconnection logic

As with v2, CAF attempts to re-establish network connections that are lost due to temporary WiFi signal loss or other network errors. This is now done at the session level; a session can enter a "suspended" state when the connection is lost, and will transition back to a "connected" state when connectivity is restored. The framework takes care of reconnecting to the Web Receiver application and reconnecting any Cast channels as part of this process.

In addition, CAF also adds automatic session resumption. If the sender application is sent to the background or is terminated (by swiping-away or because of a crash) while a Cast session is in progress, the framework will attempt to resume that session when the sender application returns to the foreground or is relaunched; this is handled automatically by the GCKSessionManager, which will issue the appropriate callbacks on any registered GCKSessionManagerListener instances.

Custom channel registration

In v2, custom channels (implemented using either a GCKCastChannel subclass or a GCKGenericChannel and delegate) were registered with the GCKDeviceManager. In CAF, custom channels are instead registered with the GCKCastSession instance. The registration can be done in the GCKSessionManagerListener -[sessionManager:didStartCastSession:] callback method. For media applications, it is no longer necessary to explicitly register the GCKMediaControlChannel; see the following section for more details.

Media control

The v2 class GCKMediaControlChannel is deprecated and should not be used. In CAF, it is superseded by the new GCKRemoteMediaClient class, which provides equivalent functionality in a more convenient API. It is not necessary to explicitly initialize or register this object; the framework will automatically instantiate the object and register the underlying media channel at session start time if the Web Receiver application being connected to supports the media namespace.

The GCKRemoteMediaClient can be accessed with the -[remoteMediaClient] property of the GCKCastSession object.

In v2, all media requests issued on the GCKMediaControlChannel would return a numeric request ID, and methods on GCKMediaControlChannelDelegate would provide this ID when sending notifications about request completion or failure.

In CAF, all media requests issued on the GCKRemoteMediaClient will return a GCKRequest object; this object has an associated GCKRequestDelegate protocol which can be used to track the progress and eventual outcome of the request.

The v2 GCKMediaControlChannel; would send notifications about changes in the media player state on the Web Receiver via the GCKMediaControlChannelDelegate. In CAF, the GCKRemoteMediaClient provides equivalent callbacks via its GCKRemoteMediaClientListener protocol. Any number of listeners can be registered with the GCKRemoteMediaClient, which allows multiple sender components to share the single instance of GCKRemoteMediaClient that is associated with the session.

In v2, the sender application had to take on the burden of keeping the user interface in sync with the media player state on the Web Receiver. In CAF, the class GCKUIMediaController takes on most of this responsibility; see the codelab tutorial documentation for examples on how to use this component.

Introductory overlay

V2 does not provide an introductory overlay UI.

CAF adds class GCKCastContext with a method -[presentCastInstructionsViewControllerOnce] that a sender app can use to highlight the Cast button when it is first shown to users.

Mini controller

In v2, you need to implement a mini controller from scratch in the sender app.

In CAF, the framework provides a control bar, GCKUIMiniMediaControlsViewController, which you can add to the scenes where you want to show the persistent controls. There are two ways to add the mini controller to a sender app:

Expanded controller

In v2, you need to implement an expanded controller from scratch in the sender app.

CAF adds GCKUIMediaController, which you could use to more easily implement an expanded controller.

CAF adds a pre-built expanded controller widget GCKUIExpandedMediaControlsViewController which you can simply add to your app. You no longer need to implement a custom expanded controller using GCKUIMediaController.

Debug logging

The GCKLogger and GCKLoggerDelegate classes from v2 are carried over into CAF, with some changes and enhancements.

The GCKLoggerDelegate -[logFromFunction:message:] method has been deprecated in favor of -[logMessage:fromFunction:].

Framework log messages can now be filtered by constructing an appropriate GCKLoggerFilter instance and assigning it by setting the -[filter] property of the GCKLogger singleton.

Sample apps

We recommend looking at the codelabs and sample apps written for CAF.