Google Chromecast SDK TearDown in background

纵饮孤独 提交于 2019-12-01 12:56:18

问题


Using the iOS Sender API Framework, when my application goes in the background, the SDK tears down all connections and I cannot launch any more media until the app is put back in the foreground. My app plays audio and is allowed to run and stream in the background. Is there an option to tell Googlecast framework to keep the sockets opened?

Here's the log on backgrounding:

INFO: Will resign active

INFO: Now in background

FINE: -[GCKCastSocket disconnect] disconnect

FINE: -[GCKCastSocket doTeardownWithError:] doTeardownWithError

FINE: -[GCKCastSocket doTeardownWithError:] notifying delegate that socket is disconnected

FINE: -[GCKHeartbeatChannel didDisconnect] disconnected - stopping heartbeat timer if necessary

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

Then when the app resumes: INFO: Going into foreground

FINE: -[GCKCastSocket doTeardownWithError:] doTeardownWithError

FINE: -[GCKCastSocket doTeardownWithError:] notifying delegate that socket is disconnected

FINE: -[GCKCastSocket connectToHost:port:withTimeout:] Connecting to "192.168.1.4" on port 8009l...

INFO: Did become active

FINE: -[GCKCastSocket socket:didConnectToHost:port:] socketDidConnect:

FINE: -[GCKCastSocket socketDidSecure:] socketDidSecure:

FINE: -[GCKCastSocket socket:didReadData:withTag:] prefix read, expected message length=1307

FINE: -[GCKDeviceAuthChannel didReceiveBinaryMessage:] Genuine Google device didDeviceAuthenticated=YES

FINE: -[GCKDeviceManager deviceAuthChannelDidAuthenticate:] Authentic device, connecting receiver channel

FINE: -[GCKCastSocket socket:didReadData:withTag:] prefix read, expected message length=474

FINE: -[GCKDeviceManager receiverControlChannel:didReceiveStatusForApplication:] Application to join (CC1AD845) is available

FINE: -[GCKDeviceManager connectAndNotifyDidConnectToApplication:launchedApplication:] Connected to application <0x1467c8f0:GCKApplicationMetadata> Default Media Receiver (CC1AD845), transport ID web-11

FINE: -[GCKCastSocket socket:didReadData:withTag:] prefix read, expected message length=135

FINE: -[GCKMediaControlChannel didReceiveTextMessage:] message received: {"type":"MEDIA_STATUS","status":[],"requestId":6}


回答1:


With the version 2.0 of the iOS Sender API, the GCKCastSocket is closed upon receiving a UIApplicationDidEnterBackgroundNotification and this is not something that can be configured.

That means:

  • no new media can be pushed from the app to the chromecast while the app is in the background
  • it is not possible to implement lock screen controls

Alternatives (custom receiver only):

  • Send a list of media to be played to the receiver
  • Fetch new media from the cloud directly from the receiver

See also this question or this one for more details.




回答2:


This is a solution I used for other needs, but I guess it could be applied here as well (not tested yet)

1. Create a background task handlers as dispatch_block_t, let's say

 dispatch_block_t myDummyBackgroundTaskBlock = {
    [[UIApplication sharedApplication] endBackgroundTask:myDummyBackgroundTask];
    myDummyBackgroundTask = UIBackgroundTaskInvalid;
    myDummyBackgroundTask = [app beginBackgroundTaskWithExpirationHandler:myDummyBackgroundTask];
};

2. Define somewhere this background and foreground tasks handler

    // foreground
    -(void)handleTasksForApplicationInForeground {
    if(myDummyBackgroundTask) { // reset that task
       [[UIApplication sharedApplication] endBackgroundTask: myDummyBackgroundTask];
       myDummyBackgroundTask = UIBackgroundTaskInvalid;
     }
    }

     // background
     -(void) handleTasksForApplicationInBackground {
         UIDevice *device = [UIDevice currentDevice];
         BOOL backgroundSupported = NO;
        if ([device respondsToSelector:@selector(isMultitaskingSupported)])
         backgroundSupported = device.multitaskingSupported;
        if(backgroundSupported && backgroundEnabled) { // perform a background task

            myDummyBackgroundTaskBlock = ^{
                [[UIApplication sharedApplication] endBackgroundTask: myDummyBackgroundTaskBlock];
                myDummyBackgroundTaskBlock = UIBackgroundTaskInvalid;
           };

           SEL sel = @selector(doDummyBackgroundTask);
           [self doBackgroundTaskAsync:sel];

           [self performSelector:@selector(doBackgroundTaskAsync:) withObject:nil afterDelay:500.0f]; /// LP: this is the funny part since iOS will kill the task after 500 sec.
             }
           }

3. Now let's handle in the application delegate the background mode (As defined before you can activate background mode with different options in your app .plist):

    -(void)applicationDidEnterBackground:(UIApplication *)application {
       [self handleTasksForApplicationInBackground];
     }

    -(void)applicationWillEnterForeground:(UIApplication *)application {
       [self handleTasksForApplicationInForeground];
     }

4. Let's see what the background async task selector does

        -(void) doBackgroundTaskAsync:(SEL)selector {

        @try {
             if( [[UIApplication sharedApplication] backgroundTimeRemaining] < 5 ) { 
               return;
             }

           if(!myDummyBackgroundTaskBlock) { // need to create again on-the-fly
                myDummyBackgroundTaskBlock = ^{
                      [[UIApplication sharedApplication] endBackgroundTask:myDummyBackgroundTask];
                     myDummyBackgroundTask = UIBackgroundTaskInvalid;
                };
             }

            myDummyBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:myDummyBackgroundTaskBlock];
          dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

           while ([[UIApplication sharedApplication] backgroundTimeRemaining] > 5.0) {
              int delta = 5.0;
              [self performSelector: selector ];
              sleep(delta);
          }
        });
      }
       @catch (...) {
     }
    }


来源:https://stackoverflow.com/questions/22541221/google-chromecast-sdk-teardown-in-background

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!