166 lines
6.3 KiB
Objective-C
166 lines
6.3 KiB
Objective-C
//
|
|
// NotificationViewController.m
|
|
// EQNNotificationContent
|
|
//
|
|
// Refactored by Andrea Busi on 14/10/2020.
|
|
// Copyright © 2020 Earthquake Network. All rights reserved.
|
|
//
|
|
|
|
#import "NotificationViewController.h"
|
|
#import "PastquakesAnnotation.h"
|
|
#import "ReteSismicaAnnotation.h"
|
|
#import "EQNUtility.h"
|
|
|
|
@import UserNotifications;
|
|
@import UserNotificationsUI;
|
|
@import MapKit;
|
|
|
|
@interface NotificationViewController () <UNNotificationContentExtension, MKMapViewDelegate>
|
|
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
|
|
@property (weak, nonatomic) IBOutlet UILabel *descriptionLabel;
|
|
@property (weak, nonatomic) IBOutlet UILabel *waveLabel;
|
|
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
|
|
|
|
/// This will be calculated as seismic date + warning time
|
|
@property (strong, nonatomic) NSDate *userSeismicTimestamp;
|
|
@property (strong, nonatomic) NSTimer *countdownTimer;
|
|
@end
|
|
|
|
@implementation NotificationViewController
|
|
|
|
- (void)setMapView:(MKMapView *)mapView
|
|
{
|
|
_mapView = mapView;
|
|
_mapView.scrollEnabled = NO;
|
|
_mapView.zoomEnabled = NO;
|
|
}
|
|
|
|
#pragma mark - View Lifecycle
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
// Do any required interface initialization here.
|
|
}
|
|
|
|
- (void)didReceiveNotification:(UNNotification *)notification
|
|
{
|
|
UNNotificationContent *content = notification.request.content;
|
|
NSDictionary *userInfo = content.userInfo;
|
|
|
|
// set title and description
|
|
self.titleLabel.text = content.title;
|
|
self.descriptionLabel.text = content.body;
|
|
|
|
// add annotation onthe map
|
|
CLLocation *coordinate = [[CLLocation alloc] initWithLatitude:[userInfo[@"latitude"] doubleValue]
|
|
longitude:[userInfo[@"longitude"] doubleValue]];
|
|
MKCoordinateSpan span = MKCoordinateSpanMake(10.5, 10.5);
|
|
MKCoordinateRegion region = MKCoordinateRegionMake(coordinate.coordinate, span);
|
|
[self.mapView setCenterCoordinate:coordinate.coordinate animated:NO];
|
|
[self.mapView setRegion:region animated:YES];
|
|
|
|
if ([userInfo[@"type"] isEqualToString:@"eqn"]) {
|
|
PastquakesAnnotation *annotation = [[PastquakesAnnotation alloc] initWithTitle:content.body
|
|
location:coordinate.coordinate
|
|
intensita:[userInfo[@"intensity"] intValue]];
|
|
[self.mapView addAnnotation:annotation];
|
|
|
|
} else if ([userInfo[@"type"] isEqualToString:@"manual"]){
|
|
ReteSismicaAnnotation *annotation = [[ReteSismicaAnnotation alloc] initWithTitle:content.body
|
|
location:coordinate.coordinate
|
|
magnitudo:[userInfo[@"magnitudo"] intValue]];
|
|
[self.mapView addAnnotation:annotation];
|
|
}
|
|
|
|
|
|
self.userSeismicTimestamp = [self calculateUserSeismicTimestampWithInfo:userInfo];
|
|
if (self.userSeismicTimestamp) {
|
|
// start the countdown
|
|
self.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
|
|
target:self
|
|
selector:@selector(countdownFired:)
|
|
userInfo:nil
|
|
repeats:YES];
|
|
[self.countdownTimer fire];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Private
|
|
|
|
- (nullable NSDate *)calculateUserSeismicTimestampWithInfo:(NSDictionary *)info
|
|
{
|
|
// dobbiamo calcolare l'ora in cui il sisma arriverà nella posizione dell'utente
|
|
// per fare questo, il calcolo sarà:
|
|
// timestamp sisma + warning time
|
|
|
|
// ultima posizione nota dell'utente
|
|
CLLocationManager *manager = [[CLLocationManager alloc] init];
|
|
CLLocation *lastUserLocation = manager.location;
|
|
if (!lastUserLocation) {
|
|
return nil;
|
|
}
|
|
|
|
// posizione sisma
|
|
double latitude = [info[@"latitude"] doubleValue];
|
|
double longitude = [info[@"longitude"] doubleValue];
|
|
CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
|
|
|
|
// distanza tra sisma e utente (in km)
|
|
CLLocationDistance distance = [lastUserLocation distanceFromLocation:location];
|
|
double userDistance = distance/1000;
|
|
|
|
// calcoliamo warning_time
|
|
double waveSpeed = [info[@"wave_speed"] doubleValue];
|
|
double warningTime = round(userDistance/waveSpeed - 5);
|
|
|
|
// aggiungiamo il warning time al timestamp del sisma
|
|
NSDate *seismicDate = [EQNUtility getDateFromString:info[@"datetime"]];
|
|
NSDate *userSeismicDate = [seismicDate dateByAddingTimeInterval:warningTime];
|
|
|
|
return userSeismicDate;
|
|
}
|
|
|
|
- (void)countdownFired:(id)sender
|
|
{
|
|
NSDate *now = [NSDate date];
|
|
NSTimeInterval difference = MAX([self.userSeismicTimestamp timeIntervalSinceDate:now], 0);
|
|
|
|
self.waveLabel.text = [NSString stringWithFormat:@"%@ %.0f %@", NSLocalizedString(@"alert_wave", @""), difference, NSLocalizedString(@"alert_seconds", @"")];
|
|
|
|
if (difference <= 0) {
|
|
// stop the countdown
|
|
[self.countdownTimer invalidate];
|
|
self.countdownTimer = nil;
|
|
}
|
|
}
|
|
|
|
#pragma mark - MKMapViewDelegate
|
|
|
|
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
|
|
{
|
|
if ([annotation isKindOfClass:[PastquakesAnnotation class]]) {
|
|
PastquakesAnnotation *anLocation = (PastquakesAnnotation *)annotation;
|
|
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_PASTQUAKES];
|
|
if (annotationView == nil) {
|
|
annotationView = anLocation.annotationView;
|
|
} else {
|
|
annotationView.annotation = anLocation;
|
|
}
|
|
return annotationView;
|
|
|
|
} else if ([annotation isKindOfClass:[ReteSismicaAnnotation class]]) {
|
|
ReteSismicaAnnotation *anLocation = (ReteSismicaAnnotation *)annotation;
|
|
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_RETESMARTPHONE];
|
|
if (annotationView == nil) {
|
|
annotationView = anLocation.annotationView;
|
|
} else {
|
|
annotationView.annotation = anLocation;
|
|
}
|
|
return annotationView;
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
@end
|