2

I'm using latest Google Cast SDK for iOS (version 3.1.1.10003) and our app is remote controlling Google Cast devices, e.g. it changes their volume. It needs to do so also when our app goes to background.

However, GCKSessionManager invokes suspendSessionWithReason: when the app goes to background. This said, the session will be suspended and thus our app can't control it any longer.

How can I make GCKSessionManager not suspend sessions when apps go to background?

Edit: I'm providing a solution below but that is not user friendly due to significant delays when reconnecting.

Lars Blumberg
  • 19,326
  • 11
  • 90
  • 127

2 Answers2

7

In the latest Google Cast SDK, you can set it in the options like so:

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

However, regardless of that, the session dies from a lost network connection. The trick becomes playing an "empty" audio file from the device, which keeps it alive. Stupid to think that this must be the industry standard.

Matt Mc
  • 8,882
  • 6
  • 53
  • 89
  • Hi, I'm having the same issue. As per your suggestion, we play empty audio file from device. Not sure, I understand that. When the app is already in background, how will you play the empty audio file to keep the session alive? – Renu Apr 29 '18 at 22:09
  • @Renu When you start casting, you start playing the empty audio file, basically. You don't start playing it when you go to background, IIRC. – Matt Mc May 30 '18 at 18:52
3

As Google Cast SDK calls GCKSessionManager.suspendSessionWithReason when the app goes to background, one solution is to replace this method with a different implementation that checks if the reason is .AppBackgrounded and then actually ignores the call.

Then SDK doesn't kill the the session immediately when app goes to background but it will still suspend the session at a later point. The session can however be restarted from background mode – it however takes significant time and that delay is negatively perceived from the user perspective. Furthermore the session regularly suspends again after a few seconds of not "talking to it".

Any better solution is still very much appreciated.

extension GCKSessionManager {
    static func ignoreAppBackgroundModeChange() {
        let oldMethod = class_getInstanceMethod(GCKSessionManager.self, #selector(GCKSessionManager.suspendSessionWithReason))
        let newMethod = class_getInstanceMethod(GCKSessionManager.self, #selector(GCKSessionManager.suspendSessionWithReasonIgnoringAppBackgrounded))
        method_exchangeImplementations(oldMethod, newMethod)
    }

    func suspendSessionWithReasonIgnoringAppBackgrounded(reason: GCKConnectionSuspendReason) -> Bool {
        guard reason != .AppBackgrounded else { return false }
        return suspendSessionWithReason(reason)
    }
}

All we need to do now is to call GCKSessionManager.ignoreAppBackgroundModeChange().

Edit:

As of latest Google Cast SDK, it has a new option to keep sessions alive in background.

Lars Blumberg
  • 19,326
  • 11
  • 90
  • 127
  • 2
    in the latest SDK session gets suspended on completion of current item with reason "GCKConnectionSuspendReasonNetworkNotReachable " Any way of overcoming this obstacle? – Vikas Dadheech Aug 09 '17 at 10:45
  • I also got `GCKConnectionSuspendReasonNetworkNotReachable` error with `suspendSessionsWhenBackgrounded = true`. Google Cast SDK 4.4.4 – X. W Sep 11 '19 at 10:42