Отправка 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:
,
Я также обнаружил, что, даже если вы используете исключительно локальные уведомления, вы должны:
- Включите Удаленные уведомления для вашей цели на вкладке Возможности в Фоновых режимах
- Включите оповещения или баннеры в приложении Настройки, в настройках Центра уведомлений.
Пример обработчика событий для фоновой выборки:
- (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 секунд после нажатия кнопки "Домой".