IOS jailbreak app: continuous background operation

I am the author of a Cydia setup called AirFloat. An application that implements the AirPlay audio protocol (formerly known as AirTunes), allowing you to transfer audio to your iOS device. AirFloat was originally an App Store application until it booted Apple from the App Store.

Since then I have done this for free at Cydia. Currently, the application is in Cydia exactly the same as the previous version of the App Store. As a result, I get a lot of requests to make it work in the background. But I can’t make it work.

I mainly think of two approaches.

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

  • Create a daemon that launches the actual implementation of AirPlay and communicates with the UI application using notify . It works. View. It starts and plays audio, but MPNowPlayingInfoCenter, it seems, cannot be updated using an application other than the UI. Also, when the daemon works as a custom mobile.

  • The second approach is for all of this to work in a user interface application. But I am having difficulty if it is not suspended. I set "Required Backgrounds" to audio and continuous. The server can still work, but then Bonjour ads are reduced because the startup cycle stops when in the background. Secondly, the application should start automatically using SpringBoard and restart with an abnormal exit.

, . ( ), SpringBoard .

- , ?

+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. , aync

            -(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 . , , .

+2

. "voip" , SpringBoard.

+1

Source: https://habr.com/ru/post/1534741/


All Articles