2012-06-15 10 views
21

W systemie iOS w jaki sposób mogę nakazać systemowi operacyjnemu zachowanie bieżącej aplikacji, nawet jeśli nie jest ona już na pierwszym planie?iOS: Zachowaj aplikację działającą jak usługa.

I wiele więcej aplikacji to robi.

+2

iOS pozwala tylko na pewien typ aplikacji, aby to zrobić. Jakiego rodzaju aplikacji zamierzasz napisać, aby nadal działał w tle? – nhahtdh

+1

Duplikat: http://stackoverflow.com/questions/6287989/running-apps-in-background – nhahtdh

+1

Jeśli twoje pytanie dotyczy aplikacji VoIP (ponieważ wspomniałeś o Skype), przejrzyj linki tutaj: http: // stackoverflow. com/a/11033929/653513 Jednak obsługa i aplikacja w tle nie są dokładnie tym samym. –

Odpowiedz

34

Zasadniczo nie ma czegoś takiego jak aplikacja lub funkcja typu usługi w systemie iOS. Nawet aplikacje "w tle" (UIBackgroundMode) nie mogą działać całkowicie swobodnie i bez ograniczeń, takich jak usługa lub demon itd. Na innych systemach operacyjnych.

Oto sytuacja dotycząca wykonania tła i powiadomień oraz timerów itp

1) Aplikacja nie może wykonać w tle, chyba że:

a) żąda dodatkowego czasu od systemu operacyjnego, aby to zrobić. Odbywa się to za pomocą beginBackgroundTaskWithExpirationHandler. Nie określono (celowo) przez Apple, jak długo ten dodatkowy czas jest, jednak w praktyce jest to około 10 minut.

b) aplikacja ma tryb tła, tryby to: voip, audio, lokalizacja, podstawa. Nawet jeśli ma jeden z tych typów, aplikacja nie może być uruchamiana bez ograniczeń. Reszta tej dyskusji zakłada, że ​​aplikacja nie ma trybu tła. Jeśli spróbujesz użyć jednego z tych trybów tła, aby aplikacja mogła działać w tle, ale Twoja aplikacja nie korzysta z określonej funkcji, aplikacja zostanie odrzucona po przesłaniu do sklepu z aplikacjami (tj. Do ustawienia trybu UIBackground MUSI to być: aplikacja VoIP, POTRZEBA ciągłej aktualizacji lokalizacji, możliwość nieprzerwanego odtwarzania dźwięku w tle jest podstawową funkcją lub może być aplikacją newstand).

2) Gdy aplikacja jest zawieszona, NIE MOŻNA zrobić WSZYSTKIEGO, aby bezpośrednio się rozbudzić. Nie może wcześniej zaplanować NSTimer, nie może korzystać z czegoś takiego jak performSelector: afterDelay. itp.

TYLKO sposób, w jaki aplikacja może ponownie się uaktywnić, to jeśli użytkownik robi coś, aby uczynić ją aktywną. Użytkownik może zrobić to z pomocą z następujących czynności:

a) Uruchom aplikację bezpośrednio z jego ikonę

b) uruchomić aplikację w odpowiedzi na lokalne zgłoszenia, które zostało wcześniej zaplanowane przez aplikację, gdy był aktywny .

c) Uruchom aplikację w odpowiedzi na zdalne powiadomienie wysłane przez serwer.

d) Kilka innych: takich jak uruchamianie adresu URL, jeśli aplikacja jest zarejestrowana, aby poradzić sobie z uruchamianiem za pośrednictwem adresu URL; lub jeśli jest zarejestrowany jako zdolny do radzenia sobie z określonym rodzajem treści.

Jeśli aplikacja znajduje się na pierwszym planie po uruchomieniu powiadomienia lokalnego/zdalnego, aplikacja otrzymuje ją bezpośrednio.

Jeśli aplikacja nie jest obecnie na pierwszym planie po uruchomieniu powiadomienia lokalnego/zdalnego, aplikacja NIE otrzymuje go. Nie ma kodu, który jest wykonywany po uruchomieniu powiadomienia!

Tylko JEŻELI użytkownik wybierze powiadomienie, aplikacja stanie się aktywna i będzie mogła zostać uruchomiona.

Należy pamiętać, że użytkownik może wyłączyć powiadomienia dla całego urządzenia lub tylko dla określonej aplikacji, w takim przypadku użytkownik nigdy ich nie zobaczy. Jeśli urządzenie zostanie wyłączone, gdy powiadomienie zostanie zwolnione, zostanie ono utracone.

Aktualizacja dla iOS 7

1) istnieją pewne nowe tryby tła, takich jak tło pobieraniu (wciąż nie może być wzburzony przez system operacyjny w deterministyczny sposób jednak)

2) nie ma teraz tło zawiadomienie

3 Push) beginBackgroundTaskWithExpirationHandler czas zmniejszona z 10 minut do około 3.

+0

aplikacje VoIP mogą działać w tle (z pewnymi ograniczeniami) - muszą po prostu zarejestrować się w systemie operacyjnym jako aplikacja VoIP (i faktycznie muszą zapewniać funkcjonalność VoIP lub nie przejdą procesu zatwierdzania) –

+0

Jak Skype i inne aplikacje pracują nieprzerwanie ? –

+0

Teraz, jeśli nie potrzebuję ciągłych aktualizacji lokalizacji, ale raczej okresowo, czy aplikacja zostanie odrzucona z powodu korzystania z usług w tle lub czy istnieje inny sposób na obudzenie aplikacji co 5-10 minut? – selytch

2

teraz wszystko się zmieniło w iOS7, to jest teraz wersja beta.

z Apple's developer portal:

przechowywać zawartość swojej aplikacji up-to-date, przyjmując nowe API wielozadaniowość w iOS 7. Nowe usługi pozwalają aplikacja do aktualizacji informacji i pobrać zawartość w tło bez potrzeby niepotrzebnego wyczerpania baterii. Aktualizacje mogą się odbywać na różne okazje i są inteligentnie planowane zgodnie z użytkowaniem, dzięki czemu aplikacja może aktualizować zawartość w tle, gdy użytkownicy tego potrzebują.

0

Tak możemy to zrobić,

Tworzenie prywatną pole śledzić nasz status:

UIBackgroundTaskIdentifier _bgTask; 

obecnie nazywamy tę metodę, aby uruchomić aplikację jak usługi

if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) 
{ 
   _bgTask = UIBackgroundTaskInvalid; 
   [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(doBackground:) 
name:UIApplicationDidEnterBackgroundNotification object:nil]; 
} 

Teraz utwórz selektor -

- (void) doBackground:(NSNotification *)aNotification 
{ 
   UIApplication *app = [UIApplication sharedApplication]; 

   if ([app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)]) 
   { 
      _bgTask = [app beginBackgroundTaskWithExpirationHandler:^ 
      { 
         dispatch_async(dispatch_get_main_queue(),^
         { 
            if (_bgTask != UIBackgroundTaskInvalid) 
            { 
               [app endBackgroundTask:_bgTask]; 
               _bgTask = UIBackgroundTaskInvalid; 
            } 
         }); 
      }]; 
   } 
} 

Po zakończeniu zadania, należy zadzwonić pod Code

UIApplication *app = [UIApplication sharedApplication]; 
if ([app respondsToSelector:@selector(endBackgroundTask:)]) 
{ 
   if (_bgTask != UIBackgroundTaskInvalid) 
   { 
      [app endBackgroundTask:_bgTask]; 
      _bgTask = UIBackgroundTaskInvalid; 
   } 
} 
Powiązane problemy