Отправка UILocationNotification из фона

У меня есть приложение, где мне нужно отправить UILocationNotification когда приложение не на переднем плане / Active. Если у меня есть код для этого, он не будет отправлять, пока приложение не будет открыто и активно.

Вот моя функция:

- (void)setLocalNotificationForType:(SPKLocalNotificationType)notificationType fromUser:(NSString *)userName withMessageText:(NSString *)msgText {

    UILocalNotification *notif = [[UILocalNotification alloc] init];
    notif.userInfo = @{@"handle": _convoHandle, @"room": _convoName};
    notif.fireDate = [NSDate date];
    notif.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
    notif.soundName = UILocalNotificationDefaultSoundName;
    notif.timeZone = [NSTimeZone defaultTimeZone];

    if (notificationType == 1) { // message
        notif.alertBody = [NSString stringWithFormat:@"@%@ said: \"%@\"", userName, msgText];
    } else if (notificationType == 2) { // image
        notif.alertBody = [NSString stringWithFormat:@"@%@ sent an image", userName];
    } else {
        return;
    }

    if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) {
        [[UIApplication sharedApplication] presentLocalNotificationNow:notif];
    }
}

Обновление: теперь кажется, что проблема в том, что подключение к серверу "приостановлено", пока приложение находится в фоновом режиме. После того как я открою приложение, все данные поступают сразу. Я использую SocketRocket для подключения к моей Node.js Сервер веб-сокетов Primus. Это то, что обычно происходит? Это мой первый раз, используя SocketRocket так что я не уверен.

Обновление: я также включил Remote Notifications для фоновых режимов я также зарегистрировался для удаленных уведомлений, и на устройстве я также удостоверился, что включены "баннеры" и "значки".

Обновление: я дополнительно настроил веб-сокет для использования фоновой очереди.

[webSocket setDelegateOperationQueue:[NSOperationQueue new]];

Соединение все еще приостановлено.

Спасибо!

2 ответа

Редактировать: похоже, что SocketRocket по умолчанию использует основную очередь отправки, которая выполняется в главном потоке приложения. Когда приложение работает в фоновом режиме, обработка в основном потоке останавливается, поэтому стоило бы попытаться переместить работу в фоновый поток в очередь фоновых операций.

На ваше SRWebSocket объект, попробуйте позвонить:

[webSocket setDelegateOperationQueue:[NSOperationQueue new]];


Без проверки документов, возможно, установка timeZone а также fireDate на UILocalNotification мешает. Они вам не нужны, если вы собираетесь передать уведомление presentLocalNotificationNow:,

Я также обнаружил, что, даже если вы используете исключительно локальные уведомления, вы должны:

  1. Включите Удаленные уведомления для вашей цели на вкладке Возможности в Фоновых режимах
  2. Включите оповещения или баннеры в приложении Настройки, в настройках Центра уведомлений.

Пример обработчика событий для фоновой выборки:

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    UIBackgroundFetchResult result = UIBackgroundFetchResultNoData;
    // ... perform a network request
    if (successfulNetworkRequest) {
        UILocalNotification* localNotification = [UILocalNotification new];

        localNotification.alertAction = @"View";
        localNotification.alertBody = @"Stuff";

        localNotification.soundName = UILocalNotificationDefaultSoundName;
        localNotification.applicationIconBadgeNumber = 1;

        localNotification.userInfo = @{@"stuff": @"other stuff"};

        [application presentLocalNotificationNow:localNotification];

        result = UIBackgroundFetchResultNewData;
    } else {
        result = UIBackgroundFetchResultFailed;
    }

    completionHandler(result);
}

Боюсь, вы неправильно понимаете местное уведомление. Я думаю, что вы должны сделать, это зарегистрировать уведомление в будущем и отправить его через некоторое время после того, как пользователь нажал кнопку "Домой". Но в своем коде вы зарегистрировали предупреждение в ТЕКУЩЕЕ ВРЕМЯ и сделали что-то с уведомлением (извините, но я не знаю, что вы хотите сделать в своем коде).

Вы можете изменить это следующим образом:

- (void)setLocalNotificationForType:(SPKLocalNotificationType)notificationType fromUser:(NSString *)userName withMessageText:(NSString *)msgText {

    UILocalNotification *notif = [[UILocalNotification alloc] init];
    notif.userInfo = @{@"handle": _convoHandle, @"room": _convoName};

    //Set the fire time 10 seconds later
    notif.fireDate = [[NSDate date] dateByAddingTimeInterval:10];

    notif.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
    notif.soundName = UILocalNotificationDefaultSoundName;
    notif.timeZone = [NSTimeZone defaultTimeZone];

    if (notificationType == 1) { // message
        notif.alertBody = [NSString stringWithFormat:@"@%@ said: \"%@\"", userName, msgText];
    } else if (notificationType == 2) { // image
        notif.alertBody = [NSString stringWithFormat:@"@%@ sent an image", userName];
    } else {
        return;
    }

    //Register this notification
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

И в вашем приложении делегат -applicationDidEnterBackground:позвони -setLocalNotificationForType:fromUser:withMessageText: способ сделать и зарегистрировать уведомление. Затем вы можете ожидать локальное уведомление через 10 секунд после нажатия кнопки "Домой".

Другие вопросы по тегам