skip to Main Content

I initialize Google Cast SDK in my application: didFinishLaunching like that:

let criteria = GCKDiscoveryCriteria(applicationID: kGCKDefaultMediaReceiverApplicationID)
let options = GCKCastOptions(discoveryCriteria: criteria)
GCKCastContext.setSharedInstanceWith(options)

I’ve tried to stream video content to Default Media Receiver and it works.

But I need to be able to change kGCKDefaultMediaReceiverApplicationID to a custom receiver application id to send different content to a custom receiver application I’ve registered via Google Cast SDK Developer Console. I can’t relaunch the app to specify a different application id.

Is there any way to do it dynamically at some point in the app after GCKCastContext.setSharedInstanceWith(options) has already been called?

The call of this method works only once and I cannot update GCKDiscoveryCriteria: GCKCastContext.setSharedInstanceWith(options)

I use ‘google-cast-sdk-no-bluetooth’, version: 4.5.3

In Android SDK there is a method which can change the receiver app id on the fly: https://developers.google.com/android/reference/com/google/android/gms/cast/framework/CastContext#public-void-setreceiverapplicationid-string-applicationid

Unfortunately, I don’t see anything like that in the iOS SDK 🙁

The only thing I found is this (inside GCKSessionManager):

/**
 * Sets the default session options for the given device category.The session options are passed to
 * the GCKDeviceProvider::createSessionForDevice:sessionID:sessionOptions: method when the user
 * selects a device from the Cast dialog.  For Cast sessions, the session options can specify which
 * receiver application to launch.
 *
 * @param sessionOptions The session options. May be <code>nil</code> to remove any previously set
 * options.
 * @param category The device category.
 *
 * @since 4.0
 */
- (void)setDefaultSessionOptions:(nullable GCKSessionOptions *)sessionOptions
               forDeviceCategory:(NSString *)category;

But there is no documentation on which sessionOptions and category to pass (category is probably kGCKCastDeviceCategory). It’s not understandable which params exist and how to construct them.

2

Answers


  1. Chosen as BEST ANSWER

    I found a solution after some time of reverse engineering. It requires 2 steps which are necessary:

    Step 1: Initializing GCKDiscoveryCriteria using a private Objective-C call:

    let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID)
    let initWithIds = Selector(("initWithApplicationIDs:"))
    if criteria.responds(to: initWithIds) {
        criteria.perform(initWithIds, with: NSOrderedSet(array: [kGCKDefaultMediaReceiverApplicationID, kReceiverAppID]))
    }
        
    let options = GCKCastOptions(discoveryCriteria: criteria)
    GCKCastContext.setSharedInstanceWith(options)
    

    Here you need to provide an instance of NSOrderedSet with application ids you want to use. In my case one of them is default media receiver app id, and the second is custom.

    Step 2: Dynamically setting what app id to use for the newly created sessions. You can call it many times during your app lifecycle:

    let sessionManager = GCKCastContext.sharedInstance().sessionManager
    sessionManager.setDefaultSessionOptions(["gck_applicationID": NSString("YOUR_RECEIVER_APP_ID")],
                                                                                    forDeviceCategory: kGCKCastDeviceCategory)
        
    

    Here we use a string gck_applicationID as a key. I've spent several days trying to find it and finally managed to do it!!! You can use kGCKDefaultMediaReceiverApplicationID as a value, or your custom receiver app id.

    Thanks to @iUrii and his direction to go reverse engineering. https://stackoverflow.com/a/65408060/5147552

    P.S.: I used a private method to accomplish what I wanted. It works in google-cast-sdk-no-bluetooth, version 4.5.3. But potentially it's a subject to change. Be careful when using it, since the new versions of SDK might break it.


  2. You can delete a Cast’s singleton instance by calling private objc unsetSharedInstance selector and then set it again:

    let unset = Selector("unsetSharedInstance")
    if GCKCastContext.responds(to: unset) {
        GCKCastContext.perform(unset)
    }
    GCKCastContext.setSharedInstanceWith(GCKCastOptions(discoveryCriteria: GCKDiscoveryCriteria(applicationID: "APP_ID")))
    

    You can use it as a temporary solution because it can be changed in new versions of the library.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search