ios,swift,casting,chromecast,google-cast , How to properly connect to Google Cast device and cast an url with an custom receiver?

How to properly connect to Google Cast device and cast an url with an custom receiver?


Tag: ios,swift,casting,chromecast,google-cast

For creating this I used Google Cast reference at Github &

Then if you downloaded it have a look at my block of code that has to do with Google Cast. If you see something that makes this error happen, please let me know. Because I honestly don't know if this a Xcode or a Google Cast bug.. or is the most common error.. Humans

Start the emulator, it wil look for active Chrome Cast devices in the network. If found the cast button wil appear. When you press the cast button it wil go to chooseDevice() function and wil present a UIAlertController with the device(s) in your network and then you can select an device you want to cast to.

If you clicked on an device it wil go to connectToDevice() function and make an connection.

When it's connected it should go to the next function called "deviceManagerDidConnect". So I get an message "Connected".. after 5 seconds I get an error message "Error Code=2. Network connection timeout". When I rebuild the project I get an different outcome.. after the "deviceManagerDidConnect" It is now going to "didConnectToCastApplication" function and that didn't happen the first time. Is this a bug or am I doing something wrong?

What I expect is that it is going to "deviceManagerDidConnect" and after that it is going to "didConnectToCastApplication" function. After that all works I want to cast a WKWebView.. I know that not (yet) supported. So I want to cast an URL I gave in an Textfield.

What version of the product are you using? On what operating system?
GoogleCastSDK-2.5.1-Release, OS X Yosemite 10.10.1 Xcode Version 6.1.1 (6A2008a)

Thanks in advance and have a great day,


Below you can find my code..

    // ==================== Google Cast ====================
    // ==================== chooseDevice() ====================
