11

I have a problem that when I my application goes in background the GCKSocket of chromecast iOS api closes and I get this typr of error from api

-[GCKCastSocket socketDidDisconnect:withError:]  socketDidDisconnect:withError: "(null)"

and then if I bring the application to foreground the api creates the socket automatically and set the playback state to paused. If I now try to play the video again it plays normally.

I am starting the playback of the media on the background thread like this.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,
                                             0), ^ {
[[CastViewController instance] castMedia:self.media];      

});

How to keep playback alive even when the application goes to background?

here is the logging from api

2014-02-25 17:19:01.388 CastVideos[28470:60b] -[GCKCastSocket disconnect] disconnect

2014-02-25 17:19:01.391 CastVideos[28470:60b] -[GCKCastSocket doTeardownWithError:] doTeardownWithError

2014-02-25 17:19:01.395 CastVideos[28470:60b] -[GCKCastSocket doTeardownWithError:] notifying delegate that socket is disconnected

2014-02-25 17:19:01.399 CastVideos[28470:60b] -[GCKHeartbeatChannel didDisconnect] disconnected - stopping heartbeat timer if necessary

2014-02-25 17:19:01.457 CastVideos[28470:60b] -[GCKCastSocket socketDidDisconnect:withError:] socketDidDisconnect:withError: "(null)"
4
  • 1
    App in background mode and background thread are not related.
    – user523234
    Commented Feb 25, 2014 at 11:56
  • so which background mode should be used to support chromecast playback like for airplay we use avaudiosession with audio background mode
    – hariszaman
    Commented Feb 25, 2014 at 12:10
  • If you don't need to submit to AppStore, any background mode will do assuming chromecast will work in background mode. That I am not familiar with.
    – user523234
    Commented Feb 25, 2014 at 12:24
  • I have already define audio background mode for airplay so why it is not working then?
    – hariszaman
    Commented Feb 25, 2014 at 12:32

2 Answers 2

11
+50

Currently, the Cast iOS SDK closes the socket when you go to background, and that is not a configurable item at this point. However, that doesn't mean that your media playback on the Cast device should stop; in fact the correct behavior is the following:

  • if user has explicitly disconnected herself from the cast device, and if she is the last connected device to the receiver, then the receiver should stop the playback, otherwise receiver should continue playback.

The key here is the "explicit" part; if, for example, the sender goes out of wifi range and gets disconnected, or if the sender goes to sleep and gets disconnected, these are considered "implicit" disconnects and should not cause the receiver to stop.

In other words, it is really the receiver who should have the logic to decide if it has to stop itself or keep playing, and for that to work, it has to be able to decided if a device disconnect was caused implicitly or explicitly. In the current receiver SDK APIs, unfortunately that is not included in the onSenderDisconnected event that the receiver gets; in the next update or so of the receiver, it will change so receiver can see why a disconnect is happening, at least as much as it needs to distinguish an explicit from an implicit one. Then it can implement the logic. Meanwhile, sender needs to have an out-of-band channel to send a message indicating its explicit intention.

Update: Receiver SDK has been updated to have the information that can tell whether the sender was implicitly or explicitly disconnected, see the docs.

5
  • thanks for your answer, should I try sending message to receiver side once the app goes to sleep or background? Perhaps telling the receiver that it is an implicit/explicit disconnect
    – hariszaman
    Commented Mar 1, 2014 at 0:29
  • no, if you go to background or out of range, receiver will realize you are gone and considers you disconnected and since you didn't send the explicit message, it should be interpreted as an implicit one. Send a message (before the fix goes into effect) only if user is explicitly disconnecting
    – Ali Naddaf
    Commented Mar 1, 2014 at 0:34
  • but currently the demo receiver application stops automatically once the sender goes to background, how to overcome that?
    – hariszaman
    Commented Mar 1, 2014 at 0:50
  • 1
    That is a sample app; make sure that your seder app is not sending a stopApplication on disconnect and then write your own custom receiver to do the logic that I outlined.
    – Ali Naddaf
    Commented Mar 1, 2014 at 1:43
  • ok, I have managed to do it by implementing a separate method on the receiver side for the mediaelement stop, once the [self.mediacontrolchannel stop] method is called from the sender side. And commenting out the code from onDiscconect on receiver side which stop the mediaelement.
    – hariszaman
    Commented Mar 3, 2014 at 11:07
-1

There is a hack that helps to keep the connection alive when it goes in background.

You can replace the call for a GCKSessionManager.suspendSession(with:) for a custom that doesn't disconnect.

extension GCKSessionManager {
    static func ignoreAppBackgroundModeChange() {
        let oldMethod = class_getInstanceMethod(GCKSessionManager.self, #selector(GCKSessionManager.suspendSession(with:)))
        let newMethod = class_getInstanceMethod(GCKSessionManager.self, #selector(GCKSessionManager.suspendSessionIgnoringAppBackgrounded(with:)))
        method_exchangeImplementations(oldMethod, newMethod)

    }

    func suspendSessionIgnoringAppBackgrounded(with reason: GCKConnectionSuspendReason) -> Bool {
        guard reason != .appBackgrounded else { return false }
        return suspendSession(with:reason)
    }
}

Just call the method ignoreAppBackgroundModeChange() once from anywhere before to enter in background.

The problem I've found with this is when you return to the app you are going to have a network error after a few seconds, because Google Cast is trying to reconnect to the device.

I fixed that reconnecting when the error happens, with a flag to identify it entered in background before.

reference: How to keep GCKCastSession alive when app goes to background

Not the answer you're looking for? Browse other questions tagged or ask your own question.