2013-03-16 140 views
2

我是一個名爲AirFloat的Cydia調整的作者。實現AirPlay音頻協議(以前稱爲AirTunes)的應用程序,使您可以將音頻流到您的iOS設備。 AirFloat最初是一款App Store應用程序,直到Apple從App Store啓動。越獄iOS設備應用程序:一致的後臺操作

我從那以後在Cydia免費提供。目前該應用程序在Cydia中的位置與之前的App Store版本完全相同。由於這個原因,我得到了很多要求使其在後臺工作的請求。但我無法讓它工作。

基本上我在考慮兩種方法。

注意:AirFloat會在iOS鎖定屏幕上顯示當前正在播放的曲目。

  1. 創建一個後臺程序,它運行實際的AirPlay的實現,並使用notify一個UI的應用程序進行通信。這工作。有點。它運行並播放音頻,但MPNowPlayingInfoCenter似乎無法從非UI應用程序更新。當守護進程以用戶移動運行時。

  2. 第二種方法是讓它在UI應用程序中工作。但是我有困難沒有被暫停。我已將「必需的背景模式」設置爲音頻連續。服務器可能仍在運行,但Bonjour廣告會被關閉,因爲運行循環在後臺停止。其次,應用程序應該與SpringBoard自動啓動,並在異常退出時重新啓動。

我個人更喜歡第二種方法,因爲我會避免進行進程間通信。對於這種工作方式,我需要完整的後臺執行(包括運行循環),並且在SpringBoard啓動時啓動並在異常退出時重新啓動。

任何人有任何建議如何解決這個問題?

回答

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.現在讓我們來看看h andle在應用程序委託的背景模式(定義之前,你可以在應用的.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將反正殺應用程序的後臺任務。無論如何,如果用戶突然在前臺和後臺之間切換應用程序,它將無限期地工作。

+1

非常感謝!我將用即將發佈的版本對此進行測試。謝謝! – Trenskow 2013-04-20 10:36:49

+0

從iOS7起,背景活動從600秒縮短。 (5分鐘)至180秒。 (3分鐘),所以調用doBackgroundTaskAsync(延遲*)的選擇器必須在大於等於180.0f後被調用 – loretoparisi 2014-09-28 22:48:17

1

部分答案。如果您將「voip」添加爲背景模式,它將由SpringBoard自動啓動。

+0

This Works。它會自動啓動。一切皆好。但必須有某種方式讓它始終在後臺運行。像MobilePhone.app或MobileMail.app一樣。 – Trenskow 2013-03-17 15:02:56

相關問題