Удаление уведомлений на основе местоположения, когда пользователь выходит из региона
Я установил (по умолчанию iOS8) уведомления о местоположении для своего приложения.
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.regionTriggersOnce = NO;
notification.userInfo = @{ @"notification_id" : @"someID" };
notification.region = region;
notification.alertBody = alertBody;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
Когда пользователь входит в указанную область, уведомление отображается в NotificationCenter
правильно.
Тем не менее, я хочу удалить это уведомление, когда пользователь выходит из этого региона, потому что для пользователя нет смысла возвращаться домой и просматривать центр уведомлений, пока они не получат сообщение, которое выглядит так:
"Вы находитесь в XXXXX!"
Кто-нибудь пробовал что-то подобное? Документация неясно, как это можно сделать.
Ответы
Ответ 1
CLRegion
объект имеет специальные свойства для этого: notifyOnEntry
и notifyOnExit
.
Все, что вам нужно, - это обновить код следующим образом:
CLRegion *region = .... // Configure region here
region.notifyOnEntry = YES;
region.notifyOnExit = NO;
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.regionTriggersOnce = NO;
notification.userInfo = @{ @"notification_id" : @"someID" };
notification.region = region;
notification.alertBody = alertBody;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
Вот Apple documentation, который объясняет это:
@property(nonatomic, copy) CLRegion *region
Присвоение значения этому свойство заставляет локальное уведомление доставляться, когда пользователь пересекает границу регионов. Сам объект области определяет инициируется ли уведомление при входе пользователя или выходе из него регион.
Ответ 2
Я действительно устал вчера и не смог завершить свой ответ вовремя.
Основываясь на некоторых ответах, у меня есть только ключ к тому, что вы должны делать. Я не пробовал это сам (геообработка - это действительно боль, чтобы проверить, я знаю это, потому что я работаю над проектом geofencing atm.), Мне также никогда не приходилось удалять отправленное уведомление из Центра уведомлений раньше.
Я предполагаю, что ваше приложение не завершится из-за всего процесса. Поэтому мы не будем использовать здесь функцию startMonitoringForRegion
.
Ответ написан в Swift 2.0 (это не так сложно перевести на ObjC).
func createAndRegisterSomeNotificationSomewhere() {
let region = CLCircularRegion(center: someCoordinates, radius: someRadius, identifier: someIdentifier)
region.notifyOnEntry = true
region.notifyOnExit = true
let locationNotification = UILocalNotification()
locationNotification.alertBody = "someAlertBody"
locationNotification.userInfo = ["notification_id" : "someID"]
locationNotification.regionTriggersOnce = false
locationNotification.region = region // remember 'presentLocalNotificationNow' will not work if this value is set
UIApplication.sharedApplication().scheduleLocalNotification(locationNotification)
}
/* CLLocationManagerDelegate provides two function */
// func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion)
// func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion)
/* If I'm not mistaken they are only called for monitored regions and not location based local notifications */
/* I mean you will have to use something like: self.locationManager.startMonitoringForRegion(someCircularRegion) */
/* Correct me if I'm wrong. So consider to rebuild the following logic to ease everything if you want to monitor regions. */
/* Now when you receive your location notification */
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
if let region = notification.region {
self.locationManager.requestStateForRegion(region)
/* based on other answers this will remove your noticaiton from NC and cancel from showing it anywhere */
application.cancelLocalNotification(notification)
/* but we need this notification still be scheduled because 'region.notifyOnExit = true' should fire it again later */
application.scheduleLocalNotification(notification)
}
}
func locationManager(manager: CLLocationManager, didDetermineState state: CLRegionState, forRegion region: CLRegion) {
/* this is not the best solution, because it adds some latency to the dilivery code and CLRegionState can also be Unknown sometimes */
/* I'd go with the two functions above if I only had up to 20 regions to monitor (max region limit per App, read CLLocationManager docs) */
/* the mechanics would be more clear and save */
switch state {
case .Inside:
/* create a new noticiation with the same cpecs as the cancled notification but this time withot the region */
let sameNotificationAsAbove = UILocalNotification()
/* if you really need to know your IDs inside userInfo so create some good mechanics to pass these before canceling */
/* at least I would save the identifier of the region iside the noticiation */
/* save the notification somewhere to delete it later from NC */
self.someArrayToSaveDeliveredNotifications.append(sameNotificationAsAbove)
/* fire the notification */
UIApplication.sharedApplication().presentLocalNotificationNow(sameNotificationAsAbove)
case default:
/* if it is true that notication inside NC can be deleted just by calling 'cancelLocalNotification' function */
/* so find your notification inside someArrayToSaveDeliveredNotifications bases on the region.identier which you saved inside userInfo */
let notificationToCancel = self.getNotificationForIdentifier(region.identifier)
UIApplication.sharedApplication().cancelLocalNotification(notificationToCancel)
/* this should delete your notification from NC based on other answers */
}
}
Это какая-то псевдомеханика, которую я бы построил, если бы мне пришлось, поэтому, если что-то не так или неправильно, я был бы признателен за ваши отзывы.:)
Ответ 3
Это очистит все уведомления приложений из Центра уведомлений.
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Ответ 4
Похоже, вы можете очистить конкретное уведомление, если удерживаете объект UILocalNotification. Используя свой объект уведомления, который вы создали в приведенном выше примере, вы можете позвонить
[[UIApplication sharedApplication] cancelLocalNotification:notification];
чтобы очистить уведомление.
Ответ 5
Это похоже на очень простое решение. выполните следующие шаги, которые вам помогут.
- Сделайте одно фоновое обслуживание, которое будет работать в фоновом режиме, чтобы проверить ваше местоположение.
- Когда вы входите в местное уведомление о локальном пожаре, которое уже сделано вами. хорошая работа.
- Но когда вы покидаете этот регион (проверьте справочную службу с указанием данных о местоположении, например, теперь местоположение совпадает с данными о местоположении, когда пользователь вводил этот регион). запустите новое локальное уведомление с пустыми данными. и он также очистит уведомление из окна уведомления.
Ответ 6
Вы должны вызвать фоновый метод, который должен вызываться только тогда, когда устройство выходит из местоположения. Это может быть достигнуто путем создания слоя для области и запуска сразу, когда он выходит из границы.
В этом методе вы можете либо удалить все уведомления о соответствующем приложении с помощью
[[UIApplication sharedApplication] cancelLocalNotification:notification];
или может удалить только определенное уведомление, вызвав
UIApplication* application = [UIApplication sharedApplication];
NSArray* scheduledNotifications = [NSArray arrayWithArray:application.scheduledLocalNotifications];
application.scheduledLocalNotifications = scheduledNotifications;
Вы получите все действующие уведомления, доступные для конкретного приложения. Удалите конкретное уведомление для определенного региона.
Ответ 7
CLLocationManagerDelegate. Делегат имеет набор методов, которые получают инициированную базу в местоположении устройства. Например:
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
В вашем случае, что вам нужно сделать, это когда срабатывает следующий обратный вызов;
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
удалите уведомление из NotificationCenter