越狱iOS设备的应用程序:一致的后台操作
我是一个叫做AirFloat的Cydia调整的作者。 实现AirPlayaudio协议(以前称为AirTunes)的应用程序,可以将audiostream式传输到您的iOS设备。 AirFloat最初是一个App Store应用程序,直到它从苹果App Store启动。
我从那以后就在Cydia免费提供了。 目前该应用程序在Cydia中的位置与之前的App Store版本完全相同。 作为这个的结果,我得到了很多请求,使其在后台工作。 但是我无法让它工作。
基本上我正在考虑两种方法。
注意:AirFloat在iOSlocking屏幕上显示当前正在播放的曲目。
-
创build一个运行实际AirPlay实现的守护进程,并使用notify与UI应用进行通信。 这工作。 有点。 它运行并播放audio,但MPNowPlayingInfoCenter似乎不能从非UI应用程序更新。 另外当守护程序以用户移动的方式运行时。
-
第二种方法是在UI应用程序中使用它们。 但是我有困难没有被暂停。 我已将“所需的背景模式”设置为audio和连续模式。 服务器可能仍然在运行,但Bonjour广告被closures,因为运行循环在后台停止。 其次,应用程序应该与SpringBoard自动启动,并重新启动exception退出。
我个人更喜欢第二种方法,因为我会避免进行进程间通信。 而这种方法的工作,我需要完整的后台执行(包括运行循环),并启动SpringBoard启动和重新启动exception退出。
任何人有任何build议如何解决这个问题?
首先感谢你与AirFlow RAOP的惊人的作品是相当困难的事情!
所以你可以做的是
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 (...) { } }
我知道这个解决scheme很好,但是我知道有时候iOS会杀死app后台任务。 无论如何,如果用户突然在前台和后台之间切换应用程序,它将无限期地工作。
部分答案。 如果您将“voip”添加为背景模式,SpringBoard会自动启动。