越狱iOS设备的应用程序:一致的后台操作 [英] App for jailbroken iOS device: Consistent background operation

查看:129
本文介绍了越狱iOS设备的应用程序:一致的后台操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Cydia调整项AirFloat的作者。一款实现了AirPlay音频协议的应用程序(以前称为AirTunes),可以将音频流传输到您的iOS设备。 AirFloat最初是一个App Store应用程序,直到Apple从App Store启动它为止。

I am the author of a Cydia tweak called AirFloat. An app that implements the AirPlay audio protocol (previously known as AirTunes), making it possible to stream audio to your iOS device. AirFloat is originally an App Store app, until it got booted by Apple from the App Store.

从那以后,我就在Cydia免费提供了它。目前,该应用程序在Cydia中的位置与以前的App Store版本完全相同。结果,我收到了很多要求使其在后台运行的请求。但是我无法使它正常工作。

I've since that made it available for free in Cydia. Currently the app stands in Cydia exactly as the previous App Store version. As a result of this I get a lot of requests to make it work in the background. But I cannot get it to work.

基本上我正在考虑两种方法。

Basically I am thinking of two approaches.

注意:AirFloat显示在iOS锁定屏幕上当前播放的曲目。

Note: AirFloat displays the currently playing track on the iOS lock screen.


  1. 创建一个守护程序,该守护程序运行实际的AirPlay实现,并与使用通知。这可行。有点儿。它运行并播放音频,但是MPNowPlayingInfoCenter似乎无法从非UI应用程序更新。同样,当守护程序以用户 mobile 的身份运行时。

  1. Create a daemon, which runs the actual AirPlay implementation, and communicates with a UI app using notify. This works. Kind of. It runs and plays the audio, but the MPNowPlayingInfoCenter does not seem to be updatable from a non-UI application. Also when the daemon is running as user mobile.

第二种方法是使其全部在UI应用程序中工作。但是我很难不暂停它。我已将必需的背景模式设置为音频连续。服务器可能仍在运行,但是Bonjour广告被关闭了,因为在后台运行循环被暂停了。其次,应使用SpringBoard自动启动该应用程序,并在异常退出时重新启动。

Second approach is to just have it all work in a UI application. But I am having difficulties not having it be suspended. I've set the "Required Background Modes" to audio and continuous. The server might still be running, but then the Bonjour advertising is brought down, because the run loop is brought to a halt when in background. Secondly the app should be launched automatically with SpringBoard and relaunched on abnormal exit.

我个人更喜欢第二种方法,因为我将避免进行进程间通信。为了使这种方法起作用,我需要完整的后台执行(包括运行循环),并使其同时在SpringBoard启动时启动,并在异常退出时重新启动。

Personally I prefer the second approach, because I would avoid doing interprocess communication. And for this approach to work I would need full background execution (including run loops) and have it both launched on SpringBoard launch and relaunched on abnormal exit.

任何人都有任何建议

推荐答案

首先感谢您与AirFlow RAOP的出色合作!

First thank you for your amazing works with AirFlow RAOP is pretty hard thing!

所以您可以做的是

1。创建一个后台任务处理程序,如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];
         }

4。让我们看看后台异步任务选择器的作用

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

我知道这个解决方案很好用,但是我知道有时候iOS会终止应用程序后台任务。无论如何,如果用户突然在前台和后台之间切换应用程序,它将无限期运行。

I know that this solution works nice but I know that sometimes it happens that iOS will kill the app background task anyway. Anyway if the users suddenly switches the app between foreground and background it will works indefinitely.

这篇关于越狱iOS设备的应用程序:一致的后台操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