This guide shows you how to create a cast-enabled iOS Sender App by walking you through an existing example app.
To follow along with this guide, download our cast example, which is a complete iOS app that implements casting functionality for videos with ads using the IMA iOS SDK.
Prerequisites
This guide builds upon existing knowledge of the Google Cast SDK and the IMA SDK for iOS. Users should familiarize themselves with:
This guide discusses the specific setup used in the Cast Example to communicate with the receiver. It doesn't cover standard Cast setup code or normal IMA ad playback. For more details on implementing the receiver, see our HTML5 Receiver Guide.
Sending messages
The casting logic for CastExample is implemented in CastViewController.m
. It uses a cast channel
defined in CastMessageChannel.h
to route messages between receiver and sender. The
castVideo
function attempts to load the content URL, it then sends a custom messsage to the
receiver telling it to request ads using the same ad tag and seek to the sender's current timestamp.
CastViewController.m
- (IBAction)castVideo:(id)sender {
// Show alert if not connected.
if (!self.deviceManager ||
self.deviceManager.connectionState != GCKConnectionStateConnected) {
UIAlertController *alert = [UIAlertController
alertControllerWithTitle:@"Not Connected"
message:@"Please connect to Cast device"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action =
[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil];
[alert addAction:action];
[self presentViewController:alert animated:YES completion:nil];
return;
}
[self.viewController pauseVideo];
NSString *contentUrl = self.viewController.kContentUrl;
GCKMediaMetadata *metadata = [[GCKMediaMetadata alloc] init];
GCKMediaInformation *mediaInformation =
[[GCKMediaInformation alloc] initWithContentID:contentUrl
streamType:GCKMediaStreamTypeBuffered
contentType:@"video/mp4"
metadata:metadata
streamDuration:0
customData:nil];
[self.mediaControlChannel loadMedia:mediaInformation
autoplay:NO
playPosition:0];
if (self.viewController.adIsVmap || !self.viewController.adHasStarted) {
[self sendMessage:[NSString
stringWithFormat:@"requestAd,%@,%f",
self.viewController.kAdTagUrl,
CMTimeGetSeconds(
self.viewController.contentPlayer
.currentTime)]];
} else {
[self sendMessage:[NSString
stringWithFormat:@"seek,%f",
CMTimeGetSeconds(
self.viewController.contentPlayer
.currentTime)]];
}
}
- (void)sendMessage:(NSString *)message {
NSLog(@"Sending message: %@", message);
[self.messageChannel sendTextMessage:message];
}
Two messages are defined: seek, to resume playback on the receiver without ads, and requestAd, which re-requests the same ad tag on the receiver. This is used for ad playlists and VMAP in this example, but you can define your own behavior for what should happen when you cast. These messages are comma-delimited, where the first parameter is the message name, and the remaining parameters are ad-tag and seek time.
Receiving messages
The receiver provides notices of time updates from a casting video and when a casted ad stops and content starts. This is handled in the sender by two messages:
onContentPauseRequested
onContentResumeRequested
These messages are comma-delimited and formatted similarly to the seek and requestAd messages described above.
- (void)onCastMessageReceived:(CastMessageChannel *)channel
withMessage:(NSString *)message {
// handle the delegate being called here
NSLog(@"Receiving message: %@", message);
NSArray *splitMessage = [message componentsSeparatedByString:@","];
NSString *event = splitMessage[0];
if ([event isEqualToString:@"onContentPauseRequested"]) {
self.castAdPlaying = true;
self.castContentTime =
CMTimeMakeWithSeconds([splitMessage[1] floatValue], 1);
} else if ([event isEqualToString:@"onContentResumeRequested"]) {
self.castAdPlaying = false;
}
}
The variables castAdPlaying
and castContentTime
are used to determine whether an ad is playing
on the cast device and to store the content time at which the ad was started. In the event the
receiver stops casting, the sender knows where to resume content from.
Next steps
At this point you have a good understanding of how the iOS sender app interacts with the receiver. To try it out, create a receiver app and register your receiver in order to receive an app ID that's used with API calls from the sender app.