2

私は AirFloat と呼ばれる Cydia の微調整の作成者です。AirPlay オーディオ プロトコル (以前は AirTunes と呼ばれていました) を実装し、オーディオiOS デバイスにストリーミングできるようにするアプリ。AirFloat は、Apple が App Store から起動するまでは、もともと App Store アプリでした。

それ以来、Cydiaで無料で利用できるようにしました。現在、アプリは以前の App Store バージョンとまったく同じように Cydia に存在します。この結果、バックグラウンドで動作させるようにという多くのリクエストを受け取ります。しかし、私はそれを機能させることができません。

基本的には2つのアプローチを考えています。

注: AirFloat は、現在再生中のトラックを iOS ロック画面に表示します。

  1. 実際の AirPlay 実装を実行し、 notifyを使用して UI アプリと通信するデーモンを作成します。これは機能します。すこし。実行してオーディオを再生しますが、MPNowPlayingInfoCenter は非 UI アプリケーションから更新できないようです。また、デーモンがユーザーmobileとして実行されている場合。

  2. 2 番目のアプローチは、すべてを UI アプリケーションで機能させることです。しかし、私はそれが中断されないのに苦労しています。「必要なバックグラウンド モード」をaudioおよびContinuousに設定しました。サーバーはまだ実行されている可能性がありますが、バックグラウンドで実行ループが停止するため、Bonjour アドバタイジングは停止します。次に、SpringBoard を使用してアプリを自動的に起動し、異常終了時に再起動する必要があります。

個人的には、プロセス間通信を避けるため、2 番目のアプローチを好みます。そして、このアプローチを機能させるには、完全なバックグラウンド実行 (実行ループを含む) が必要であり、SpringBoard の起動時に起動し、異常終了時に再起動する必要があります。

これを解決する方法について何か提案はありますか?

4

2 に答える 2

2

まず、AirFlow で素晴らしい作品をありがとうございました。RAOP はかなり難しいものです。

だからあなたができることは

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 がアプリのバックグラウンド タスクを強制終了することが時々あることを知っています。とにかく、ユーザーがアプリをフォアグラウンドとバックグラウンドの間で突然切り替えた場合、アプリは無期限に動作します。

于 2013-04-17T19:10:33.583 に答える
1

部分的な答え。バックグラウンドモードとして「voip」を追加すると、SpringBoardによって自動的に開始されます。

于 2013-03-16T18:53:12.943 に答える