Подтвердить что ты не робот

IOS: поддерживайте приложение как службу

В iOS, как я должен дать указание ОС поддерживать приложение в рабочем состоянии, даже если оно больше не находится на переднем плане?

И многие другие приложения делают это.

4b9b3361

Ответ 1

По сути, в iOS нет такого понятия, как приложение типа сервиса или функциональность. Даже "фоновые" приложения (UIBackgroundMode) не могут работать совершенно бесплатно и без ограничений, таких как служба, демон и т.д. В других ОС.

Здесь ситуация с фоновым исполнением и уведомлениями и таймерами и т.д.

1) Приложение не может выполняться в фоновом режиме, если:

а) он запрашивает дополнительное время у ОС для этого. Это делается с помощью beginBackgroundTaskWithExpirationHandler. Apple не указывает (намеренно), как долго это дополнительное время, однако на практике оно составляет около 10 минут.

б) приложение имеет фоновый режим, режимы VoIP, аудио, местоположение, газетный киоск. Даже если у него есть один из этих типов, приложение не может выполняться без ограничений. В остальной части этого обсуждения предполагается, что приложение не имеет фонового режима. Если вы попытаетесь использовать один из этих фоновых режимов, чтобы ваше приложение могло работать в фоновом режиме, но ваше приложение не использует законным образом определенные функции, тогда ваше приложение будет отклонено после отправки в магазин приложений (т.е. Иметь UIBackgroundMode Это ДОЛЖНО быть: приложение VoIP, НЕОБХОДИМОЕ иметь постоянные обновления местоположения, возможность непрерывного воспроизведения звука в фоновом режиме - это фундаментальная функция, или приложение для газетных киосков).

2) Когда приложение приостановлено, оно не может сделать НИЧЕГО, чтобы пробудить себя напрямую. Ранее он не мог запланировать NSTimer, он не может использовать что-то вроде executeSelector: afterDelay. и т.п.

Единственный способ, которым приложение может снова стать активным, - это если ПОЛЬЗОВАТЕЛЬ делает что-то, чтобы сделать его активным. Пользователь может сделать это с помощью следующего:

а) Запустите приложение прямо с его иконки

б) Запустите приложение в ответ на локальное уведомление, которое ранее было запланировано приложением, когда оно было активным.

c) Запустите приложение в ответ на удаленное уведомление, отправленное сервером.

d) несколько других: например, запуск URL, если приложение зарегистрировано для запуска через URL; или если он зарегистрирован, чтобы иметь возможность иметь дело с определенным типом контента.

Если приложение находится на переднем плане, когда запускается локальное/удаленное уведомление, приложение получает его напрямую.

Если приложение в данный момент не находится на переднем плане, когда запускается локальное/удаленное уведомление, тогда приложение НЕ получает его. Нет кода, который выполняется при срабатывании уведомления!

Только если пользователь выберет уведомление, приложение станет активным и сможет его выполнить.

Обратите внимание, что пользователь может отключить уведомления либо для всего устройства, либо только для конкретного приложения, и в этом случае пользователь никогда их не увидит. Если устройство отключено во время срабатывания уведомления, оно теряется.

ОБНОВЛЕНИЕ ДЛЯ IOS 7

1) появились некоторые новые фоновые режимы, такие как фоновая выборка (однако вы все еще не можете быть вызваны ОС детерминированным способом)

2) там теперь фоновое push-уведомление

3) время beginBackgroundTaskWithExpirationHandler уменьшено с 10 минут до 3.

Ответ 2

В iOS7 все изменилось, теперь это бета.

С портала Apple для разработчиков:

Обновляйте содержимое вашего приложения, применяя новые API многозадачности в iOS 7. Новые сервисы позволяют вашему приложению обновлять информацию и загружать контент в фоновом режиме, не разряжая батарею без необходимости. Обновления могут происходить в подходящее время и разумно планируются в соответствии с использованием, поэтому ваше приложение может обновлять контент в фоновом режиме именно тогда, когда это нужно пользователям.

Ответ 3

Да, мы можем это сделать,

Создайте личное поле для отслеживания нашего статуса:

UIBackgroundTaskIdentifier _bgTask;

Теперь вызовите этот метод, чтобы запустить ваше приложение, как сервис

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

Теперь создайте селектор -

- (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;
            }
         });
      }];
   }
}

Когда вы закончите свою задачу, вызовите код ниже -

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

Ответ 4

Свифт версия ответа @Zoeb S. Может быть, не правильный ответ на ОП. Но это поможет вам запустить background task всякий раз, когда приложение переходит в фоновый режим. И убивает себя iOS через некоторое время (Надеюсь, после завершения обработки).

Объявить переменную

fileprivate let backgroundTaskStarter = {
  // TODO: If this doesn't work, switch to willResignActiveNotification.
  UIApplication.didEnterBackgroundNotification.observe() { _ in
    UIApplication.shared.beginBackgroundTask {
      NSLog("endBackgroundTask called by iOS")
    }
  }
}()

И в методе Filename.swift init() выполните:

_ = backgroundTaskStarter