Enable casting to Chromecast devices (iOS)

Learn how to enable casting with the iOS SDK.


The Google Cast framework enables a viewer to stream video and audio content to a compatible TV or sound system. By enabling the Google Cast framework in your app, a viewer can use a cast button to stream your content to a Chromecast-enabled device on a shared network connection.

🚧

  • The JWP iOS SDK supports casting to the Default Media Receiver and to Styled Media Receivers.

  • Custom receivers are not officially supported. However, if the video playback implements the same interface used in the Default Media Receiver, you may be able to initiate a casting session with a custom receiver.

  • To specify a receiver and start scanning for devices, pass a media receiver app ID to the withAppId argument of the startScanningForDevices method of the JWCastController.



Requirement

Item Description
Google Cast SDK This SDK handles discovery of, casting to, and disconnecting from chromecast devices.
  1. Download the framework.
  2. Manually add the framework to your project. This step includes manually adjusting project settings, and adding 15+ standard frameworks to the project, as described in the link.
  3. Initialize the Google Cast SDK in your AppDelegate.

🚧

The JWP iOS SDK's cast integration requires that you link your app to the dynamic build of the Google Cast SDK. Since Google only distributes its static libraries via CocoaPods, there is no CocoaPods integration option β€” only the manual download approach described above is possible.



Set up permissions

  1. If you are using Xcode 12 and targeting iOS 12+, enable Access Wifi Information.

    πŸ“˜

    1. Click the app target > Capabilities > Access WiFi Information.
      2. Click the toggle to ON to enable Access Wifi Information.
  2. (Guest mode only) In the Info.plist for your app, add NSBluetoothAlwaysUsageDescription to create a Bluetooth access request. Read Are there changes in iOS 13 that may impact my app? in the FAQs section below.

    πŸ“˜

    If you are using the google-cast-sdk-no-bluetooth dependency, you can skip this step.

  3. (iOS 14) In the info.plist, add the following two keys:
    • NSBonjourServices with _googlecast._tcp and _<your-app-id>._googlecast._tcp inside the array
    • NSLocalNetworkUsageDescription

    <key>NSBonjourServices</key>
    <array>
      <string>_googlecast._tcp</string>
      <string>_ABCD1234._googlecast._tcp</string>
    </array>
    <key>NSLocalNetworkUsageDescription</key>
    <string>${PRODUCT_NAME} uses the local network to discover Cast-enabled devices on your WiFi
    network.</string>
    


Configure and enable casting

With JWPlayerViewController

Initialize the CastContext as described in Google's article, Integrate Cast Into Your iOS App.

After initializing a CastContext, casting is handled automatically by JWPlayerViewController. A casting button will appear on the player, and you can respond to casting-related callbacks by overriding the JWCastingDelegate methods on JWPlayerViewController.

πŸ’‘

If you are trying to cast outside of JWPlayerViewController, JWPlayerViewController might interfere with your implementation because the Google Cast SDK uses as singleton. To prevent JWPlayerViewController from handling casting, set handleCastingInternally to false.

class CustomPlayerViewController: JWPlayerViewController {

    override var handleCastingInternally: Bool {
        return false
    }
}


Without JWPlayerViewController

  1. Initialize the CastContext as described in Google's article, Integrate Cast Into Your iOS App.

  2. In your app, create a JWCastController object and set its delegate. The delegate must adhere to the JWCastDelegate protocol and implement its delegate methods.

    func setUpCastController() {
        castController = JWCastController(player: player)
     
        castController?.delegate = self
    }
    
    - (void)setUpCastController
    {
        self.castController = [[JWCastController alloc] initWithPlayer:self.player];
        
        self.castController.delegate = self;
    }
    
  3. Call startDiscovery() to scan for devices.

    func beginScanning() {
        castController.startDiscovery()
    }
    
    - (void) beginScanning
    {
        [self.castController startDiscovery];
    }
    

    Once available devices are discovered, the event is reported to the JWCastDelegate method, devicesAvailable:. This method supplies a list of available devices within range as an array of JWCastingDevice.

    func castController(_ controller: JWCastController, devicesAvailable devices: [JWCastingDevice]) 
    {
        availableDevices = devices
    }
    
    -	(void)castController:(JWCastController *)controller devicesAvailable: (NSArray<JWCastingDevice *> *)devices
    {
        self.availableDevices = devices;
    }
    
  4. Call the connectToDevice: method to connect to a device.

    When a connection is established, the JWCastingDelegate method, connectedTo:, is called. This signals the ability to cast the video that is reproduced by the JWPlayer instance.

    func onUserSelectedDevice(_ index: Int!) 
    {
        let chosenDevice = availableDevices[index]
        castController?.connectToDevice(chosenDevice)
    }
    
    -(void)onUserSelectedDevice:(NSInteger)index
    {
        JWCastingDevice *chosenDevice = availableDevices[index];
        [self.castController connectToDevice:chosenDevice];
    }
    
  5. Call cast() on the JWCastController instance.

    func castController(_ controller: JWCastController, connectedTo device: JWCastingDevice) {
        self.castController.cast()
    }
    
    -	(void)castController:(JWCastController *)controller connectedTo:(JWCastingDevice *)device
    {
        [self.castController cast];
    }
    

The JWP API controls the playback of the video being casted. The JWPlayerDelegate provides the playback callbacks while casting.



FAQs

Are there changes in iOS 13 that may impact my app?

Overview

With the release of iOS 13, we want to let you know about an important change. This change is not related to JWP's SDK specifically, but we do want to make sure all of our customers aware of any third-party updates.

Apple has introduced stricter permissions requirements in iOS 13 that enforce a tighter control for Bluetooth access.

In order to prevent failed casting sessions and application crashes, we encourage all customers to make a small change to their iOS applications. This change does not require development changes or SDK updates. But, it does require resubmitting your app to the App Store.

After making the following change to your app, your app users will be required to provide Bluetooth access permissions. If a user declines to give permission to Bluetooth access, the casting button will disappear and casting functionality is disabled. Playback on the device is unchanged.


Implement the change

1328

Use the following steps to implement this change:

  1. In Xcode, open Info.plist for your app.
  2. Create a Key named NSBluetoothAlwaysUsageDescription. When added, this appears as Privacy - Bluetooth Always Usage Description.
  3. From the Type options, select String.
  4. Set a message noting that Bluetooth is needed to enable Google Cast as the Value.

You can also update the source code of Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
	<string>Bluetooth is needed to enable Google Cast.</string>

Which features are not supported when casting with an iOS SDK player?

The following features are not supported during a casting session with an iOS SDK player:

  • Google IMA ads
  • FreeWheel ads
  • Multiple-audio tracks or AudioTrack switching
  • Captions
    • 608 captions
    • Sidecar captions
  • DVR and live streaming capabilities

Also note that Google does not support FairPlay DRM.