Google Chromecast SDK TearDown在后台

使用iOS发件人API框架,当我的应用程序在后台运行时,SDK会将所有连接closures,并且在应用程序放回到前台之前,我无法启动任何其他媒体。 我的应用程序播放audio,并允许在后台运行和stream。 有没有一个选项可以告诉Googlecast框架保持套接字打开?

这里是背景的日志:

信息:将辞职活跃

信息:现在在后台

精细: – [GCKCastSocket断开]断开连接

FINE: – [GCKCastSocket doTeardownWithError:] doTeardownWithError

FINE: – [GCKCastSocket doTeardownWithError:]通知委托套接字断开

FINE: – [GCKHeartbeatChannel didDisconnect]断开连接 – 如有必要停止心跳计时器

FINE: – [GCKCastSocket socketDidDisconnect:withError:] socketDidDisconnect:withError:“(null)”

然后,当应用程序恢复:信息:进入前景

FINE: – [GCKCastSocket doTeardownWithError:] doTeardownWithError

FINE: – [GCKCastSocket doTeardownWithError:]通知委托套接字断开

FINE: – [GCKCastSocket connectToHost:port:withTimeout:]在端口8009l上连接到“192.168.1.4”…

信息:变得活跃了

FINE: – [GCKCastSocket套接字:didConnectToHost:端口:] socketDidConnect:

FINE: – [GCKCastSocket socketDidSecure:] socketDidSecure:

FINE: – [GCKCastSocket套接字:didReadData:withTag:]前缀读取,预期消息长度= 1307

FINE: – [GCKDeviceAuthChannel didReceiveBinaryMessage:]正版Google设备didDeviceAuthenticated = YES

FINE: – [GCKDeviceManager deviceAuthChannelDidAuthenticate:]正确的设备,连接接收通道

FINE: – [GCKCastSocket套接字:didReadData:withTag:]前缀读取,预期消息长度= 474

FINE: – [GCKDeviceManager receiverControlChannel:didReceiveStatusForApplication:]应用程序join(CC1AD845)可用

FINE: – [GCKDeviceManager connectAndNotifyDidConnectToApplication:launchApplication:]连接到应用程序<0x1467c8f0:GCKApplicationMetadata>默认媒体接收器(CC1AD845),传输ID web-11

FINE: – [GCKCastSocket套接字:didReadData:withTag:]前缀读取,预期消息长度= 135

FINE: – [GCKMediaControlChannel didReceiveTextMessage:]收到的消息:{“type”:“MEDIA_STATUS”,“status”:[],“requestId”:6}

使用iOS Sender API的2.0版, GCKCastSocket在收到UIApplicationDidEnterBackgroundNotificationclosures,这不是可以configuration的东西。

这意味着:

  • 当应用程序在后台时,没有新媒体可以从应用程序推送到Chromecast
  • 不可能实现锁屏控制

替代品(仅限定制接收器):

  • 发送要播放的媒体列表到接收器
  • 直接从接收器中从云端获取新媒体

参见这个问题或这个更多细节。

这是我用于其他需求的解决scheme,但我想它也可以在这里应用(还没有testing过)

1.创build一个后台任务处理程序dispatch_block_t,比方说

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

2.定义这个背景和前台任务处理程序

  // 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.现在让我们来处理应用程序委托的背景模式(按照您的应用程序.plist中的不同选项激活背景模式之前定义的):

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

让我们来看看背景asynchronous任务select器的作用

  -(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 (...) { } }