func chooseDevice() {
    if selectedDevice == nil {
        let alertController = UIAlertController(title: "Choose device..", message: "", preferredStyle: .ActionSheet)

        for device in deviceScanner.devices {
            alertController.addAction(UIAlertAction(title: device.friendlyName, style: .Default, handler: { alertAction in
                self.selectedDevice = device as GCKDevice

        let addCancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: { alertAction in
            alertController.dismissViewControllerAnimated(true, completion: nil)

        // Add action to the controller

        // Finaly present the action controller
        presentViewController(alertController, animated: true, completion: nil)
    else {

        let mediaTitle = self.mediaInformation?.metadata.stringForKey(kGCKMetadataKeyTitle)
        //            mediaTitle.metadata.stringForKey(kGCKMetadataKeyTitle) //Silver Essence Castaway
        //            var mediaTitle = mediaInformation.metadata.stringForKey(kGCKMetadataKeyTitle)

        NSLog("De waarde van kGCKMetadataKeyTitle is: \(kGCKMetadataKeyTitle)")

        let alertController = UIAlertController(title: "Casting to: \(selectedDevice.friendlyName)", message: nil, preferredStyle: .ActionSheet)

        let addDisconnectingAction = UIAlertAction(title: "Disconnect device", style: .Destructive, handler: { alertAction in
                            println("De waarde van mediaInformation is: \(mediaTitle)")
                            if mediaTitle != nil {
                                (mediaTitle != nil ? 1 : 0)
                                alertController.dismissViewControllerAnimated(true, completion: nil)
                                println("the else UIAlertController")

        let addCancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: { alertAction in
                            println("De waarde van mediaInformation is: \(mediaTitle)")
                            if mediaTitle != nil {
                                (mediaTitle != nil ? 2 : 1)
                                alertController.dismissViewControllerAnimated(true, completion: nil)
                                println("else uiactionsheet")

        // Add action to the controller

        // Finaly present the action controller
        self.presentViewController(alertController, animated: true, completion: nil)

    // ==================== updateStatsFromDevice() ====================
func updateStatsFromDevice() {
    if mediaControlChannel != nil {
        mediaInformation = mediaControlChannel.mediaStatus.mediaInformation

    // ==================== isConnected() ====================
func isConnected() -> Bool {
    return deviceManager.isConnected

    // ==================== connectToDevice() ====================
func connectToDevice() {
    if selectedDevice != nil {
        //            var info = NSBundle.mainBundle().infoDictionary!["CFBundleIdentifier"] as? NSString
        //            deviceManager = GCKDeviceManager(device: selectedDevice, clientPackageName: info)
        deviceManager = GCKDeviceManager(device: selectedDevice, clientPackageName: "CFBundleIdentifier")

        //            NSLog("de waarde van info is \(info)")
        NSLog("de waarde van selectedDevice is \(selectedDevice)")

        deviceManager.delegate = self

    // ==================== deviceDisconnected() ====================
func deviceDisconnected() {
    NSLog("Device disconneted: \(selectedDevice.friendlyName)")
    deviceManager = nil
    selectedDevice = nil
    mediaControlChannel = nil
    textChannel = nil

    // ==================== updateButtonStates() ====================
func updateButtonStates() {
    if (deviceScanner.devices.count == 0) {
        // Hide the cast button
        chromecastButton.setImage(btnImage, forState: .Normal)
        chromecastButton.hidden = true
    if (deviceScanner.devices.count > 0) {

        chromecastButton.setImage(btnImage, forState: .Normal)
        chromecastButton.hidden = false

        // Show cast button
        if (deviceManager != nil) {
            chromecastButton.setImage(btnImageSelected, forState: .Normal)
            chromecastButton.hidden = false

    // ==================== sendText ====================
@IBAction func sendText(sender: AnyObject) {
    NSLog("Cast video")

    if deviceManager == nil {
        var alert = UIAlertController(title: "Not connected", message: "Please connect to Cast device", preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
        presentViewController(alert, animated: true, completion: nil)


    // Define media metadata
    var metaData = GCKMediaMetadata(metadataType: GCKMediaMetadataType.User)

    metaData.setString("Bug Bunny!", forKey: kGCKMetadataKeyTitle)
    metaData.setString("dit is allemaal maar was subtitles", forKey: kGCKMetadataKeySubtitle)
    var url = NSURL(string: "")
    metaData.addImage(GCKImage(URL: url, width: 480, height: 360))

    //        var mediaInformation = GCKMediaInformation(contentID: "", streamType: .None, contentType: "video/mp4", metadata: metaData as GCKMediaMetadata, streamDuration: 0, customData: nil)
    mediaInformation = GCKMediaInformation(contentID: "", streamType: GCKMediaStreamType.None, contentType: "video/mp4", metadata: metaData, streamDuration: 0, customData: nil)

    NSLog("waarde van mediainformation is : \(mediaInformation)")

    self.mediaControlChannel?.loadMedia(mediaInformation, autoplay: true, playPosition: 0)
    //        textChannel.sendTextMessage(textFieldUrl.text)

    // MARK: GCKDeviceScannerListener
    // ==================== deviceDidComeOnline() ====================
func deviceDidComeOnline(device: GCKDevice!) {
    NSLog("device found! \(device.friendlyName)")

    // ==================== deviceDidGoOffline() ====================
func deviceDidGoOffline(device: GCKDevice!) {
    NSLog("device did go offline \(device.friendlyName)")

    // MARK: UIActionSheetDelegate
    // ==================== actionSheet() ====================
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
    if selectedDevice == nil {
        if buttonIndex < deviceScanner.devices.count {
            selectedDevice = deviceScanner.devices[buttonIndex] as GCKDevice
            NSLog("Selecting device: \(selectedDevice.friendlyName)")
    else {
        if buttonIndex == 1 {
            NSLog("Disconnecting device: \(selectedDevice.friendlyName)")
        else if buttonIndex == 0 {
            // Join the existing session

    // MARK: GCKDeviceManagerDelegate
    // ==================== deviceManagerDidConnect() ====================
func deviceManagerDidConnect(deviceManager: GCKDeviceManager!) {

    // ==================== didConnectToCastApplication() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didConnectToCastApplication applicationMetadata: GCKApplicationMetadata!, sessionID: String!, launchedApplication: Bool) {
    NSLog("application has launched")

    // textChannel = HTCGTextChannel(namespace: "urn:x-cast:com.silver.essence.Silver")
    // self.deviceManager.addChannel(textChannel)

    mediaControlChannel = GCKMediaControlChannel()
    mediaControlChannel.delegate = self

    // ==================== didFailToConnectToApplicationWithError() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didFailToConnectToApplicationWithError error: NSError!) {


    // ==================== didFailToConnectWithError() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didFailToConnectWithError error: NSError!) {


    // ==================== didDisconnectWithError() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didDisconnectWithError error: NSError!) {
    NSLog("Received notification that device disconnected")

    if error != nil {


    // ==================== didReceiveApplicationMetadata() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didReceiveApplicationMetadata metadata: GCKApplicationMetadata!) {
    applicationMetadata = metadata

    // ==================== showError() ====================
func showError(error: NSError) {
    var alert = UIAlertController(title: "Something went wrong", message: error.description, preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
    presentViewController(alert, animated: true, completion: nil)

    // ==================== viewDidLoad() ====================
override func viewDidLoad() {
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "saveNSUserDefaults", name: "kSaveSwitchesStatesNotification", object: nil);
    navigationItem.title = "Settings"

    // ==================== Adding the Chromecast button ====================
    //        kReceiverAppID = kGCKMediaDefaultReceiverApplicationID

    NSLog("de waarde van kReceiverAppID in viewDidLoad() is : \(kReceiverAppID)")

    btnImage = UIImage(named: "icon-cast-identified")
    btnImageSelected = UIImage(named: "icon-cast-connected")

    chromecastButton = UIButton()
    chromecastButton.setImage(UIImage(named: "icon-cast-identified"), forState: .Normal)
    chromecastButton.frame = CGRectMake(0, 0, 45, 45)
    chromecastButton.addTarget(self, action: "chooseDevice", forControlEvents: .TouchUpInside)
    chromecastButton.hidden = true

    var rightItem:UIBarButtonItem = UIBarButtonItem()
    rightItem.customView = chromecastButton
    self.navigationItem.leftBarButtonItem = rightItem

    // ==================== Scan for Chromecast devices ====================
    deviceScanner = GCKDeviceScanner()
    filterCriteria = GCKFilterCriteria(forAvailableApplicationWithID: kReceiverAppID)
    deviceScanner.filterCriteria = filterCriteria


finally I found the problem! It was in the receiver. The HTML file that the receiver is loading when you connect to a cast device in your network. Make sure that your HTML file has the proper functions to connect back to the application. Hope this will help someone who is encounter the same problem and not to think about the solution for weeks..

If you don't know which functions are needed look at the examples that Google have provided us.


How to save text field value in uicollectionviewcell

hi i have text field in uicollectionviewcell so what i need it example : when i edit text filed value in row 5 and i done it and go to text filed in row 20 to edit value the collectionview has reloaded and forget value in row 5, so i...

MFMessageComposeViewControllerDelegate not being called

I am trying to implement a class that will present a MFMessageComposeViewController from the AppDelegate. The class declaration looks like this: import UIKit import MessageUI class MyClass: NSObject, MFMessageComposeViewControllerDelegate { func sendAMessage() { // message view controller let messageVC = MFMessageComposeViewController() messageVC.body = "Oh hai!" messageVC.recipients = ["8675309"] // set...

try to recover views from custom cell

I made a custom cell from my storyboard, with an UIImageView and a UILabel. Each of them have a tag 100 for the imageView and 102 for UILabel. I try to get them in my datasource method but as below, they are still nil and I don't know why. ...

Omitting the return type in Swift closures

I'm working through one of the examples at the very handy and colourfully named site here, specifically : func applyMutliplication(value: Int, multFunction: Int -> Int) -> Int { return multFunction(value) } applyMutliplication(2, {value in value * 3 }) Notice that the closure given when calling applyMultiplication() does not specify a...

Scaling everything up and down for different devices in UIStoryboard

Is it possible to have the storyboard scale everything up or down depending on the screen size or do I have to do it programmatically? For example the UI on iPhone 6 plus would look exactly like the one on iPhone 5 but just larger.

NSString to NSDate doesn't work

now it works with this code: NSString *myDate = @"06/18/2015 8:26:17 AM"; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"MM/dd/yyyy hh:mm:ss a"]; [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US"]]; NSDate *date = [dateFormatter dateFromString:myDate]; [dateFormatter setDateFormat:@"dd.MM. HH:mm"]; NSString *dateString = [dateFormatter stringFromDate:date]; cell.timeLabel.text = dateString; ...

Parse and Swift Geopoints not saving

I have tried everything. No matter what my Geopoints will not save when using an actual device with xcode or using the simulator. if signUpError == nil { PFGeoPoint.geoPointForCurrentLocationInBackground { (geoPoint: PFGeoPoint?, error: NSError?) -> Void in if error == nil { PFUser.currentUser()!.setValue(geoPoint, forKey: "location") } } I am not...

It is possible to continuously update the UILabel text as user enter value in UITextField in iOS

In my application i have one UILabel and UITextField. Initially UILabel text in nil. As soon as user enter some text in UITextField my UILabel text also Update. Let say When user enter A in UITextField my UILabel immediately show A, B in UITextField my UILabel show B and so...

How can I fix crash when tap to select row after scrolling the tableview?

I have a table view like this: when the user tap one row, I want uncheck the last row and check the selected row. So I wrote my code like this: (for example my lastselected = 0) func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { var lastIndexPath:NSIndexPath = NSIndexPath(forRow: lastSelected, inSection:...

Extra table cells when UITableViewController is embedded into a Container in a UIViewController

In order to customize a table view and add some additional controls to it, I've embedded a UTTableViewController into a Container View and placed that container View into a UIViewController. I've followed the instructions I found here: Embedding TableView in TableViewController into another view TableView is configured with four static...

Unexpectedly found nil while unwrapping an Optional value - Plist

i am trying to read from propriety list using swift but im getting this error, and thats the code im using to read from my plist : Arrays i'm using : var recipeNames :[String] = [] var recipeImages :[String] = [] var recipeTime :[String] = [] In viewDidload : var...

How can I show ONLY the date (and not the time) using NSDateFormatter?

I think the question is pretty straightforward. I need only the date to appear, and not the time. Couldn't find anything for Swift, so my code is here: = NSDateFormatter.localizedStringFromDate(dates[indexPath.row], dateStyle: .ShortStyle, timeStyle: .ShortStyle) ...

looping variable in swift

i want to change this variable become looping in swift: var image1 = UIImage(named: "image1") var image2 = UIImage(named: "image2") var image3 = UIImage(named: "image3") var image4 = UIImage(named: "image4") var image5 = UIImage(named: "image5") var image6 = UIImage(named: "image6") var image7 = UIImage(named: "image7") images.append(image1!) images.append(image2!) images.append(image3!) images.append(image4!) images.append(image5!)...

IOS - Adjust cell height based on content

im trying to build apps that have tableview cell similiar with twitter, there are text and images. My problem is i want to insert the image above the text. While it can be text only. So if there are no image, the text will be in position (0,0). And if...

How to create UITableViewCells with complex content in order to keep scrolling fluent

I am working on a project where I have a table view which contains a number of cells with pretty complex content. It will be between usually not more than two, but in exceptions up to - lets say - 30 of them. Each of these complex cells contain a...

App crashes when i start typing in uiseachbar in uitableview

I am making a project in which i am fetching addressbook in my tableview with the help of NSObject class. Now , I allocated a UISearchbar in it , but when i start typing , the app crashes with the following error :---- 'Can't use in/contains operator with collection (not...

UITapGestureRecognizer sender is the gesture, not the ui object

I've got a button called and I gave it a UIGestureRecognizer so that an IBAction is only run when the button is long pressed. You do this by adding a UILongPressGestureRecognizer to the button iteself. Then you control drag that gesture recognizer to a function like this: @IBAction func handleGesture(sender:...

How to add checkbox to uicollectionview in swift

some time ago someone already asked this question and a few answers were given but i didn't really understand any of them. So i was wondering if anyone could please write an easy to understand tutorial on how to do the things shown on the image below: I would...

How to get time difference based on GMT on Swift

I am trying to get a time difference based on a GMT time. where at the end of everyday the timer resets to zero. I've tried the below code on the Xcode simulator and every time i change the time on the mac, the difference also changes. how can i...

Difference between stringByAppendingString and appendString in ios

What is the difference between stringByAppendingString and appendString? If NSString is not mutable then how could it append string?

Do I have to use both of these methods?

When I expand a UITableViewCell on touch, I know I have to update the UITableView. Right now I'm doing: tableView.beginUpdates() tableView.reloadRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.Automatic) tableView.endUpdates() Do I need to use both updates methods as well as the reload method? Or is it just one or the other? I'm not completely understanding,...

animating a view on top of uitableview

I have a UINavigationController that has my custom ViewController with a tableView in it that takes up the whole screen. I want to push down the tableView and reveal a settings menu with just a couple items. My SettingsView.xib I created in a separate nib that is 320 x 90...

Call method after asynchronous request obj-c

In my app I init a new object, where there is method which calls NSURLConnection's sendAsynchronousRequest method. After the request, I would like to call a method in the caller UIViewController. I tried to use a static method but I then I can't control IBOutlets. How can I do this?...

UITabBarViewController doesn't rotate - iOS

I have a UITabBarViewController that contains 5 tabs and a login view which is not part of my tab bar, in my settings I have set that I support all device orientations. but when I run my app, only my login view is the only which rotates. I have created...

Build error after I localized Info.plist

I localized Info.plist : And I got this build error : error: could not read data from '/Users/cherif/Apps/Wesh/Info.plist': The file “Info.plist” couldn’t be opened because there is no such file. Actually there are now two Info.plist files : fr.lproj/Info.plist Base.lproj/Info.plist How to localize the Info.plist path ?...

What's the equivalent of finally in Swift

I try to use the error handling modeling in Swift2. do { try NSFileManager.defaultManager().removeItemAtPath("path") } catch { // ... } finally { // compiler error. } But it seems that there is no finally keyword out there.How can I achieve try-catch-finally pattern in Swift.Any help is welcome....

What is the best practice add video background view?

I want to add background view with video (or gif) like in app "Uber" I'd like to use video background view for a long time in my app. And I want to know the answers to these questions: What of them will consume less battery energy Can I use it...

How to disable the Copy/Hide feature in UIImagePickerController when long pressing a image …?

- Actually am using UIImagePickerController for my usecase,and if i long press any picture ,it shows Copy/Hide option (as shown in the sample image) - I dont want the Copy/Hide feature. Guide me with some suggestions if u too have encountered :)... Thanks in advance...iOS Geeks...PLZ refer my code snippet...

Reference method from different class as curried function

There are two merge methods in RACSignal: - (RACSignal *)merge:(RACSignal *)signal; + (RACSignal *)merge:(id<NSFastEnumeration>)signals; When I write RACSignal.merge it references static method: class func merge(signals: NSFastEnumeration!) -> RACSignal! How to reference object method? I can't write self.merge, because it is in wrapper class and self is not RACSignal....

Adding Image And title both to UIsegmentControl IOS

Is there a way so that you can set both image and title of UISegmentControl simultaneously, so that image appear next to the title , just like image appear next to title in UIButton. I am trying but if I set image of Selected segment of UISegmentControl then title disappears...

Getting video from Asset Catalog using On Demand ressources

I attributed to my .mp4 video the "tokyo" tag for example, and set it as installed during the app installation. Now before I was using a Path to get it from my resources, now it's different because it's located on the Asset Catalog. After found documentations, I tried something like...

Twilio Client Python not Working in IOS Browser

I have created a simple twilio client application to make phone calls from Web Browser to phones. I used a sample Flask app to generate a secure Capability Token and used twilio.min.js library to handle calls from my HTML. The functionality works fine in Computer Browsers ans Android Phone Browsers,...

How to draw each a vertex of a mesh as a circle

How to draw each a vertex of a mesh as a circle?

Set color CFAttributedStringRef

I have this methods for draw a table ant populated . What i want is to change the color for one word from each column , but i dont know how can i do it . Can somebeday help me ,please ? Any help will be appreciate . in my...

Is it possible to obtain an unique iCloud user ID on cocoa?

My iOS app is currently on beta in TestFlight, and as a way to retribute to the nice people who helped me test it I would like to offer them some goodies such as, for instance, the full final version of the app for free. For this, I was thinking...