Compare commits

...

69 Commits

Author SHA1 Message Date
Andrea Busi 928793b755 release: Increase version for release 2020-10-01 19:19:23 +02:00
Andrea Busi 3d7a0ad9f6 refactor: Remove initial loading controller 2020-10-01 19:19:23 +02:00
Andrea Busi 00a54dede1 feat: Show country selection on first app start 2020-10-01 19:19:23 +02:00
Andrea Busi 76861163a3 fix: Use proper formatter for decimal values 2020-10-01 19:19:23 +02:00
Andrea Busi 8ba2f8cea6 fix: Use https for new settings endpoint 2020-10-01 13:04:13 +02:00
Andrea Busi bcfadc7f3e fix: Fix crash due to wrong ES string 2020-10-01 13:04:13 +02:00
Andrea Busi e830e2eeb5 dependency: Update Pods 2020-09-30 15:59:12 +02:00
Andrea Busi e37ea4757d feat: Add icons for new seismic networks 2020-09-30 13:07:10 +02:00
Andrea Busi 5504160db6 feat: Add text when share seismic card 2020-09-30 12:58:13 +02:00
Andrea Busi 0dddb1c69b refactor: Improve code style 2020-09-30 12:58:13 +02:00
Andrea Busi 9c70f0a6d6 fix: Try to solve crazy crash 2020-09-30 12:58:13 +02:00
Andrea Busi d6d3ee8682 fix: Solve crash when reload table with already expanded cells 2020-09-30 12:58:13 +02:00
Andrea Busi 397e1c6e24 fix: Use proper translation 2020-09-28 10:52:48 +02:00
Andrea Busi 2b304cd7aa feat: Improve country picker selection 2020-09-28 10:26:33 +02:00
Andrea Busi 88c1c5aa16 feat: Update notification settings when user select a country 2020-09-27 17:28:18 +02:00
Andrea Busi 7a9206b15a feat: Add new seismic networks
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/20
2020-09-27 17:28:18 +02:00
Andrea Busi ee7596644b refactor: Use new endpoint to save settings value and remove no longer needed settings
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/20
2020-09-27 17:28:17 +02:00
Andrea Busi 85191d228e fix: Save missing value for raggio sismi forti setting 2020-09-27 17:28:17 +02:00
Andrea Busi b3f099efd8 refactor: Move default settings save in dedicated methods 2020-09-27 17:28:17 +02:00
Andrea Busi e11c5f8f19 refactor: Remove unused enum 2020-09-27 14:02:43 +02:00
Andrea Busi bbcf67d7cc fix: Update some missing translations 2020-09-27 14:02:43 +02:00
Andrea Busi 89193b61ce fix: Minor layout fixes 2020-09-27 14:02:43 +02:00
Andrea Busi d5993d01bf feat: Add message for empty seismic table 2020-09-26 18:31:00 +02:00
Andrea Busi 3b379a5da1 dependency: Add DZNEmptyDataSet 2020-09-26 18:31:00 +02:00
Andrea Busi 7013b868b2 fix: Use proper zoom on seismic map 2020-09-26 18:31:00 +02:00
Andrea Busi 211de82031 feat: Add "expande/collapse" to show/hide buttons in seismic cards
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/21
2020-09-26 18:31:00 +02:00
Andrea Busi e8b5f742d1 feat: Open map detail when tap on map in cell 2020-09-26 18:31:00 +02:00
Andrea Busi 0731a1e134 fix: Update seismic networks
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/21
2020-09-26 18:31:00 +02:00
Andrea Busi 1dc71ca8df refactor: Remove duplicated strings 2020-09-26 16:23:58 +02:00
Andrea Busi ea275e46b9 feat: Add command to set default settings 2020-09-26 14:28:11 +02:00
Andrea Busi de1912ea99 refactor: Add missing translations 2020-09-26 14:28:11 +02:00
Andrea Busi 4ec735ac9e fix: Add missing translations for previous release 2020-09-26 14:28:11 +02:00
Andrea Busi c15aeb0e3a feat: Add card settings 2020-09-26 14:08:32 +02:00
Andrea Busi 3b5e8e395f refactor: Remove old sesmic layout and controller 2020-09-26 14:08:32 +02:00
Andrea Busi 672982d7d5 feat: Add missing logic in new seismic controller 2020-09-26 14:08:32 +02:00
Andrea Busi 2ee413d9c8 feat: Add feature to save seismic event in calendar 2020-09-26 14:08:23 +02:00
Andrea Busi 39a10b2cbc feat: New beautifult layout for seismic cards 2020-09-26 14:08:23 +02:00
Andrea Busi 0eb0880b0e refactor: Improve code in EQMaccelerometroManager class 2020-09-25 22:15:15 +02:00
Andrea Busi 73c8ce1094 refactor: Move background fetch directly in the AppDelegate 2020-09-25 13:30:30 +02:00
Andrea Busi 4bb4815cd1 refactor: Better ServerRequest class
- Remove dead code
- Always call completion when handle the request
- Remove crazy checks when handle responses
2020-09-25 13:30:30 +02:00
Andrea Busi 1501b88a02 refactor: Improve EQNSisma model in order to use proper data types 2020-09-24 10:43:28 +02:00
Andrea Busi cd94302e00 release: Increase version for release 2020-09-24 10:26:55 +02:00
Andrea Busi eed5f6ae28 refactor: Convert constants from macro to static const (and use https) 2020-09-24 10:26:55 +02:00
Andrea Busi d29621492a fix: Force data download if magnitude filter change 2020-09-24 10:26:55 +02:00
Andrea Busi e56919d279 feat: Add different seismic endpoints based on the magnitude filter
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/15
2020-09-24 10:26:55 +02:00
Andrea Busi 28f31979bb refactor: Remove not yet used Tsunami model 2020-09-24 10:26:55 +02:00
Andrea Busi 3b93ab84ce refactor: Improve code in EQNManager and remove dead code 2020-09-24 10:26:55 +02:00
Andrea Busi 8a4f6436f0 refactor: Use updated API to retrieve seismics 2020-09-24 10:26:55 +02:00
Andrea Busi ea2573c17c refactor: Reorganize some constants 2020-09-24 10:26:55 +02:00
Andrea Busi 0f5c4fc8dc Merge branch 'stable/v2.2.x' into develop 2020-09-24 10:25:45 +02:00
Andrea Busi 831c33bdb9 release: Increase version for release 2020-09-21 14:01:14 +02:00
Andrea Busi 7438f8bfb9 fix: Force alert refresh when view is displayed 2020-09-21 14:00:49 +02:00
Andrea Busi 86de3fa026 refactor: Remove no longer used class 2020-09-21 14:00:49 +02:00
Andrea Busi b47fdcb8a1 feat: Update notification settings when seismic filters change 2020-09-21 09:33:03 +02:00
Andrea Busi ce3436876d refactor: Improve code for notification models 2020-09-21 09:33:03 +02:00
Andrea Busi 2d0a453626 feat: Add warning alert if magitude filter is lower than 2.0 2020-09-21 09:33:03 +02:00
Andrea Busi e9cc1e9ea2 refactor: Review nav bar background and tint color 2020-09-21 09:33:03 +02:00
Andrea Busi 2627eef807 dependency: Update Pods 2020-09-20 21:48:42 +02:00
Andrea Busi 4cf1ae1fb3 chore: Update Xcode to recommended settings 2020-09-20 21:48:42 +02:00
Andrea Busi c7bf8ecc94 refactor: Recreate filters in Seismic section
- Add new fitlters
- Recreate controllers and support classes in Swift

Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/14
2020-09-20 21:48:42 +02:00
Andrea Busi 323a9df3e8 refactor: Improve Swift interoperability 2020-09-20 16:06:39 +02:00
Andrea Busi ce21acce3b fix: Add missing translation for a magnitude value 2020-09-20 16:06:39 +02:00
Andrea Busi 81f8740486 refactor: Recreate controllers to manage filters in Seismic section 2020-09-15 07:05:43 +02:00
Andrea Busi 41c4170e71 feat: Add generic picker view 2020-09-15 07:05:42 +02:00
Andrea Busi 16e0d15522 fix: Remove debug print 2020-09-11 17:13:23 +02:00
Andrea Busi 62e6437d4a refactor: Remove not yet used classes 2020-09-11 17:13:19 +02:00
Andrea Busi a71ee9afbf feat: Add class to style rounded buttons 2020-09-11 17:11:39 +02:00
Andrea Busi bb3c8798f3 refactor: Use Colors inside AppTheme to handle app colors 2020-09-11 17:11:39 +02:00
Andrea Busi c23012cc56 refactor: Remove unused color 2020-09-11 16:30:08 +02:00
139 changed files with 4298 additions and 5289 deletions
+66
View File
@@ -1,5 +1,71 @@
# Changelog
## Versione 2.3
### Build (34)
- Apertura automatica selezione nazione (solo 1 volta, ad installazione/update app)
- Corretti decimali in layout card sisma
- Rimosso controller loading iniziale
### Build (33)
- Corretto crash con lingua spagnola
### Build (32)
- Aggiunto testo in condivisione sisma
- Aggiunte icone in notifiche push per nuove reti
### Build (31)
- Risolto crash in reload tabella reti sismiche
- Possibile fix per crash in background
### Build (30)
- Migliorata selezione nazione
- Corretta traduzione errata
### Build (29)
- Corretti colore e udm magnitudo in schede sisma
- Aggiunte nuove reti sismiche
- Migrato a nuovo endpoint per salvataggio settings
- Corretto errore in invio parametri settings
- Aggiunto aggiornamento reti notifiche da selezione nazione
### Build (28)
- Messaggio se tabella sismi è vuota
- Corretto filtro enti
### Build (27)
- Corretto zoom mappa
- Corretto elenco reti e ordinato in filtri
- Apertura mappa da cella espansa
- Aggiornate icone sezione sismi e aggiunga espandi/collassa
### Build (26)
- Aggiunto salvataggio evento in calendario
- Aggiunta logica mancante (filtri, impostazioni e mappa dettaglio)
- Corretto layout schede sismi
- Aggiunta gestione campanella
- Aggiunto popup per impostazioni singola card
### Build (25)
- Nuovo layout in schede sismi
### Build (23)
- Refresh impostazioni se torno da filtri
- Cambiata API per download sismi e aggiornati relativi modelli
- Aggiunta nuova gestione per download sismi in base a magnitudo
### Build (22)
- Aggiunto aggiornamento impostazioni notifiche se toggle filtri sismi è attivo
- Correzioni grafiche varie
### Build (21)
- Ricreato controlle per gestione filtri Sismi
- Aggiunti filtri mancanti e rivista logica filtro
- Compilazione con Xcode 12 (iOS 14)
### Build (20)
- Ricreati controller per gestione filtri in sezione Sismi
## Versione 2.2.1
### Build (24)
@@ -17,67 +17,37 @@
@implementation NotificationService
/*
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
// Modify the notification content here...
self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
self.contentHandler(self.bestAttemptContent);
}
*/
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler
{
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
// Modify the notification content here...
// Configure the notification's payload.
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:request.content.title arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:request.content.body
arguments:nil];
content.sound = [UNNotificationSound defaultSound];
// Configure the notification's payload.
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:request.content.title arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:request.content.body
arguments:nil];
content.sound = [UNNotificationSound defaultSound];
self.bestAttemptContent.title = content.title;
self.bestAttemptContent.body = content.body;
/*
// Deliver the notification in five seconds.
UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger
triggerWithTimeInterval:5 repeats:NO];
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond"
content:content trigger:trigger];
// Schedule the notification.
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request];
*/
// check for media attachment, example here uses custom payload keys mediaUrl and mediaType
NSDictionary *userInfo = request.content.userInfo;
NSString *messaggioModificato = @"non modificato";
if (userInfo == nil)
{
if (userInfo == nil) {
[self contentComplete];
return;
}
if ([userInfo objectForKey:@"type"])
{
if ([userInfo objectForKey:@"type"]) {
NSString *stringURL = @"http://www.earthquakenetwork.it/icons/";
if ([[userInfo objectForKey:@"type"] isEqualToString:@"eqn"]) {
self.bestAttemptContent.sound = [UNNotificationSound soundNamed:[EQNAllertaSismica center].tonoAllarme];
self.bestAttemptContent.sound = [UNNotificationSound soundNamed:[EQNAllertaSismica sharedInstance].tonoAllarme];
NSString *intensity = [userInfo objectForKey:@"intensity"];
switch ([intensity intValue]) {
@@ -93,11 +63,7 @@
default:
break;
}
}
else if ([[userInfo objectForKey:@"type"] isEqualToString:@"manual"]) {
} else if ([[userInfo objectForKey:@"type"] isEqualToString:@"manual"]) {
NSString *intensity = [userInfo objectForKey:@"magnitude"];
switch ([intensity intValue]) {
case 0:
@@ -111,62 +77,64 @@
break;
default:
break;
}
}
else if ([[userInfo objectForKey:@"type"] isEqualToString:@"official"]) {
} else if ([[userInfo objectForKey:@"type"] isEqualToString:@"official"]) {
NSString *provaider = [userInfo objectForKey:@"provider"];
double intensity = [[userInfo objectForKey:@"magnitude"] doubleValue];
NSString *colore = @"green";
if (intensity < 3.5)
NSString *colore = @"";
if (intensity < 2.0) {
colore = @"_white";
} else if (intensity < 3.5) {
colore = @"_green";
else if (intensity < 4.5)
} else if (intensity < 4.5) {
colore = @"_yellow";
else if (intensity < 5.5)
} else if (intensity < 5.5) {
colore = @"_red";
else
} else {
colore = @"_purple";
if ([provaider isEqualToString:@"USGS"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star%@2.png", colore]];
if ([provaider isEqualToString:@"SGC"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star3%@2.png", colore]];
if ([provaider isEqualToString:@"CSN"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star3f%@2.png", colore]];
if ([provaider isEqualToString:@"SSN"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star4%@2.png", colore]];
if ([provaider isEqualToString:@"INPRES"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star4r%@2.png", colore]];
if ([provaider isEqualToString:@"FUNVISIS"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star6%@2.png", colore]];
if ([provaider isEqualToString:@"Ineter"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"triangle%@2.png", colore]];
if ([provaider isEqualToString:@"RSN"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"triangle2%@2.png", colore]];
if ([provaider isEqualToString:@"PHIVOLCS"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"triround_inner%@2.png", colore]];
if ([provaider isEqualToString:@"IGEPN"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"triround%@2.png", colore]];
if ([provaider isEqualToString:@"INGV"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"circle%@2.png", colore]];
if ([provaider isEqualToString:@"EMSC"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"dyamond%@2.png", colore]];
if ([provaider isEqualToString:@"IGP"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"dyamond_round%@2.png", colore]];
if ([provaider isEqualToString:@"JMA"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"esa%@2.png", colore]];
if ([provaider isEqualToString:@"GEONET"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"oct%@2.png", colore]];
if ([provaider isEqualToString:@"CSI"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"penta%@2.png", colore]];
if ([provaider isEqualToString:@"IGN"])
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"square%@2.png", colore]];
}
else if ([[userInfo objectForKey:@"type"] isEqualToString:@"tsunami"]){
}
if ([provaider isEqualToString:@"USGS"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star%@2.png", colore]];
} else if ([provaider isEqualToString:@"SGC"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star3%@2.png", colore]];
} else if ([provaider isEqualToString:@"CSN"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star3f%@2.png", colore]];
} else if ([provaider isEqualToString:@"SSN"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star4%@2.png", colore]];
} else if ([provaider isEqualToString:@"INPRES"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star4r%@2.png", colore]];
} else if ([provaider isEqualToString:@"FUNVISIS"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star6%@2.png", colore]];
} else if ([provaider isEqualToString:@"Ineter"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"triangle%@2.png", colore]];
} else if ([provaider isEqualToString:@"RSN"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"triangle2%@2.png", colore]];
} else if ([provaider isEqualToString:@"PHIVOLCS"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"triround_inner%@2.png", colore]];
} else if ([provaider isEqualToString:@"IGEPN"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"triround%@2.png", colore]];
} else if ([provaider isEqualToString:@"INGV"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"circle%@2.png", colore]];
} else if ([provaider isEqualToString:@"EMSC"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"dyamond%@2.png", colore]];
} else if ([provaider isEqualToString:@"IGP"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"dyamond_round%@2.png", colore]];
} else if ([provaider isEqualToString:@"JMA"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"esa%@2.png", colore]];
} else if ([provaider isEqualToString:@"GEONET"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"oct%@2.png", colore]];
} if ([provaider isEqualToString:@"CSI"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"penta%@2.png", colore]];
} else if ([provaider isEqualToString:@"IGN"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"square%@2.png", colore]];
} else if ([provaider isEqualToString:@"UASD"] || [provaider isEqualToString:@"BDTIM"] || [provaider isEqualToString:@"NCS"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"thick_star%@2.png", colore]];
} else if ([provaider isEqualToString:@"RSPR"]) {
stringURL = [stringURL stringByAppendingString:[NSString stringWithFormat:@"star6f%@2.png", colore]];
}
} else if ([[userInfo objectForKey:@"type"] isEqualToString:@"tsunami"]){
NSString *color = [userInfo objectForKey:@"color"];
if ([color isEqualToString:@"gr"])
@@ -181,23 +149,20 @@
stringURL = [stringURL stringByAppendingString:@"tsunami_red.png"];
messaggioModificato = [self setMessage:[userInfo objectForKey:@"message"]];
}
[self loadAttachmentForUrlString:stringURL
completionHandler: ^(UNNotificationAttachment *attachment) {
self.bestAttemptContent.attachments = [NSArray arrayWithObjects:attachment, nil];
if (![messaggioModificato isEqualToString:@"non modificato"])
self.bestAttemptContent.body = [NSString stringWithFormat:@"%@", messaggioModificato];
}];
self.bestAttemptContent.attachments = [NSArray arrayWithObjects:attachment, nil];
if (![messaggioModificato isEqualToString:@"non modificato"])
self.bestAttemptContent.body = [NSString stringWithFormat:@"%@", messaggioModificato];
}];
}
}
-(NSString *)setMessage:(NSString *)message{
- (NSString *)setMessage:(NSString *)message
{
BOOL warning = false;
BOOL watch = false;
BOOL threat = false;
@@ -223,46 +188,40 @@
if ([message.lowercaseString containsString:@"supplement"])
supplement = YES;
if (warning){
if (warning) {
if (supplement)
_message = NSLocalizedString(@"Supplemento di allerta", @"");
_message = NSLocalizedString(@"Supplemento di allerta", @"");
else if(cancellation)
_message = NSLocalizedString(@"Allerta cancellata", @"");
_message = NSLocalizedString(@"Allerta cancellata", @"");
else
_message = NSLocalizedString(@"Allerta Tsunami", @"");
}
else if (watch){
_message = NSLocalizedString(@"Allerta Tsunami", @"");
} else if (watch) {
if (supplement)
_message = NSLocalizedString(@"Supplemento di valutazione", @"");
_message = NSLocalizedString(@"Supplemento di valutazione", @"");
else if(cancellation)
_message = NSLocalizedString(@"Valutazione cancellata", @"");
_message = NSLocalizedString(@"Valutazione cancellata", @"");
else
_message = NSLocalizedString(@"Valutazione Tsunami", @"");
}
else if (threat){
_message = NSLocalizedString(@"Valutazione Tsunami", @"");
} else if (threat) {
if (threatFinal)
_message = NSLocalizedString(@"Pericolo cessato", @"");
_message = NSLocalizedString(@"Pericolo cessato", @"");
else
_message = NSLocalizedString(@"Pericolo tsunami", @"");
}
else if (information){
_message = NSLocalizedString(@"Pericolo tsunami", @"");
} else if (information){
_message = NSLocalizedString(@"Messaggio informativo", @"");
}
else if (supplement){
} else if (supplement){
_message = NSLocalizedString(@"Messaggio supplementare", @"");
}
return _message;
}
- (void)serviceExtensionTimeWillExpire {
- (void)serviceExtensionTimeWillExpire
{
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
[self contentComplete];
self.contentHandler(self.bestAttemptContent);
}
@@ -277,37 +236,37 @@
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:attachmentURL
completionHandler: ^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) {
if (error != nil)
{
NSLog(@"%@", error.localizedDescription);
self.bestAttemptContent.body = [NSString stringWithFormat:@"%@ [error], %@", self.bestAttemptContent.body,error.localizedDescription];
}
else
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localURL = [NSURL fileURLWithPath:[temporaryFileLocation.path
stringByAppendingString:fileExt]];
[fileManager moveItemAtURL:temporaryFileLocation
toURL:localURL
error:&error];
NSError *attachmentError = nil;
attachment = [UNNotificationAttachment attachmentWithIdentifier:[attachmentURL lastPathComponent]
URL:localURL
options:nil
error:&attachmentError];
if (attachmentError)
{
NSLog(@"%@", attachmentError.localizedDescription);
self.bestAttemptContent.body = [NSString stringWithFormat:@"%@ [attachmentError], %@", self.bestAttemptContent.body,error.localizedDescription];
}
}
completionHandler(attachment);
}];
completionHandler: ^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) {
if (error != nil)
{
NSLog(@"%@", error.localizedDescription);
self.bestAttemptContent.body = [NSString stringWithFormat:@"%@ [error], %@", self.bestAttemptContent.body,error.localizedDescription];
}
else
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localURL = [NSURL fileURLWithPath:[temporaryFileLocation.path
stringByAppendingString:fileExt]];
[fileManager moveItemAtURL:temporaryFileLocation
toURL:localURL
error:&error];
NSError *attachmentError = nil;
attachment = [UNNotificationAttachment attachmentWithIdentifier:[attachmentURL lastPathComponent]
URL:localURL
options:nil
error:&attachmentError];
if (attachmentError)
{
NSLog(@"%@", attachmentError.localizedDescription);
self.bestAttemptContent.body = [NSString stringWithFormat:@"%@ [attachmentError], %@", self.bestAttemptContent.body,error.localizedDescription];
}
}
completionHandler(attachment);
}];
[task resume];
}
@@ -317,4 +276,5 @@
[self.session invalidateAndCancel];
self.contentHandler(self.bestAttemptContent);
}
@end
@@ -10,8 +10,6 @@
8C10B0B92281FE7F00125C9F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C10B0BD2281FE7F00125C9F /* Localizable.strings */; };
8C10B0BA2281FE7F00125C9F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C10B0BD2281FE7F00125C9F /* Localizable.strings */; };
8C10B0BB2281FE7F00125C9F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C10B0BD2281FE7F00125C9F /* Localizable.strings */; };
8C13E84B220B2E7E0009CFE4 /* MenuSelezioneEntiViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C13E84A220B2E7E0009CFE4 /* MenuSelezioneEntiViewController.m */; };
8C13E84F220B89360009CFE4 /* ElencoFiltroEntiTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C13E84E220B89360009CFE4 /* ElencoFiltroEntiTableViewController.m */; };
8C14113121ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113021ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m */; };
8C14113721EE502800A59729 /* EQNAllertaSismica.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113621EE502800A59729 /* EQNAllertaSismica.m */; };
8C2B251121938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2B251021938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m */; };
@@ -23,9 +21,6 @@
8C465D9E21F7BD8700F04673 /* PastquakesAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C602249218EDBE200C799C2 /* PastquakesAnnotation.m */; };
8C465D9F21F7BE0600F04673 /* Assets.xcassets in Sources */ = {isa = PBXBuildFile; fileRef = 8CBD3DD12149B9AD0070C963 /* Assets.xcassets */; };
8C483C9721FA662900259FD2 /* alert_star_trek.wav in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CF12CC721DE43A400613AC5 /* alert_star_trek.wav */; };
8C483C9A21FA664000259FD2 /* EQNAllertaSismica.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113621EE502800A59729 /* EQNAllertaSismica.m */; };
8C483C9B21FA665C00259FD2 /* EQNAllertaSismica.h in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C14113521EE502800A59729 /* EQNAllertaSismica.h */; };
8C483C9C21FA665C00259FD2 /* EQNAllertaSismica.m in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C14113621EE502800A59729 /* EQNAllertaSismica.m */; };
8C483CA521FBC06D00259FD2 /* alerta_japanese.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 8C483CA421FBC06D00259FD2 /* alerta_japanese.m4r */; };
8C483CA621FBC06D00259FD2 /* alerta_japanese.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 8C483CA421FBC06D00259FD2 /* alerta_japanese.m4r */; };
8C483CA721FBC06D00259FD2 /* alerta_japanese.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 8C483CA421FBC06D00259FD2 /* alerta_japanese.m4r */; };
@@ -53,13 +48,9 @@
8C7CD64921F7D11700835812 /* ReteSismicaAnnotation.m in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CD08637218B3BEE0000CB5E /* ReteSismicaAnnotation.m */; };
8C7CD64A21F7D11700835812 /* ReteSismicaAnnotation.h in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CD08636218B3BEE0000CB5E /* ReteSismicaAnnotation.h */; };
8C8EBBA721540039002784BA /* EQNUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C8EBBA621540039002784BA /* EQNUser.m */; };
8C9B755C2233A25100F8FDEE /* MenuFiltroEntiViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C9B755B2233A25100F8FDEE /* MenuFiltroEntiViewController.m */; };
8C9B755F2233BFDE00F8FDEE /* FiltroEnti.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C9B755E2233BFDE00F8FDEE /* FiltroEnti.m */; };
8CA46BA12194532E00C63C16 /* SismaAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CA46BA02194532E00C63C16 /* SismaAnnotation.m */; };
8CABD7212194B7C700C3E09C /* ImpostazioniViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CABD7202194B7C700C3E09C /* ImpostazioniViewController.m */; };
8CADAA9421B2627D0044E256 /* LogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CADAA9321B2627D0044E256 /* LogViewController.m */; };
8CAFD7C521825E4A00F8BD29 /* EQNSisma.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CAFD7C421825E4A00F8BD29 /* EQNSisma.m */; };
8CAFD7C82182648600F8BD29 /* EQNRetiSismiViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CAFD7C72182648600F8BD29 /* EQNRetiSismiViewController.m */; };
8CBD3DC72149B9AD0070C963 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CBD3DC62149B9AD0070C963 /* AppDelegate.m */; };
8CBD3DCA2149B9AD0070C963 /* ReteSmartphone.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CBD3DC92149B9AD0070C963 /* ReteSmartphone.m */; };
8CBD3DCD2149B9AD0070C963 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8CBD3DCB2149B9AD0070C963 /* Main.storyboard */; };
@@ -68,21 +59,13 @@
8CBD3DD82149B9AD0070C963 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CBD3DD72149B9AD0070C963 /* main.m */; };
8CC1B15A217CB09100F22178 /* DettagliMappaViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CC1B159217CB09100F22178 /* DettagliMappaViewController.m */; };
8CC2B44F214AC7F8002ED1B2 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CC2B44E214AC7F8002ED1B2 /* CoreMotion.framework */; };
8CCE164421E67F1300173CD9 /* EQNImpostazioniNotifiche.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE164321E67F1300173CD9 /* EQNImpostazioniNotifiche.m */; };
8CCE164B21E7BAB200173CD9 /* EQNNotificheTempoReale.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE164A21E7BAB200173CD9 /* EQNNotificheTempoReale.m */; };
8CCE164E21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE164D21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.m */; };
8CCE165121E7BAEC00173CD9 /* EQNNotificeReteSismiche.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE165021E7BAEC00173CD9 /* EQNNotificeReteSismiche.m */; };
8CCE165121E7BAEC00173CD9 /* EQNNotificheReteSismiche.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE165021E7BAEC00173CD9 /* EQNNotificheReteSismiche.m */; };
8CCE165521EA378800173CD9 /* SettingsUserReportAlertsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE165421EA378800173CD9 /* SettingsUserReportAlertsViewController.m */; };
8CCE165821EB1E0000173CD9 /* SettingsSeismicNetworkAlertsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE165721EB1E0000173CD9 /* SettingsSeismicNetworkAlertsViewController.m */; };
8CCE166121EBA37500173CD9 /* EQNNotificheTsunami.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE166021EBA37500173CD9 /* EQNNotificheTsunami.m */; };
8CD0862E218A41930000CB5E /* CellDettagliMappaTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD0862D218A41930000CB5E /* CellDettagliMappaTableViewCell.m */; };
8CD08631218ADFCA0000CB5E /* Cell_Reti_sismicheTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD08630218ADFCA0000CB5E /* Cell_Reti_sismicheTableViewCell.m */; };
8CD08635218AF6030000CB5E /* Cell_Meteo_TableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD08634218AF6030000CB5E /* Cell_Meteo_TableViewCell.m */; };
8CD08638218B3BEE0000CB5E /* ReteSismicaAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD08637218B3BEE0000CB5E /* ReteSismicaAnnotation.m */; };
8CF05B51218C41FB0055012B /* PickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF05B4B218C41F90055012B /* PickerViewController.m */; };
8CF05B52218C41FB0055012B /* TBDInputViewControllerData.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8CF05B4E218C41FA0055012B /* TBDInputViewControllerData.xib */; };
8CF05B53218C41FB0055012B /* PickerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8CF05B4F218C41FA0055012B /* PickerViewController.xib */; };
8CF05B54218C41FB0055012B /* TBDInputViewControllerData.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF05B50218C41FB0055012B /* TBDInputViewControllerData.m */; };
8CF05B57218C93BA0055012B /* EQNUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF05B56218C93BA0055012B /* EQNUtility.m */; };
8CF12CCA21DE43A500613AC5 /* alert_star_trek.wav in Resources */ = {isa = PBXBuildFile; fileRef = 8CF12CC721DE43A400613AC5 /* alert_star_trek.wav */; };
8CF12CD321DE49B600613AC5 /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CF12CD221DE49B600613AC5 /* UserNotifications.framework */; };
@@ -94,28 +77,34 @@
8CF4F4D5216D336B0057110B /* EQNDatoGrafico.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF4F4D4216D336B0057110B /* EQNDatoGrafico.m */; };
8CF4F4D8216D3A110057110B /* EQNAreaCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF4F4D7216D3A110057110B /* EQNAreaCheck.m */; };
8CF4F4DB216D44930057110B /* EQNPastquakes.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF4F4DA216D44930057110B /* EQNPastquakes.m */; };
8CF4F4DE2175352E0057110B /* WaitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF4F4DD2175352E0057110B /* WaitViewController.m */; };
8CF6604F214C0E58009F4314 /* EQNCalibrazione.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF6604E214C0E58009F4314 /* EQNCalibrazione.m */; };
8CF66053214C12DC009F4314 /* EQNMath.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF66052214C12DC009F4314 /* EQNMath.m */; };
8CF66058214C566B009F4314 /* ServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF66055214C566A009F4314 /* ServerRequest.m */; };
8CF66059214C566B009F4314 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF66056214C566A009F4314 /* Reachability.m */; };
8CFA6323219A2C610099EB0E /* Tsunami.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CFA6322219A2C610099EB0E /* Tsunami.m */; };
C89115902FEA7A0A31514912 /* Pods_Earthquake_Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25A8BFFE29D46740E8A8A7A3 /* Pods_Earthquake_Network.framework */; };
DC03BEAB250BC0A60084769B /* EQNRoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC03BEAA250BC0A60084769B /* EQNRoundedButton.swift */; };
DC08803F24F5A89000186D97 /* SettingEnableTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC08803E24F5A89000186D97 /* SettingEnableTableViewCell.swift */; };
DC08804124F5B41400186D97 /* SettingSliderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC08804024F5B41400186D97 /* SettingSliderTableViewCell.swift */; };
DC0E551324F8063300D54270 /* SettingSegmentedTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0E551224F8063300D54270 /* SettingSegmentedTableViewCell.swift */; };
DC11ABE824E6700E00D866A8 /* UIColor+EQN.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC11ABE724E6700E00D866A8 /* UIColor+EQN.swift */; };
DC105641251E7ECE002579BB /* UIFont+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC105640251E7ECE002579BB /* UIFont+Extensions.swift */; };
DC27EB2F24F6EBE000ACBFE0 /* SettingsSeismicNetworksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC27EB2E24F6EBE000ACBFE0 /* SettingsSeismicNetworksViewController.swift */; };
DC2814302519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC28142F2519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift */; };
DC2814382519C56100C1AFF7 /* SeismicNetworksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2814372519C56100C1AFF7 /* SeismicNetworksViewController.swift */; };
DC3ADD3924CB2F3D00737919 /* alert_star_trek.wav in Resources */ = {isa = PBXBuildFile; fileRef = 8CF12CC721DE43A400613AC5 /* alert_star_trek.wav */; };
DC3BA11124D1A9C90062EE7F /* SubscriptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3BA11024D1A9C90062EE7F /* SubscriptionsViewController.swift */; };
DC3CE50A250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3CE509250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift */; };
DC4B67612517833F00634277 /* EQNSeismic.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4B67602517833F00634277 /* EQNSeismic.swift */; };
DC52B8A224FC145500ABEBA6 /* SettingsBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52B8A124FC145500ABEBA6 /* SettingsBaseViewController.m */; };
DC52B8A524FCCD6900ABEBA6 /* AppTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC52B8A424FCCD6900ABEBA6 /* AppTheme.swift */; };
DC65B391250F243E00251693 /* SeismicSettingsNetworksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC65B390250F243E00251693 /* SeismicSettingsNetworksViewController.swift */; };
DC886A5D24E92D5500F7A5D3 /* EQNBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DC886A5C24E92D5500F7A5D3 /* EQNBaseViewController.m */; };
DC974AFF251748B300A139EC /* SeismicFiltersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC974AFE251748B300A139EC /* SeismicFiltersViewController.swift */; };
DC99A50324E66E270071BC9F /* EQNCommandProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC99A50224E66E270071BC9F /* EQNCommandProtocol.swift */; };
DC99A50524E66E430071BC9F /* EQNAppearanceCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC99A50424E66E430071BC9F /* EQNAppearanceCommand.swift */; };
DC99A50724E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC99A50624E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift */; };
DCAA913F24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAA913E24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift */; };
DCB28CEE24FB8400001F557E /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB28CED24FB8400001F557E /* SettingsViewController.swift */; };
DCB45BC8250E86E100DB2D0C /* SeismicSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB45BC7250E86E100DB2D0C /* SeismicSettingsViewController.swift */; };
DCB6FBEC24D0B40600ED23B8 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DCB6FBEB24D0B40600ED23B8 /* Colors.xcassets */; };
DCBB267A24D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBB267924D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift */; };
DCBB267C24D1E98300F04559 /* EQNBaseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBB267B24D1E98300F04559 /* EQNBaseTableViewCell.swift */; };
@@ -123,8 +112,11 @@
DCBB268024D1ECE200F04559 /* SubscriptionDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBB267F24D1ECE200F04559 /* SubscriptionDetailViewController.swift */; };
DCC23DEC24D281CE003A2404 /* SubscriptionsActiveTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC23DEB24D281CE003A2404 /* SubscriptionsActiveTableViewCell.swift */; };
DCC23DEF24D28F58003A2404 /* EQNEdgeInsetLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC23DEE24D28F58003A2404 /* EQNEdgeInsetLabel.swift */; };
DCC76BD8251F56050005C4DC /* SeismicCardSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC76BD7251F56050005C4DC /* SeismicCardSettingsViewController.swift */; };
DCC76BE4251F69FB0005C4DC /* EQNUserDefaultsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC76BE3251F69FB0005C4DC /* EQNUserDefaultsCommand.swift */; };
DCD3E3C024D15576007C78D4 /* PurchaseProVersionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCD3E3BF24D15576007C78D4 /* PurchaseProVersionViewController.swift */; };
DCD4571C24F6CF0D00B58304 /* EQNGenericValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCD4571B24F6CF0D00B58304 /* EQNGenericValue.swift */; };
DCDAB31925188BB3001AE40D /* EQNAllertaSismica.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113621EE502800A59729 /* EQNAllertaSismica.m */; };
DCDE0BD924E58CCE00209778 /* EQNMainTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDE0BD824E58CCE00209778 /* EQNMainTabBarController.m */; };
DCEFF21324F5821E009D3FE1 /* SettingDetailTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCEFF21224F5821E009D3FE1 /* SettingDetailTableViewCell.swift */; };
DCEFF21724F58569009D3FE1 /* SettingSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCEFF21624F58569009D3FE1 /* SettingSectionHeaderView.swift */; };
@@ -181,10 +173,6 @@
8C10B0BE2281FE9E00125C9F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
8C10B0BF2281FEA000125C9F /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
8C10B0C42282360900125C9F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8C13E849220B2E7E0009CFE4 /* MenuSelezioneEntiViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MenuSelezioneEntiViewController.h; sourceTree = "<group>"; };
8C13E84A220B2E7E0009CFE4 /* MenuSelezioneEntiViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MenuSelezioneEntiViewController.m; sourceTree = "<group>"; };
8C13E84D220B89360009CFE4 /* ElencoFiltroEntiTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ElencoFiltroEntiTableViewController.h; sourceTree = "<group>"; };
8C13E84E220B89360009CFE4 /* ElencoFiltroEntiTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ElencoFiltroEntiTableViewController.m; sourceTree = "<group>"; };
8C14112F21ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SettingsRealTimeAlertsViewController.h; sourceTree = "<group>"; };
8C14113021ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SettingsRealTimeAlertsViewController.m; sourceTree = "<group>"; };
8C14113521EE502800A59729 /* EQNAllertaSismica.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNAllertaSismica.h; sourceTree = "<group>"; };
@@ -231,20 +219,12 @@
8C7A3B65225A5EA40045B266 /* NSDictionary+BVJSONString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+BVJSONString.h"; sourceTree = "<group>"; };
8C8EBBA521540039002784BA /* EQNUser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNUser.h; sourceTree = "<group>"; };
8C8EBBA621540039002784BA /* EQNUser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNUser.m; sourceTree = "<group>"; };
8C9B755A2233A25100F8FDEE /* MenuFiltroEntiViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MenuFiltroEntiViewController.h; sourceTree = "<group>"; };
8C9B755B2233A25100F8FDEE /* MenuFiltroEntiViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MenuFiltroEntiViewController.m; sourceTree = "<group>"; };
8C9B755D2233BFDE00F8FDEE /* FiltroEnti.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FiltroEnti.h; sourceTree = "<group>"; };
8C9B755E2233BFDE00F8FDEE /* FiltroEnti.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FiltroEnti.m; sourceTree = "<group>"; };
8CA46B9F2194532E00C63C16 /* SismaAnnotation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SismaAnnotation.h; sourceTree = "<group>"; };
8CA46BA02194532E00C63C16 /* SismaAnnotation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SismaAnnotation.m; sourceTree = "<group>"; };
8CABD71F2194B7C700C3E09C /* ImpostazioniViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImpostazioniViewController.h; sourceTree = "<group>"; };
8CABD7202194B7C700C3E09C /* ImpostazioniViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImpostazioniViewController.m; sourceTree = "<group>"; };
8CADAA9221B2627D0044E256 /* LogViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogViewController.h; sourceTree = "<group>"; };
8CADAA9321B2627D0044E256 /* LogViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LogViewController.m; sourceTree = "<group>"; };
8CAFD7C321825E4A00F8BD29 /* EQNSisma.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNSisma.h; sourceTree = "<group>"; };
8CAFD7C421825E4A00F8BD29 /* EQNSisma.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNSisma.m; sourceTree = "<group>"; };
8CAFD7C62182648600F8BD29 /* EQNRetiSismiViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNRetiSismiViewController.h; sourceTree = "<group>"; };
8CAFD7C72182648600F8BD29 /* EQNRetiSismiViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNRetiSismiViewController.m; sourceTree = "<group>"; };
8CBD3DC22149B9AD0070C963 /* Earthquake Network.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Earthquake Network.app"; sourceTree = BUILT_PRODUCTS_DIR; };
8CBD3DC52149B9AD0070C963 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
8CBD3DC62149B9AD0070C963 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -258,34 +238,19 @@
8CC1B158217CB09100F22178 /* DettagliMappaViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DettagliMappaViewController.h; sourceTree = "<group>"; };
8CC1B159217CB09100F22178 /* DettagliMappaViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DettagliMappaViewController.m; sourceTree = "<group>"; };
8CC2B44E214AC7F8002ED1B2 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
8CCE164221E67F1300173CD9 /* EQNImpostazioniNotifiche.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNImpostazioniNotifiche.h; sourceTree = "<group>"; };
8CCE164321E67F1300173CD9 /* EQNImpostazioniNotifiche.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNImpostazioniNotifiche.m; sourceTree = "<group>"; };
8CCE164921E7BAB200173CD9 /* EQNNotificheTempoReale.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNNotificheTempoReale.h; sourceTree = "<group>"; };
8CCE164A21E7BAB200173CD9 /* EQNNotificheTempoReale.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNNotificheTempoReale.m; sourceTree = "<group>"; };
8CCE164C21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNNotificheSegnalazioniUtente.h; sourceTree = "<group>"; };
8CCE164D21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNNotificheSegnalazioniUtente.m; sourceTree = "<group>"; };
8CCE164F21E7BAEC00173CD9 /* EQNNotificeReteSismiche.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNNotificeReteSismiche.h; sourceTree = "<group>"; };
8CCE165021E7BAEC00173CD9 /* EQNNotificeReteSismiche.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNNotificeReteSismiche.m; sourceTree = "<group>"; };
8CCE164F21E7BAEC00173CD9 /* EQNNotificheReteSismiche.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNNotificheReteSismiche.h; sourceTree = "<group>"; };
8CCE165021E7BAEC00173CD9 /* EQNNotificheReteSismiche.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNNotificheReteSismiche.m; sourceTree = "<group>"; };
8CCE165321EA378800173CD9 /* SettingsUserReportAlertsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SettingsUserReportAlertsViewController.h; sourceTree = "<group>"; };
8CCE165421EA378800173CD9 /* SettingsUserReportAlertsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SettingsUserReportAlertsViewController.m; sourceTree = "<group>"; };
8CCE165621EB1E0000173CD9 /* SettingsSeismicNetworkAlertsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SettingsSeismicNetworkAlertsViewController.h; sourceTree = "<group>"; };
8CCE165721EB1E0000173CD9 /* SettingsSeismicNetworkAlertsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SettingsSeismicNetworkAlertsViewController.m; sourceTree = "<group>"; };
8CCE165F21EBA37500173CD9 /* EQNNotificheTsunami.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNNotificheTsunami.h; sourceTree = "<group>"; };
8CCE166021EBA37500173CD9 /* EQNNotificheTsunami.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNNotificheTsunami.m; sourceTree = "<group>"; };
8CD0862C218A41930000CB5E /* CellDettagliMappaTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CellDettagliMappaTableViewCell.h; sourceTree = "<group>"; };
8CD0862D218A41930000CB5E /* CellDettagliMappaTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CellDettagliMappaTableViewCell.m; sourceTree = "<group>"; };
8CD0862F218ADFCA0000CB5E /* Cell_Reti_sismicheTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Cell_Reti_sismicheTableViewCell.h; sourceTree = "<group>"; };
8CD08630218ADFCA0000CB5E /* Cell_Reti_sismicheTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Cell_Reti_sismicheTableViewCell.m; sourceTree = "<group>"; };
8CD08633218AF6030000CB5E /* Cell_Meteo_TableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Cell_Meteo_TableViewCell.h; sourceTree = "<group>"; };
8CD08634218AF6030000CB5E /* Cell_Meteo_TableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Cell_Meteo_TableViewCell.m; sourceTree = "<group>"; };
8CD08636218B3BEE0000CB5E /* ReteSismicaAnnotation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReteSismicaAnnotation.h; sourceTree = "<group>"; };
8CD08637218B3BEE0000CB5E /* ReteSismicaAnnotation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReteSismicaAnnotation.m; sourceTree = "<group>"; };
8CF05B4B218C41F90055012B /* PickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PickerViewController.m; sourceTree = "<group>"; };
8CF05B4C218C41F90055012B /* TBDInputViewControllerData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBDInputViewControllerData.h; sourceTree = "<group>"; };
8CF05B4D218C41FA0055012B /* PickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PickerViewController.h; sourceTree = "<group>"; };
8CF05B4E218C41FA0055012B /* TBDInputViewControllerData.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TBDInputViewControllerData.xib; sourceTree = "<group>"; };
8CF05B4F218C41FA0055012B /* PickerViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PickerViewController.xib; sourceTree = "<group>"; };
8CF05B50218C41FB0055012B /* TBDInputViewControllerData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBDInputViewControllerData.m; sourceTree = "<group>"; };
8CF05B55218C93BA0055012B /* EQNUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNUtility.h; sourceTree = "<group>"; };
8CF05B56218C93BA0055012B /* EQNUtility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNUtility.m; sourceTree = "<group>"; };
8CF12CC721DE43A400613AC5 /* alert_star_trek.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = alert_star_trek.wav; sourceTree = "<group>"; };
@@ -304,8 +269,6 @@
8CF4F4D7216D3A110057110B /* EQNAreaCheck.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNAreaCheck.m; sourceTree = "<group>"; };
8CF4F4D9216D44930057110B /* EQNPastquakes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNPastquakes.h; sourceTree = "<group>"; };
8CF4F4DA216D44930057110B /* EQNPastquakes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNPastquakes.m; sourceTree = "<group>"; };
8CF4F4DC2175352E0057110B /* WaitViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WaitViewController.h; sourceTree = "<group>"; };
8CF4F4DD2175352E0057110B /* WaitViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WaitViewController.m; sourceTree = "<group>"; };
8CF6604D214C0E58009F4314 /* EQNCalibrazione.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNCalibrazione.h; sourceTree = "<group>"; };
8CF6604E214C0E58009F4314 /* EQNCalibrazione.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNCalibrazione.m; sourceTree = "<group>"; };
8CF66050214C0F7F009F4314 /* Costanti.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Costanti.h; sourceTree = "<group>"; };
@@ -315,26 +278,32 @@
8CF66055214C566A009F4314 /* ServerRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ServerRequest.m; sourceTree = "<group>"; };
8CF66056214C566A009F4314 /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = "<group>"; };
8CF66057214C566B009F4314 /* ServerRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServerRequest.h; sourceTree = "<group>"; };
8CFA6321219A2C610099EB0E /* Tsunami.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Tsunami.h; sourceTree = "<group>"; };
8CFA6322219A2C610099EB0E /* Tsunami.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tsunami.m; sourceTree = "<group>"; };
C4FB0D7EEA34F8222369E1BB /* Pods-Earthquake Network.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Earthquake Network.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Earthquake Network/Pods-Earthquake Network.debug.xcconfig"; sourceTree = "<group>"; };
DC03BEAA250BC0A60084769B /* EQNRoundedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNRoundedButton.swift; sourceTree = "<group>"; };
DC08803E24F5A89000186D97 /* SettingEnableTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingEnableTableViewCell.swift; sourceTree = "<group>"; };
DC08804024F5B41400186D97 /* SettingSliderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingSliderTableViewCell.swift; sourceTree = "<group>"; };
DC0E551224F8063300D54270 /* SettingSegmentedTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingSegmentedTableViewCell.swift; sourceTree = "<group>"; };
DC11ABE724E6700E00D866A8 /* UIColor+EQN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+EQN.swift"; sourceTree = "<group>"; };
DC105640251E7ECE002579BB /* UIFont+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Extensions.swift"; sourceTree = "<group>"; };
DC27EB2E24F6EBE000ACBFE0 /* SettingsSeismicNetworksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSeismicNetworksViewController.swift; sourceTree = "<group>"; };
DC28142F2519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworkTableViewCell.swift; sourceTree = "<group>"; };
DC2814372519C56100C1AFF7 /* SeismicNetworksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworksViewController.swift; sourceTree = "<group>"; };
DC3BA11024D1A9C90062EE7F /* SubscriptionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsViewController.swift; sourceTree = "<group>"; };
DC3CE509250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNGenericPickerViewController.swift; sourceTree = "<group>"; };
DC414C0024CDA09A008D9AE4 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = "<group>"; };
DC4B67602517833F00634277 /* EQNSeismic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNSeismic.swift; sourceTree = "<group>"; };
DC52B8A024FC145500ABEBA6 /* SettingsBaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SettingsBaseViewController.h; sourceTree = "<group>"; };
DC52B8A124FC145500ABEBA6 /* SettingsBaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SettingsBaseViewController.m; sourceTree = "<group>"; };
DC52B8A424FCCD6900ABEBA6 /* AppTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTheme.swift; sourceTree = "<group>"; };
DC65B390250F243E00251693 /* SeismicSettingsNetworksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicSettingsNetworksViewController.swift; sourceTree = "<group>"; };
DC886A5B24E92D5500F7A5D3 /* EQNBaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNBaseViewController.h; sourceTree = "<group>"; };
DC886A5C24E92D5500F7A5D3 /* EQNBaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNBaseViewController.m; sourceTree = "<group>"; };
DC974AFE251748B300A139EC /* SeismicFiltersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicFiltersViewController.swift; sourceTree = "<group>"; };
DC99A50224E66E270071BC9F /* EQNCommandProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNCommandProtocol.swift; sourceTree = "<group>"; };
DC99A50424E66E430071BC9F /* EQNAppearanceCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNAppearanceCommand.swift; sourceTree = "<group>"; };
DC99A50624E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNStartupCommandsBuilder.swift; sourceTree = "<group>"; };
DCAA913E24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingMultivaluesTableViewCell.swift; sourceTree = "<group>"; };
DCB28CED24FB8400001F557E /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
DCB45BC7250E86E100DB2D0C /* SeismicSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicSettingsViewController.swift; sourceTree = "<group>"; };
DCB6FBEB24D0B40600ED23B8 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
DCBB267924D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsHeaderTableViewCell.swift; sourceTree = "<group>"; };
DCBB267B24D1E98300F04559 /* EQNBaseTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNBaseTableViewCell.swift; sourceTree = "<group>"; };
@@ -342,6 +311,8 @@
DCBB267F24D1ECE200F04559 /* SubscriptionDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionDetailViewController.swift; sourceTree = "<group>"; };
DCC23DEB24D281CE003A2404 /* SubscriptionsActiveTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsActiveTableViewCell.swift; sourceTree = "<group>"; };
DCC23DEE24D28F58003A2404 /* EQNEdgeInsetLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNEdgeInsetLabel.swift; sourceTree = "<group>"; };
DCC76BD7251F56050005C4DC /* SeismicCardSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicCardSettingsViewController.swift; sourceTree = "<group>"; };
DCC76BE3251F69FB0005C4DC /* EQNUserDefaultsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNUserDefaultsCommand.swift; sourceTree = "<group>"; };
DCD3E3BF24D15576007C78D4 /* PurchaseProVersionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseProVersionViewController.swift; sourceTree = "<group>"; };
DCD4571B24F6CF0D00B58304 /* EQNGenericValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNGenericValue.swift; sourceTree = "<group>"; };
DCDE0BD724E58CCE00209778 /* EQNMainTabBarController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNMainTabBarController.h; sourceTree = "<group>"; };
@@ -362,8 +333,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8C483C9B21FA665C00259FD2 /* EQNAllertaSismica.h in Frameworks */,
8C483C9C21FA665C00259FD2 /* EQNAllertaSismica.m in Frameworks */,
8C483C9721FA662900259FD2 /* alert_star_trek.wav in Frameworks */,
8C465D9B21F653CA00F04673 /* Assets.xcassets in Frameworks */,
);
@@ -420,25 +389,12 @@
children = (
8C602247218D9DBF00C799C2 /* Dettagli mappa */,
8CF05B4A218C41E60055012B /* inputView */,
8CD08632218AF5C80000CB5E /* cellTableView */,
8CBD3DC82149B9AD0070C963 /* ReteSmartphone.h */,
8CBD3DC92149B9AD0070C963 /* ReteSmartphone.m */,
8CF4F4DC2175352E0057110B /* WaitViewController.h */,
8CF4F4DD2175352E0057110B /* WaitViewController.m */,
8C5EA23B2177B51C002DC156 /* SegnalazioniViewController.h */,
8C5EA23C2177B51C002DC156 /* SegnalazioniViewController.m */,
8CAFD7C62182648600F8BD29 /* EQNRetiSismiViewController.h */,
8CAFD7C72182648600F8BD29 /* EQNRetiSismiViewController.m */,
8CABD71F2194B7C700C3E09C /* ImpostazioniViewController.h */,
8CABD7202194B7C700C3E09C /* ImpostazioniViewController.m */,
8CADAA9221B2627D0044E256 /* LogViewController.h */,
8CADAA9321B2627D0044E256 /* LogViewController.m */,
8C13E849220B2E7E0009CFE4 /* MenuSelezioneEntiViewController.h */,
8C13E84A220B2E7E0009CFE4 /* MenuSelezioneEntiViewController.m */,
8C13E84D220B89360009CFE4 /* ElencoFiltroEntiTableViewController.h */,
8C13E84E220B89360009CFE4 /* ElencoFiltroEntiTableViewController.m */,
8C9B755A2233A25100F8FDEE /* MenuFiltroEntiViewController.h */,
8C9B755B2233A25100F8FDEE /* MenuFiltroEntiViewController.m */,
);
path = ViewController;
sourceTree = "<group>";
@@ -452,8 +408,6 @@
8C602245218D9DB200C799C2 /* PastquakesDettagliMappa.m */,
8C2B250F21938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.h */,
8C2B251021938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m */,
8C2B25122193927E00E0E25E /* ReteSismiDettagliMappa.h */,
8C2B25132193927E00E0E25E /* ReteSismiDettagliMappa.m */,
);
path = "Dettagli mappa";
sourceTree = "<group>";
@@ -530,47 +484,12 @@
name = Frameworks;
sourceTree = "<group>";
};
8CCE165221EA370200173CD9 /* impostazioni notifiche */ = {
isa = PBXGroup;
children = (
8CCE164221E67F1300173CD9 /* EQNImpostazioniNotifiche.h */,
8CCE164321E67F1300173CD9 /* EQNImpostazioniNotifiche.m */,
8CCE164921E7BAB200173CD9 /* EQNNotificheTempoReale.h */,
8CCE164A21E7BAB200173CD9 /* EQNNotificheTempoReale.m */,
8CCE164C21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.h */,
8CCE164D21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.m */,
8CCE164F21E7BAEC00173CD9 /* EQNNotificeReteSismiche.h */,
8CCE165021E7BAEC00173CD9 /* EQNNotificeReteSismiche.m */,
8CCE165F21EBA37500173CD9 /* EQNNotificheTsunami.h */,
8CCE166021EBA37500173CD9 /* EQNNotificheTsunami.m */,
8C14113521EE502800A59729 /* EQNAllertaSismica.h */,
8C14113621EE502800A59729 /* EQNAllertaSismica.m */,
);
path = "impostazioni notifiche";
sourceTree = "<group>";
};
8CD08632218AF5C80000CB5E /* cellTableView */ = {
isa = PBXGroup;
children = (
8CD0862F218ADFCA0000CB5E /* Cell_Reti_sismicheTableViewCell.h */,
8CD08630218ADFCA0000CB5E /* Cell_Reti_sismicheTableViewCell.m */,
8CD0862C218A41930000CB5E /* CellDettagliMappaTableViewCell.h */,
8CD0862D218A41930000CB5E /* CellDettagliMappaTableViewCell.m */,
8CD08633218AF6030000CB5E /* Cell_Meteo_TableViewCell.h */,
8CD08634218AF6030000CB5E /* Cell_Meteo_TableViewCell.m */,
);
path = cellTableView;
sourceTree = "<group>";
};
8CF05B4A218C41E60055012B /* inputView */ = {
isa = PBXGroup;
children = (
8CF05B4D218C41FA0055012B /* PickerViewController.h */,
8CF05B4B218C41F90055012B /* PickerViewController.m */,
8CF05B4F218C41FA0055012B /* PickerViewController.xib */,
8CF05B4C218C41F90055012B /* TBDInputViewControllerData.h */,
8CF05B50218C41FB0055012B /* TBDInputViewControllerData.m */,
8CF05B4E218C41FA0055012B /* TBDInputViewControllerData.xib */,
);
path = inputView;
sourceTree = "<group>";
@@ -590,7 +509,6 @@
8CF66049214C09E0009F4314 /* model */ = {
isa = PBXGroup;
children = (
8CCE165221EA370200173CD9 /* impostazioni notifiche */,
8C60224B218EDBF700C799C2 /* annotation */,
8C8EBBA521540039002784BA /* EQNUser.h */,
8C8EBBA621540039002784BA /* EQNUser.m */,
@@ -616,14 +534,8 @@
8CF4F4DA216D44930057110B /* EQNPastquakes.m */,
8C593E88217BA2470008B260 /* EQNSegnalazione.h */,
8C593E89217BA2470008B260 /* EQNSegnalazione.m */,
8CAFD7C321825E4A00F8BD29 /* EQNSisma.h */,
8CAFD7C421825E4A00F8BD29 /* EQNSisma.m */,
8CF05B55218C93BA0055012B /* EQNUtility.h */,
8CF05B56218C93BA0055012B /* EQNUtility.m */,
8CFA6321219A2C610099EB0E /* Tsunami.h */,
8CFA6322219A2C610099EB0E /* Tsunami.m */,
8C9B755D2233BFDE00F8FDEE /* FiltroEnti.h */,
8C9B755E2233BFDE00F8FDEE /* FiltroEnti.m */,
);
path = model;
sourceTree = "<group>";
@@ -637,14 +549,37 @@
name = Pods;
sourceTree = "<group>";
};
DC11ABE924E6707900D866A8 /* Extensions */ = {
DC10563F251E7EC0002579BB /* Extensions */ = {
isa = PBXGroup;
children = (
DC11ABE724E6700E00D866A8 /* UIColor+EQN.swift */,
DC105640251E7ECE002579BB /* UIFont+Extensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
DC141968250E769B0059E060 /* Seismic Networks */ = {
isa = PBXGroup;
children = (
DC28142E2519C21400C1AFF7 /* Cells */,
DC974AFE251748B300A139EC /* SeismicFiltersViewController.swift */,
DCB45BC7250E86E100DB2D0C /* SeismicSettingsViewController.swift */,
DC65B390250F243E00251693 /* SeismicSettingsNetworksViewController.swift */,
DC2814372519C56100C1AFF7 /* SeismicNetworksViewController.swift */,
DCC76BD7251F56050005C4DC /* SeismicCardSettingsViewController.swift */,
8C2B25122193927E00E0E25E /* ReteSismiDettagliMappa.h */,
8C2B25132193927E00E0E25E /* ReteSismiDettagliMappa.m */,
);
path = "Seismic Networks";
sourceTree = "<group>";
};
DC28142E2519C21400C1AFF7 /* Cells */ = {
isa = PBXGroup;
children = (
DC28142F2519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift */,
);
path = Cells;
sourceTree = "<group>";
};
DC3ADD2A24CB1E6600737919 /* Supporting Files */ = {
isa = PBXGroup;
children = (
@@ -683,6 +618,7 @@
DC3ADD2F24CB1EFB00737919 /* Libs */ = {
isa = PBXGroup;
children = (
DC10563F251E7EC0002579BB /* Extensions */,
8CF66054214C566A009F4314 /* Reachability.h */,
8CF66056214C566A009F4314 /* Reachability.m */,
8C7A3B65225A5EA40045B266 /* NSDictionary+BVJSONString.h */,
@@ -699,12 +635,21 @@
path = Storyboards;
sourceTree = "<group>";
};
DC3CE508250EB78C005A7DD5 /* Shared */ = {
isa = PBXGroup;
children = (
DC3CE509250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift */,
);
path = Shared;
sourceTree = "<group>";
};
DC99A50124E66DFB0071BC9F /* Commands */ = {
isa = PBXGroup;
children = (
DC99A50224E66E270071BC9F /* EQNCommandProtocol.swift */,
DC99A50624E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift */,
DC99A50424E66E430071BC9F /* EQNAppearanceCommand.swift */,
DCC76BE3251F69FB0005C4DC /* EQNUserDefaultsCommand.swift */,
);
path = Commands;
sourceTree = "<group>";
@@ -713,7 +658,6 @@
isa = PBXGroup;
children = (
DCF9E15024F6EA0B002B6B1D /* Networks */,
DC11ABE924E6707900D866A8 /* Extensions */,
DC99A50124E66DFB0071BC9F /* Commands */,
DCEFF21824F587CC009D3FE1 /* Settings */,
8C483CBB21FDACE500259FD2 /* VersioneProProducts.swift */,
@@ -722,6 +666,9 @@
DCF10DCC24D2C935009F34C3 /* EQNPurchaseAvailability.swift */,
DCD4571B24F6CF0D00B58304 /* EQNGenericValue.swift */,
DCF9E14C24F6D1AA002B6B1D /* EQNData.swift */,
DC4B67602517833F00634277 /* EQNSeismic.swift */,
8CAFD7C321825E4A00F8BD29 /* EQNSisma.h */,
8CAFD7C421825E4A00F8BD29 /* EQNSisma.m */,
);
path = Models;
sourceTree = "<group>";
@@ -733,8 +680,10 @@
DCDE0BD824E58CCE00209778 /* EQNMainTabBarController.m */,
DC886A5B24E92D5500F7A5D3 /* EQNBaseViewController.h */,
DC886A5C24E92D5500F7A5D3 /* EQNBaseViewController.m */,
DC3CE508250EB78C005A7DD5 /* Shared */,
DCD3E3BE24D1555F007C78D4 /* InApp */,
DCEFF21024F57163009D3FE1 /* Settings */,
DC141968250E769B0059E060 /* Seismic Networks */,
);
path = Controllers;
sourceTree = "<group>";
@@ -743,6 +692,7 @@
isa = PBXGroup;
children = (
DCC23DEE24D28F58003A2404 /* EQNEdgeInsetLabel.swift */,
DC03BEAA250BC0A60084769B /* EQNRoundedButton.swift */,
DC52B8A424FCCD6900ABEBA6 /* AppTheme.swift */,
);
path = UI;
@@ -798,6 +748,12 @@
isa = PBXGroup;
children = (
DCEFF21924F587E3009D3FE1 /* SettingItem.swift */,
8CCE164C21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.h */,
8CCE164D21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.m */,
8CCE164F21E7BAEC00173CD9 /* EQNNotificheReteSismiche.h */,
8CCE165021E7BAEC00173CD9 /* EQNNotificheReteSismiche.m */,
8C14113521EE502800A59729 /* EQNAllertaSismica.h */,
8C14113621EE502800A59729 /* EQNAllertaSismica.m */,
);
path = Settings;
sourceTree = "<group>";
@@ -877,7 +833,7 @@
8CBD3DBA2149B9AD0070C963 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1010;
LastUpgradeCheck = 1200;
ORGANIZATIONNAME = "Earthquake Network";
TargetAttributes = {
8C4B0B7921CACE3F00AED489 = {
@@ -953,7 +909,6 @@
buildActionMask = 2147483647;
files = (
8C4DD4F9228237E000AE77ED /* InfoPlist.strings in Resources */,
8CF05B52218C41FB0055012B /* TBDInputViewControllerData.xib in Resources */,
8CF12CCA21DE43A500613AC5 /* alert_star_trek.wav in Resources */,
8C483CA921FBC1E900259FD2 /* alerta_mexico.m4r in Resources */,
8CBD3DD52149B9AD0070C963 /* LaunchScreen.storyboard in Resources */,
@@ -988,6 +943,7 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Earthquake Network/Pods-Earthquake Network-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework",
"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework",
"${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework",
"${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework",
@@ -995,6 +951,7 @@
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DZNEmptyDataSet.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework",
@@ -1069,7 +1026,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8C483C9A21FA664000259FD2 /* EQNAllertaSismica.m in Sources */,
DCDAB31925188BB3001AE40D /* EQNAllertaSismica.m in Sources */,
8C4B0B7E21CACE3F00AED489 /* NotificationService.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1079,26 +1036,25 @@
buildActionMask = 2147483647;
files = (
DCEFF21324F5821E009D3FE1 /* SettingDetailTableViewCell.swift in Sources */,
8CF05B54218C41FB0055012B /* TBDInputViewControllerData.m in Sources */,
8CCE166121EBA37500173CD9 /* EQNNotificheTsunami.m in Sources */,
DCC23DEF24D28F58003A2404 /* EQNEdgeInsetLabel.swift in Sources */,
8CCE165121E7BAEC00173CD9 /* EQNNotificeReteSismiche.m in Sources */,
8C13E84B220B2E7E0009CFE4 /* MenuSelezioneEntiViewController.m in Sources */,
8CCE165121E7BAEC00173CD9 /* EQNNotificheReteSismiche.m in Sources */,
DC52B8A224FC145500ABEBA6 /* SettingsBaseViewController.m in Sources */,
DC2814382519C56100C1AFF7 /* SeismicNetworksViewController.swift in Sources */,
8CF4F4DB216D44930057110B /* EQNPastquakes.m in Sources */,
8CCE165821EB1E0000173CD9 /* SettingsSeismicNetworkAlertsViewController.m in Sources */,
8CCE165521EA378800173CD9 /* SettingsUserReportAlertsViewController.m in Sources */,
DCBB268024D1ECE200F04559 /* SubscriptionDetailViewController.swift in Sources */,
DCC76BE4251F69FB0005C4DC /* EQNUserDefaultsCommand.swift in Sources */,
DC4B67612517833F00634277 /* EQNSeismic.swift in Sources */,
DCBB267E24D1EA2000F04559 /* SubscriptionProductTableViewCell.swift in Sources */,
8CFA6323219A2C610099EB0E /* Tsunami.m in Sources */,
DC99A50524E66E430071BC9F /* EQNAppearanceCommand.swift in Sources */,
DC03BEAB250BC0A60084769B /* EQNRoundedButton.swift in Sources */,
8CCE164E21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.m in Sources */,
DCD4571C24F6CF0D00B58304 /* EQNGenericValue.swift in Sources */,
8C4E343F215012FA008B0D2A /* EQNManager.m in Sources */,
8CABD7212194B7C700C3E09C /* ImpostazioniViewController.m in Sources */,
DCAA913F24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift in Sources */,
DCF9E14F24F6EA07002B6B1D /* EQNSeismicNetwork.swift in Sources */,
8CCE164421E67F1300173CD9 /* EQNImpostazioniNotifiche.m in Sources */,
DC2814302519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift in Sources */,
8C14113721EE502800A59729 /* EQNAllertaSismica.m in Sources */,
8C483CBC21FDACE500259FD2 /* VersioneProProducts.swift in Sources */,
8C483CB821FDACD300259FD2 /* IAPHelper.swift in Sources */,
@@ -1108,9 +1064,7 @@
8CF4F4D5216D336B0057110B /* EQNDatoGrafico.m in Sources */,
8CF66058214C566B009F4314 /* ServerRequest.m in Sources */,
8CD08638218B3BEE0000CB5E /* ReteSismicaAnnotation.m in Sources */,
8CD0862E218A41930000CB5E /* CellDettagliMappaTableViewCell.m in Sources */,
DCF9E14D24F6D1AA002B6B1D /* EQNData.swift in Sources */,
8C9B755F2233BFDE00F8FDEE /* FiltroEnti.m in Sources */,
DC52B8A524FCCD6900ABEBA6 /* AppTheme.swift in Sources */,
DC27EB2F24F6EBE000ACBFE0 /* SettingsSeismicNetworksViewController.swift in Sources */,
8CF66059214C566B009F4314 /* Reachability.m in Sources */,
@@ -1119,7 +1073,6 @@
DCBB267C24D1E98300F04559 /* EQNBaseTableViewCell.swift in Sources */,
8CBD3DCA2149B9AD0070C963 /* ReteSmartphone.m in Sources */,
DCF10DCD24D2C935009F34C3 /* EQNPurchaseAvailability.swift in Sources */,
8C13E84F220B89360009CFE4 /* ElencoFiltroEntiTableViewController.m in Sources */,
DC08803F24F5A89000186D97 /* SettingEnableTableViewCell.swift in Sources */,
8CAFD7C521825E4A00F8BD29 /* EQNSisma.m in Sources */,
DCC23DEC24D281CE003A2404 /* SubscriptionsActiveTableViewCell.swift in Sources */,
@@ -1128,16 +1081,14 @@
8C2B25142193927E00E0E25E /* ReteSismiDettagliMappa.m in Sources */,
8CF05B51218C41FB0055012B /* PickerViewController.m in Sources */,
DC99A50324E66E270071BC9F /* EQNCommandProtocol.swift in Sources */,
8CF4F4DE2175352E0057110B /* WaitViewController.m in Sources */,
8CD08635218AF6030000CB5E /* Cell_Meteo_TableViewCell.m in Sources */,
8CD08631218ADFCA0000CB5E /* Cell_Reti_sismicheTableViewCell.m in Sources */,
DCB45BC8250E86E100DB2D0C /* SeismicSettingsViewController.swift in Sources */,
DCF10DC624D2B8C7009F34C3 /* EQNPurchaseUtility.swift in Sources */,
8C2B251121938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m in Sources */,
DC0E551324F8063300D54270 /* SettingSegmentedTableViewCell.swift in Sources */,
DCEFF21724F58569009D3FE1 /* SettingSectionHeaderView.swift in Sources */,
8C14113121ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m in Sources */,
8CCE164B21E7BAB200173CD9 /* EQNNotificheTempoReale.m in Sources */,
DCBB267A24D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift in Sources */,
DC65B391250F243E00251693 /* SeismicSettingsNetworksViewController.swift in Sources */,
8CF4F4D2216D2C780057110B /* EQNReteSmartphone.m in Sources */,
DC08804124F5B41400186D97 /* SettingSliderTableViewCell.swift in Sources */,
8CBD3DD82149B9AD0070C963 /* main.m in Sources */,
@@ -1151,16 +1102,17 @@
8C5EA23D2177B51C002DC156 /* SegnalazioniViewController.m in Sources */,
8CF4F4D8216D3A110057110B /* EQNAreaCheck.m in Sources */,
8C4E34452152B707008B0D2A /* EQMAccelerometroManager.m in Sources */,
8C9B755C2233A25100F8FDEE /* MenuFiltroEntiViewController.m in Sources */,
8CBD3DC72149B9AD0070C963 /* AppDelegate.m in Sources */,
DC974AFF251748B300A139EC /* SeismicFiltersViewController.swift in Sources */,
DC105641251E7ECE002579BB /* UIFont+Extensions.swift in Sources */,
8CA46BA12194532E00C63C16 /* SismaAnnotation.m in Sources */,
DCB28CEE24FB8400001F557E /* SettingsViewController.swift in Sources */,
DCC76BD8251F56050005C4DC /* SeismicCardSettingsViewController.swift in Sources */,
DC3CE50A250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift in Sources */,
8C602246218D9DB200C799C2 /* PastquakesDettagliMappa.m in Sources */,
8CAFD7C82182648600F8BD29 /* EQNRetiSismiViewController.m in Sources */,
DCEFF21A24F587E3009D3FE1 /* SettingItem.swift in Sources */,
8C8EBBA721540039002784BA /* EQNUser.m in Sources */,
8CADAA9421B2627D0044E256 /* LogViewController.m in Sources */,
DC11ABE824E6700E00D866A8 /* UIColor+EQN.swift in Sources */,
DC3BA11124D1A9C90062EE7F /* SubscriptionsViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1250,12 +1202,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 34;
DEVELOPMENT_TEAM = WJA4MR4CPC;
INFOPLIST_FILE = EQNNotificationService/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 2.2.1;
MARKETING_VERSION = 2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1272,12 +1224,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 34;
DEVELOPMENT_TEAM = WJA4MR4CPC;
INFOPLIST_FILE = EQNNotificationService/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 2.2.1;
MARKETING_VERSION = 2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1314,6 +1266,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -1372,6 +1325,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -1408,14 +1362,14 @@
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 34;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = WJA4MR4CPC;
GCC_PREFIX_HEADER = "Earthquake Network/Earthquake Network-Prefix.pch";
INFOPLIST_FILE = "Earthquake Network/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.2.1;
MARKETING_VERSION = 2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@@ -1436,13 +1390,13 @@
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 34;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = WJA4MR4CPC;
GCC_PREFIX_HEADER = "Earthquake Network/Earthquake Network-Prefix.pch";
INFOPLIST_FILE = "Earthquake Network/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.2.1;
MARKETING_VERSION = 2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@@ -1458,12 +1412,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 34;
DEVELOPMENT_TEAM = WJA4MR4CPC;
INFOPLIST_FILE = EQNNotificationContent/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 2.2.1;
MARKETING_VERSION = 2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationContent;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1480,12 +1434,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 34;
DEVELOPMENT_TEAM = WJA4MR4CPC;
INFOPLIST_FILE = EQNNotificationContent/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 2.2.1;
MARKETING_VERSION = 2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationContent;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1160"
LastUpgradeVersion = "1200"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1160"
LastUpgradeVersion = "1200"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1160"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
+18 -34
View File
@@ -8,6 +8,8 @@
#import "AppDelegate.h"
#import "Costanti.h"
#import "ServerRequest.h"
#import "EQNGeneratoreURLServer.h"
#import "EQNUser.h"
#import "EQMAccelerometroManager.h"
#import "EQNManager.h"
@@ -15,7 +17,7 @@
#import "EQNAllertaSismica.h"
#import "EQNAllertaSismica.h"
#import "EQNNotificheSegnalazioniUtente.h"
#import "EQNNotificeReteSismiche.h"
#import "EQNNotificheReteSismiche.h"
#import "EQNMainTabBarController.h"
@import GoogleMaps;
@@ -172,7 +174,7 @@ fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)(void))completionHandler {
// response.notification.request.content.sound = [UNNotificationSound soundNamed:[EQNAllertaSismica center].tonoAllarme];
// response.notification.request.content.sound = [UNNotificationSound soundNamed:[EQNAllertaSismica sharedInstance].tonoAllarme];
NSDictionary *userInfo = response.notification.request.content.userInfo;
EQNTabBarSection section = EQNTabBarSectionAllerte;
if ([userInfo[@"type"] isEqualToString:@"eqn"]) {
@@ -198,49 +200,31 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
completionHandler();
}
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
[self.mainTabBarController fetchNewDataWithCompletionHandler:^(UIBackgroundFetchResult result) {
completionHandler(result);
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSURL *url = [EQNGeneratoreURLServer urlPosizione];
[[ServerRequest defaultServerConnectionSingleton] inviaInformazioniAlServerWithURL:url richiesta:posizione success:^(id result) {
completionHandler(UIBackgroundFetchResultNewData);
} failure:^(NSError *error) {
completionHandler(UIBackgroundFetchResultFailed);
}];
}
#pragma mark - FIRMessagingDelegate
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
// Notify about received token.
// NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"];
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICA_TOKEN object:nil userInfo:dataDict];
NSLog(@"fcmToken %@", fcmToken);
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken
{
NSLog(@"[Firebase] fcmToken %@", fcmToken);
if (![[NSUserDefaults standardUserDefaults] objectForKey:TOKEN_USER]) {
[EQNAllertaSismica center].isAbilitato = YES;
[EQNAllertaSismica center].raggioSismiLievi = @"300";
[EQNAllertaSismica center].raggioSismiForti = @"600";
[EQNAllertaSismica center].sismiDaNotificare = @"0";
[[EQNAllertaSismica center] saveUserInfo];
[EQNNotificheSegnalazioniUtente center].isAbilitato = YES;
[EQNNotificheSegnalazioniUtente center].distanzaPosizione = @"300";
[[EQNNotificheSegnalazioniUtente center] saveUserInfo];
[EQNNotificeReteSismiche center].isAbilitato = YES;
[EQNNotificeReteSismiche center].distanzaPosizione = @"1000";
[EQNNotificeReteSismiche center].isAbilitaVicini = NO;
[EQNNotificeReteSismiche center].energiaSisma = @"3.5";
[EQNNotificeReteSismiche center].energiaTerremotiForti = @"7.5";
[[EQNNotificeReteSismiche center] saveUserInfo];
// save default values for notification settings
[EQNAllertaSismica saveDefaultValues];
[EQNNotificheSegnalazioniUtente saveDefaultValues];
[EQNNotificheReteSismiche saveDefaultValues];
}
[[NSUserDefaults standardUserDefaults] setObject:fcmToken forKey:TOKEN_USER];
[EQNUser defaultUser].tokenUser = fcmToken;
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
@@ -21,7 +21,6 @@ typedef NS_ENUM(NSInteger, EQNTabBarSection) {
@interface EQNMainTabBarController : UITabBarController
- (void)sincronizza;
- (void)fetchNewDataWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;
- (void)selectSection:(EQNTabBarSection)section;
@end
@@ -9,6 +9,7 @@
#import "EQNMainTabBarController.h"
#import "AppDelegate.h"
#import "EQNBaseViewController.h"
#import "SettingsBaseViewController.h"
#import "EQNUtility.h"
#import "EQNManager.h"
@@ -21,7 +22,6 @@
@implementation EQNMainTabBarController
static NSString * const SegueIdentifierInitialLoading = @"ShowInitialLoading";
static NSString * const SegueIdentifierSettings = @"ShowSettings";
static NSString * const SegueIdentifierLogs = @"ShowLogs";
@@ -48,11 +48,6 @@ static NSString * const SegueIdentifierLogs = @"ShowLogs";
// nope
}];
}
// show loader controller during initial data download
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:SegueIdentifierInitialLoading sender:self];
});
}
#pragma mark - Public
@@ -62,16 +57,6 @@ static NSString * const SegueIdentifierLogs = @"ShowLogs";
[[EQNManager defaultManager] sincronizza];
}
- (void)fetchNewDataWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSURL *url = [EQNGeneratoreURLServer urlPosizione];
[[ServerRequest defaultServerConnectionSingleton] inviaInformazioniAlServerWithURL:url richiesta:posizione success:^(id result) {
completionHandler(UIBackgroundFetchResultNewData);
} failure:^(NSError *error) {
completionHandler(UIBackgroundFetchResultFailed);
}];
}
- (void)selectSection:(EQNTabBarSection)section
{
NSInteger index = 0;
@@ -85,17 +70,6 @@ static NSString * const SegueIdentifierLogs = @"ShowLogs";
self.selectedIndex = index;
}
#pragma mark - Private
- (void)saveSettings
{
[[ServerRequest defaultServerConnectionSingleton] inviaInformazioniAlServerWithURL:[EQNGeneratoreURLServer urlInvioImpostazioniNotifiche] richiesta:impostazioniNotifiche success:^(id result){
NSLog(@"Settings saved successfully");
} failure:^(NSError *error){
NSLog(@"Settings saved failed. Error: %@", error.localizedDescription);
}];
}
#pragma mark - Helpers
- (UIViewController *)getTopControllerFromController:(UIViewController *)viewController
@@ -118,7 +92,7 @@ static NSString * const SegueIdentifierLogs = @"ShowLogs";
// if user switch from settings page, we need to force a settings save
UIViewController *controller = [self getTopControllerFromController:tabBarController.selectedViewController];
if ([controller isKindOfClass:[SettingsViewController class]]) {
[self saveSettings];
[SettingsBaseViewController saveSettings];
}
return YES;
@@ -142,7 +142,7 @@ class SubscriptionsViewController: UITableViewController {
}
private func checkDiscountPrice() -> Bool {
let downloaded = EQNManager.default().rete_smartphone?.subscriptionsDiscounted
let downloaded = EQNManager.manager().rete_smartphone?.subscriptionsDiscounted
return downloaded ?? false
}
@@ -0,0 +1,719 @@
//
// SeismicNetworkTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 22/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
import MapKit
import CoreLocation
protocol SeismicNetworkTableViewCellDelegate: class {
func seismicNetworkCellDidTapShare(_ cell: SeismicNetworkTableViewCell)
func seismicNetworkCellDidTapMap(_ cell: SeismicNetworkTableViewCell)
func seismicNetworkCellDidTapMapDetail(_ cell: SeismicNetworkTableViewCell)
func seismicNetworkCellDidTapWeather(_ cell: SeismicNetworkTableViewCell)
func seismicNetworkCellDidTapCalendar(_ cell: SeismicNetworkTableViewCell)
func seismicNetworkCellDidTapSettings(_ cell: SeismicNetworkTableViewCell)
func seismicNetworkCellDidTapClose(_ cell: SeismicNetworkTableViewCell)
}
class SeismicNetworkTableViewCell: UITableViewCell {
static let Identifier = "SeismicNetworkTableViewCell"
typealias MagnitudeColors = (textColor: UIColor, startColor: UIColor, endColor: UIColor)
/// Available informations to display inside the cell
enum InformationType: Int {
case preliminary
case time
case distance
case coordinate
case population
case realtimeSmartphones
case reportUsers
case buttons
}
/// Available cell type
enum DisplayType {
/// Compact view
case normal
/// Cell with map visible
case mapExpanded
/// Cell with weather info visible
case weatherExpanded
}
/// Delegate
weak var delegate: SeismicNetworkTableViewCellDelegate?
// MARK: - Internal
private static let DefaultVerticalSpacing: CGFloat = 6.0
private static let DefaultBodyFont = UIFont.preferredFont(forTextStyle: .body)
private static let DefaultBodyFontLight = UIFont.preferredFont(for: .body, weight: .light)
private static var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss d-MMM"
return formatter
}()
/// Seismic to show
private var seismic: EQNSisma?
private(set) var displayType = DisplayType.normal
private var informationTypes = [InformationType]()
private var colors: MagnitudeColors?
// MARK: - UI Components
private lazy var containerView: UIView = {
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.cornerRadius = AppTheme.shared.borderCornerRadius
view.layer.masksToBounds = true
return view
}()
private lazy var titleImageView: UIImageView = {
let imageView = UIImageView(frame: .zero)
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
private lazy var placeLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.preferredFont(for: .title2, weight: .semibold)
label.numberOfLines = 2
return label
}()
private lazy var networkLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = UIColor.white.withAlphaComponent(0.5)
label.textAlignment = .center
return label
}()
private lazy var magnitudeLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.preferredFont(forTextStyle: .largeTitle)
label.textColor = .red
return label
}()
private lazy var depthLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = Self.DefaultBodyFontLight
return label
}()
private lazy var timeLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = Self.DefaultBodyFontLight
return label
}()
private lazy var distanceLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = Self.DefaultBodyFontLight
return label
}()
private lazy var coordinateLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = Self.DefaultBodyFontLight
return label
}()
private lazy var populationLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = Self.DefaultBodyFontLight
return label
}()
private lazy var smartphonesLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = Self.DefaultBodyFont
label.textAlignment = .center
return label
}()
private lazy var alertsLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = Self.DefaultBodyFont
label.textAlignment = .center
return label
}()
private lazy var mapView: MKMapView = {
let mapView = MKMapView(frame: .zero)
mapView.translatesAutoresizingMaskIntoConstraints = false
mapView.isScrollEnabled = false
mapView.isZoomEnabled = false
mapView.layer.cornerRadius = AppTheme.shared.borderCornerRadius
mapView.layer.masksToBounds = true
return mapView
}()
private lazy var weatherImageView: UIImageView = {
let imageView = UIImageView(frame: .zero)
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
private lazy var weatherInfoLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = Self.DefaultBodyFontLight
return label
}()
// MARK: - Init
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupUI()
}
// MARK: - Setup
private func setupUI() {
selectionStyle = .default
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .clear
// container view
contentView.addSubview(containerView)
containerView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5.0).isActive = true
containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10.0).isActive = true
containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10.0).isActive = true
containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5.0).isActive = true
// this variable is used to keep track of the previous view, in order to attach proper constraints
var previousView: UIView = containerView
// preliminary banner on top of the cell
if informationTypes.contains(.preliminary) {
let preliminaryLabel = UILabel()
preliminaryLabel.translatesAutoresizingMaskIntoConstraints = false
preliminaryLabel.text = NSLocalizedString("official_prelimiary", comment: "").uppercased()
preliminaryLabel.textAlignment = .center
preliminaryLabel.backgroundColor = .red
preliminaryLabel.textColor = .yellow
containerView.addSubview(preliminaryLabel)
preliminaryLabel.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
preliminaryLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
preliminaryLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
preliminaryLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
previousView = preliminaryLabel
}
// title (bell icon, place label, seismic network and share button)
let titleComponentsHeight: CGFloat = 30.0
let stackViewTitle = UIStackView()
stackViewTitle.translatesAutoresizingMaskIntoConstraints = false
stackViewTitle.axis = .horizontal
stackViewTitle.distribution = .fill
stackViewTitle.alignment = .center
stackViewTitle.spacing = 4
let shareButton = UIButton(type: .custom)
shareButton.setImage(UIImage(named: "share_icon"), for: .normal)
shareButton.addTarget(self, action: #selector(shareTapped(_:)), for: .touchUpInside)
stackViewTitle.addArrangedSubview(titleImageView)
stackViewTitle.addArrangedSubview(placeLabel)
stackViewTitle.addArrangedSubview(networkLabel)
stackViewTitle.addArrangedSubview(shareButton)
titleImageView.heightAnchor.constraint(equalToConstant: titleComponentsHeight).isActive = true
titleImageView.widthAnchor.constraint(equalTo: titleImageView.heightAnchor).isActive = true
networkLabel.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
networkLabel.widthAnchor.constraint(equalToConstant: 60.0).isActive = true
shareButton.widthAnchor.constraint(equalToConstant: titleComponentsHeight).isActive = true
shareButton.widthAnchor.constraint(equalTo: shareButton.heightAnchor).isActive = true
let titleTopAnchor = previousView == containerView ? containerView.layoutMarginsGuide.topAnchor : previousView.bottomAnchor
containerView.addSubview(stackViewTitle)
stackViewTitle.topAnchor.constraint(equalTo: titleTopAnchor).isActive = true
stackViewTitle.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
stackViewTitle.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
let separator1 = addSeparator(constraintTo: stackViewTitle.bottomAnchor)
let informationsLeadingAnchor = separator1.leadingAnchor
let informationsTrailingAnchor = separator1.trailingAnchor
// magnitude information
containerView.addSubview(magnitudeLabel)
magnitudeLabel.topAnchor.constraint(equalTo: separator1.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
magnitudeLabel.leadingAnchor.constraint(equalTo: informationsLeadingAnchor, constant: 14).isActive = true
if !informationTypes.contains(.preliminary) {
containerView.addSubview(depthLabel)
depthLabel.lastBaselineAnchor.constraint(equalTo: magnitudeLabel.lastBaselineAnchor).isActive = true
depthLabel.leadingAnchor.constraint(equalTo: magnitudeLabel.trailingAnchor, constant: 16).isActive = true
}
// informations
let stackViewInformations = UIStackView()
stackViewInformations.translatesAutoresizingMaskIntoConstraints = false
stackViewInformations.axis = .vertical
stackViewInformations.distribution = .equalSpacing
stackViewInformations.spacing = 4
if informationTypes.contains(.time) {
stackViewInformations.addArrangedSubview(timeLabel)
}
if informationTypes.contains(.distance) {
stackViewInformations.addArrangedSubview(distanceLabel)
}
if informationTypes.contains(.coordinate) {
stackViewInformations.addArrangedSubview(coordinateLabel)
}
if informationTypes.contains(.population) {
stackViewInformations.addArrangedSubview(populationLabel)
}
containerView.addSubview(stackViewInformations)
stackViewInformations.topAnchor.constraint(equalTo: magnitudeLabel.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
stackViewInformations.leadingAnchor.constraint(equalTo: informationsLeadingAnchor, constant: 14).isActive = true
stackViewInformations.trailingAnchor.constraint(equalTo: informationsTrailingAnchor, constant: -14).isActive = true
previousView = stackViewInformations
if informationTypes.contains(.realtimeSmartphones) || informationTypes.contains(.reportUsers) {
let separator2 = addSeparator(constraintTo: stackViewInformations.bottomAnchor)
let stackViewReports = UIStackView()
stackViewReports.translatesAutoresizingMaskIntoConstraints = false
stackViewReports.axis = .vertical
stackViewReports.distribution = .equalSpacing
stackViewReports.alignment = .center
stackViewReports.spacing = Self.DefaultVerticalSpacing
if informationTypes.contains(.realtimeSmartphones) {
stackViewReports.addArrangedSubview(smartphonesLabel)
}
if informationTypes.contains(.reportUsers) {
stackViewReports.addArrangedSubview(alertsLabel)
}
containerView.addSubview(stackViewReports)
stackViewReports.topAnchor.constraint(equalTo: separator2.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
stackViewReports.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor, constant: 20.0).isActive = true
stackViewReports.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor, constant: -20.0).isActive = true
let separator3 = addSeparator(constraintTo: stackViewReports.bottomAnchor)
previousView = separator3
}
if informationTypes.contains(.buttons) {
// buttons
let stackViewButtons = UIStackView()
stackViewButtons.translatesAutoresizingMaskIntoConstraints = false
stackViewButtons.axis = .horizontal
stackViewButtons.distribution = .fillEqually
stackViewButtons.spacing = 4
let buttonMap = createRoundedButton(title: "🗺", action: #selector(mapTapped(_:)))
stackViewButtons.addArrangedSubview(buttonMap)
let buttonWeather = createRoundedButton(title: "🌤", action: #selector(weatherTapped(_:)))
stackViewButtons.addArrangedSubview(buttonWeather)
let buttonCalendar = createRoundedButton(title: "📆", action: #selector(calendarTapped(_:)))
stackViewButtons.addArrangedSubview(buttonCalendar)
let buttonSettings = createRoundedButton(title: "🔧", action: #selector(settingsTapped(_:)))
stackViewButtons.addArrangedSubview(buttonSettings)
containerView.addSubview(stackViewButtons)
stackViewButtons.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
stackViewButtons.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
stackViewButtons.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
stackViewButtons.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
previousView = stackViewButtons
}
if displayType == .mapExpanded {
containerView.addSubview(mapView)
mapView.heightAnchor.constraint(equalToConstant: 140.0).isActive = true
mapView.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
mapView.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
mapView.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
previousView = mapView
} else if displayType == .weatherExpanded {
let weatherTitleLabel = UILabel()
weatherTitleLabel.translatesAutoresizingMaskIntoConstraints = false
weatherTitleLabel.text = NSLocalizedString("weather_weather", comment: "")
weatherTitleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
containerView.addSubview(weatherTitleLabel)
weatherTitleLabel.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
weatherTitleLabel.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
weatherTitleLabel.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
containerView.addSubview(weatherInfoLabel)
containerView.addSubview(weatherImageView)
weatherImageView.heightAnchor.constraint(equalToConstant: 60.0).isActive = true
weatherImageView.widthAnchor.constraint(equalTo: weatherImageView.heightAnchor).isActive = true
weatherImageView.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
weatherImageView.trailingAnchor.constraint(equalTo: weatherInfoLabel.leadingAnchor, constant: -8.0).isActive = true
weatherImageView.centerYAnchor.constraint(equalTo: weatherInfoLabel.centerYAnchor).isActive = true
weatherInfoLabel.topAnchor.constraint(equalTo: weatherTitleLabel.bottomAnchor, constant: 4.0).isActive = true
weatherInfoLabel.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
previousView = weatherInfoLabel
}
if (displayType == .mapExpanded || displayType == .weatherExpanded) {
let buttonClose = createRoundedButton(title: NSLocalizedString("CHIUDI", comment: ""), action: #selector(closeTapped(_:)))
containerView.addSubview(buttonClose)
buttonClose.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
buttonClose.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
buttonClose.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
buttonClose.bottomAnchor.constraint(equalTo: containerView.layoutMarginsGuide.bottomAnchor).isActive = true
}
else {
previousView.bottomAnchor.constraint(equalTo: containerView.layoutMarginsGuide.bottomAnchor).isActive = true
}
}
private func recreateUI() {
// remove all subviews and recreate the required components
containerView.subviews.forEach({ $0.removeFromSuperview() })
setupUI()
}
private func updateUI() {
guard let seismic = seismic else { return }
containerView.backgroundColor = colors?.startColor
let notified = couldBeNotified(for: seismic)
titleImageView.image = notified ? UIImage(named: "bell") : UIImage(named: "bell_disabled")
// update seismic data
placeLabel.text = seismic.place
networkLabel.text = seismic.provider
magnitudeLabel.textColor = colors?.textColor
if informationTypes.contains(.preliminary) {
let lowerValue = seismic.magnitude.doubleValue - seismic.magnitudeRange.doubleValue/2.0
let upperValue = seismic.magnitude.doubleValue + seismic.magnitudeRange.doubleValue/2.0
magnitudeLabel.text = String(format: "%.1f-%.1f\(seismic.magnitudeType)", lowerValue, upperValue)
depthLabel.text = ""
} else {
magnitudeLabel.text = String(format: "%.1f%@", seismic.magnitude.doubleValue, seismic.magnitudeType)
depthLabel.text = String(format: "%@: %.1f km", NSLocalizedString("Profondità", comment: ""), seismic.depth.doubleValue)
}
let formattedDate = Self.dateFormatter.string(from: seismic.date)
let timeSuffix = seismic.timeDifference > 60 ? NSLocalizedString("ore fa", comment: "") : NSLocalizedString("minuti fa", comment: "")
let timeRounded = seismic.timeDifference > 60 ? Int(round(seismic.timeDifference / 60)) : Int(seismic.timeDifference)
timeLabel.text = "🕗 \(formattedDate) - \(timeRounded) \(timeSuffix)"
let distanceRounded = Int(round(seismic.userDistance))
distanceLabel.text = "📐 \(distanceRounded) km \(NSLocalizedString("dalla tua posizione", comment: ""))"
let coordinateText = coordinateString(coordinate: seismic.coordinate.coordinate)
coordinateLabel.text = "🌍 \(coordinateText)"
// evaluate population string
let populationIsRed = seismic.population100km >= 1_000_000 || seismic.userDistance <= 250
let population = formatPopulation(seismic.population100km)
populationLabel.text = "👨‍👩‍👦 \(population) \(NSLocalizedString("share_radius100", comment: ""))"
populationLabel.textColor = populationIsRed ? AppTheme.Colors.red : .black
if seismic.smartphoneNumber.intValue > 0 || true {
smartphonesLabel.text = String(format: NSLocalizedString("official_smartphones", comment: ""), seismic.smartphoneNumber)
}
if seismic.userNumber.intValue > 0 || true {
alertsLabel.text = String(format: NSLocalizedString("official_reports", comment: ""), seismic.userNumber)
}
if displayType == .mapExpanded {
// zoom based on population involved
let longitudeSpan = mapSpanLongitude(population: seismic.population100km)
let span = MKCoordinateSpan(latitudeDelta: longitudeSpan * 1.2, longitudeDelta: longitudeSpan)
let region = MKCoordinateRegion(center: seismic.coordinate.coordinate, span: span)
mapView.setCenter(seismic.coordinate.coordinate, animated: false)
mapView.setRegion(region, animated: false)
// add a pin on the center
let annotation = MKPointAnnotation()
annotation.coordinate = seismic.coordinate.coordinate
annotation.title = ""
mapView.addAnnotation(annotation)
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(mapDetailTapped(_:)))
mapView.addGestureRecognizer(tapRecognizer)
} else if displayType == .weatherExpanded {
weatherInfoLabel.text = ""
+ String(format: NSLocalizedString("weather_temperature", comment: ""), seismic.weatherTemperature.doubleValue - EQNMathKelvin) + "\n"
+ String(format: NSLocalizedString("weather_pressure", comment: ""), seismic.weatherPressure) + "\n"
+ String(format: NSLocalizedString("weather_windspeed", comment: ""), seismic.weatherWindSpeed) + "\n"
+ String(format: NSLocalizedString("weather_humidity", comment: ""), seismic.weatherHumidity) + "\n"
+ String(format: NSLocalizedString("weather_clouds", comment: ""), seismic.weatherCloud)
weatherImageView.image = UIImage(named: "weather_\(seismic.weatherIcon).png")
}
}
// MARK: - Public
/// Configure the cell to display a seismic
/// - Parameters:
/// - seismic: Seismic to display
/// - type: Type of cell
/// - informations: Informations to show
public func configure(with seismic: EQNSisma, type: DisplayType, informations: [InformationType]) {
self.seismic = seismic
self.colors = calculateColors(for: seismic.magnitude.doubleValue)
self.displayType = type
self.informationTypes = informations
if !informations.contains(.time) {
self.informationTypes += [.time]
}
if seismic.preliminary.intValue > 0 && !informations.contains(.preliminary) {
self.informationTypes += [.preliminary]
}
if seismic.smartphoneNumber.intValue > 0 && !informations.contains(.realtimeSmartphones) {
self.informationTypes += [.realtimeSmartphones]
}
if seismic.userNumber.intValue > 0 && !informations.contains(.reportUsers) {
self.informationTypes += [.reportUsers]
}
recreateUI()
updateUI()
}
/// Creates a snapshot of the current cell
/// - Returns: Image with the snapshot of the cell
public func createSnapshot() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: contentView.bounds.size)
let image = renderer.image { ctx in
contentView.drawHierarchy(in: contentView.bounds, afterScreenUpdates: true)
}
return image
}
// MARK: - Actions
@objc func shareTapped(_ sender: UIButton) {
delegate?.seismicNetworkCellDidTapShare(self)
}
@objc func mapTapped(_ sender: UIButton) {
if displayType != .mapExpanded {
delegate?.seismicNetworkCellDidTapMap(self)
}
}
@objc func weatherTapped(_ sender: UIButton) {
if displayType != .weatherExpanded {
delegate?.seismicNetworkCellDidTapWeather(self)
}
}
@objc func calendarTapped(_ sender: UIButton) {
delegate?.seismicNetworkCellDidTapCalendar(self)
}
@objc func settingsTapped(_ sender: UIButton) {
delegate?.seismicNetworkCellDidTapSettings(self)
}
@objc func closeTapped(_ sender: UIButton) {
delegate?.seismicNetworkCellDidTapClose(self)
}
@objc func mapDetailTapped(_ sender: Any) {
delegate?.seismicNetworkCellDidTapMapDetail(self)
}
// MARK: - Helpers
@discardableResult
private func addSeparator(constraintTo: NSLayoutYAxisAnchor, constanst: CGFloat = 8.0) -> UIView {
let separator = UIView()
separator.translatesAutoresizingMaskIntoConstraints = false
separator.backgroundColor = .lightGray
containerView.addSubview(separator)
separator.topAnchor.constraint(equalTo: constraintTo, constant: constanst).isActive = true
separator.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
separator.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
separator.heightAnchor.constraint(equalToConstant: 1.0).isActive = true
return separator
}
private func createRoundedButton(title: String, action: Selector) -> EQNRoundedButton {
let button = EQNRoundedButton(frame: .zero)
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: action, for: .touchUpInside)
button.setTitle(title, for: .normal)
button.setTitleColor(AppTheme.Colors.darkGray, for: .normal)
button.backgroundColor = UIColor.white.withAlphaComponent(0.5)
return button
}
/// Check if the user could be received a notification for this seismic
private func couldBeNotified(for seismic: EQNSisma) -> Bool {
let settings = EQNNotificheReteSismiche.shared()
if !settings.isAbilitato {
return false
}
if !settings.listaEnti.contains(seismic.provider) {
return false
}
var notified = true
if let radius = Double(settings.distanzaPosizione), seismic.userDistance > radius {
notified = false
}
if let magnitude = Double(settings.energiaSisma), seismic.magnitude.doubleValue < magnitude {
notified = false
}
if settings.isAbilitaVicini, seismic.userDistance < 50 {
notified = true
}
if settings.isTerremortiForti, let strongMagnitude = Double(settings.energiaTerremotiForti), seismic.magnitude.doubleValue >= strongMagnitude {
notified = true
}
return notified
}
/// Convert coordinates in degrees
private func coordinateString(coordinate: CLLocationCoordinate2D) -> String {
var latSeconds = Int(coordinate.latitude * 3600)
let latDegrees = latSeconds / 3600
latSeconds = abs(latSeconds % 3600)
let latMinutes = latSeconds / 60
latSeconds %= 60
var longSeconds = Int(coordinate.longitude * 3600)
let longDegrees = longSeconds / 3600
longSeconds = abs(longSeconds % 3600)
let longMinutes = longSeconds / 60
longSeconds %= 60
return String(format:"%d°%d'%d\"%@ lat %d°%d'%d\"%@ lon",
abs(latDegrees),
latMinutes,
latSeconds, latDegrees >= 0 ? "N" : "S",
abs(longDegrees),
longMinutes,
longSeconds,
longDegrees >= 0 ? "E" : "W" )
}
/// Determines the zoom for the map, based on the involved population
private func mapSpanLongitude(population: Double) -> CLLocationDegrees {
var zoom: CLLocationDegrees = 1
if population > 1_000_000 {
zoom = 1
} else if population < 500 {
zoom = 24
} else {
zoom = 6
}
return zoom
}
/// Format population value (ex. 1.5M, 2.4k)
private func formatPopulation(_ population: Double) -> String {
var populationString = ""
if population > 999_999 {
let roundedPopulation = round(population / 100_000) / 10
populationString = "\(roundedPopulation)M"
} else if population > 999 {
let roundedPopulation = round(population / 100) / 10
populationString = "\(roundedPopulation)K"
} else {
let roundedPopulation = round(population)
populationString = "\(roundedPopulation)"
}
return populationString
}
/// Calculate colors to use for text and background of the cell
private func calculateColors(for magnitude: Double) -> MagnitudeColors {
var textColor = UIColor.black
var r = 0, g = 0, b = 0
if (magnitude < 2.0) {
let fraction: Double = 1 - (magnitude - 0.0) / (2.0 - 0.0)
r = Int(round(200.0 + (255.0 - 200.0) * fraction))
g = Int(round(226.0 + (255.0 - 226.0) * fraction))
b = Int(round(196.0 + (255.0 - 196.0) * fraction))
textColor = UIColor(red: 12.0 / 255.0, green: 115.0 / 255.0, blue: 160.0 / 255.0, alpha: 1.0)
}
if (magnitude >= 2.0 && magnitude < 3.5) {
let fraction: Double = 1 - (magnitude - 2) / (3.5 - 2)
r = Int(round(136.0 + (200.0 - 136.0) * fraction))
g = Int(round(175.0 + (226.0 - 175.0) * fraction))
b = Int(round(131.0 + (196.0 - 131.0) * fraction))
textColor = UIColor(red: 12.0 / 255.0, green: 160.0 / 255.0, blue: 35.0 / 255.0, alpha: 1.0)
}
if (magnitude >= 3.5 && magnitude < 4.5) {
let fraction: Double = 1 - (magnitude - 3.5) / (4.5 - 3.5)
r = 252
g = Int(round(233.0 + (253.0 - 233.0) * fraction))
b = Int(round(179.0 + (209.0 - 179.0) * fraction))
textColor = UIColor(red: 244.0 / 255.0, green: 195.0 / 255.0, blue: 0.0 / 255.0, alpha: 1.0)
}
if (magnitude >= 4.5 && magnitude < 5.5) {
let fraction: Double = 1 - (magnitude - 4.5) / (5.5 - 4.5)
r = 252
g = Int(round(159.0 + (197.0 - 159.0) * fraction))
b = Int(round(161.0 + (197.0 - 161.0) * fraction))
textColor = UIColor(red: 255.0 / 255.0, green: 0.0 / 255.0, blue: 0.0 / 255.0, alpha: 1.0)
}
if (magnitude >= 5.5) {
let fraction: Double = 1 - (magnitude - 5.5) / (10 - 5.5)
r = Int(round(190.0 + (254.0 - 190.0) * fraction))
g = Int(round(124.0 + (219.0 - 124.0) * fraction))
b = 255
textColor = UIColor(red: 183.0 / 255.0, green: 60.0 / 255.0, blue: 252.0 / 255.0, alpha: 1.0)
}
let r2 = min(r + 30, 255)
let g2 = min(g + 30, 255)
let b2 = min(b + 30, 255)
let startColor = UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: 1.0)
let endColor = UIColor(red: CGFloat(r2) / 255.0, green: CGFloat(g2) / 255.0, blue: CGFloat(b2) / 255.0, alpha: 1.0)
return (textColor: textColor, startColor: startColor, endColor: endColor)
}
}
@@ -2,8 +2,8 @@
// ReteSismiDettagliMappa.h
// Earthquake Network
//
// Created by Luca Beretta on 07/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 26/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "DettagliMappaViewController.h"
@@ -11,6 +11,5 @@
@interface ReteSismiDettagliMappa : DettagliMappaViewController
@property (nonatomic, strong) EQNSisma *sisma;
@property (nonatomic, strong, nullable) EQNSisma *sisma;
@end
@@ -0,0 +1,76 @@
//
// ReteSismiDettagliMappa.m
// Earthquake Network
//
// Refactored by Andrea Busi on 26/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "ReteSismiDettagliMappa.h"
#import "SismaAnnotation.h"
@interface ReteSismiDettagliMappa ()
@property(nonatomic, strong) GADBannerView *bannerView;
@end
@implementation ReteSismiDettagliMappa
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];
for (EQNSisma *sismi in [EQNManager defaultManager].retiSismiche ) {
[self creaMarcherWithSegnalazione:sismi];
}
}
#pragma mark - Private
- (void)setupUI
{
self.mapView.delegate = self;
self.bannerView = [EQNUtility ottieniBannerWithController:self position:YES];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back"]
style:UIBarButtonItemStyleDone
target:self
action:@selector(chiudi:)];
self.navigationController.navigationItem.leftBarButtonItem = backButton;
}
- (void)creaMarcherWithSegnalazione:(id)segnalazione
{
[super creaMarcherWithSegnalazione:segnalazione];
SismaAnnotation *anAnnotation = [[SismaAnnotation alloc] initWithTitle:self.sisma.place location:self.sisma.coordinate.coordinate intensita:[self.sisma.magnitude doubleValue]];
[self.mapView addAnnotation:anAnnotation];
MKCoordinateSpan span = MKCoordinateSpanMake(10.5, 10.5);
MKCoordinateRegion region = MKCoordinateRegionMake(self.sisma.coordinate.coordinate, span);
[self.mapView setCenterCoordinate:self.sisma.coordinate.coordinate animated:NO];
[self.mapView setRegion:region animated:YES];
}
#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[SismaAnnotation class]]) {
SismaAnnotation *anLocation = (SismaAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_SISMI];
if (annotationView == nil) {
annotationView = anLocation.annotationView;
} else {
annotationView.annotation = anLocation;
}
return annotationView;
}
return nil;
}
@end
@@ -0,0 +1,83 @@
//
// SeismicCardSettingsViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 26/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
protocol SeismicCardSettingsViewControllerDelegate: class {
func seismicCardSettingsDidComplete(_ controller: SeismicCardSettingsViewController)
}
class SeismicCardSettingsViewController: UIViewController {
weak var delegate: SeismicCardSettingsViewControllerDelegate?
// MARK: - Internal
@IBOutlet private weak var containerView: UIView!
@IBOutlet private weak var informationDistanceSwitch: UISwitch!
@IBOutlet private weak var informationLocationSwitch: UISwitch!
@IBOutlet private weak var informationPopulationSwitch: UISwitch!
private var informations = [SeismicNetworkTableViewCell.InformationType]()
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
if let saved = UserDefaults.standard.array(forKey: EQNUserDefaultKeySesmicInformations) as? [Int] {
informations = saved.compactMap { SeismicNetworkTableViewCell.InformationType(rawValue: $0) }
}
setupUI()
updateUI()
}
// MARK: - Private
private func setupUI() {
containerView.layer.cornerRadius = AppTheme.shared.borderCornerRadius
containerView.layer.masksToBounds = true
}
private func updateUI() {
informationDistanceSwitch.isOn = informations.contains(.distance)
informationLocationSwitch.isOn = informations.contains(.coordinate)
informationPopulationSwitch.isOn = informations.contains(.population)
}
private func toggle(information: SeismicNetworkTableViewCell.InformationType) {
if informations.contains(information) {
informations.removeAll(where: { $0 == information })
} else {
informations.append(information)
}
}
// MARK: - Action
@IBAction func switchChanged(_ sender: UISwitch) {
if sender == informationDistanceSwitch {
toggle(information: .distance)
} else if sender == informationLocationSwitch {
toggle(information: .coordinate)
} else if sender == informationPopulationSwitch {
toggle(information: .population)
}
UserDefaults.standard.set(informations.map { $0.rawValue }, forKey: EQNUserDefaultKeySesmicInformations)
updateUI()
}
@IBAction func closeTapped(_ sender: UISwitch) {
delegate?.seismicCardSettingsDidComplete(self)
dismiss(animated: true, completion: nil)
}
}
@@ -0,0 +1,211 @@
//
// SeismicFiltersViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 20/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
@objc protocol SeismicFiltersViewControllerDelegate: class {
func seismicFiltersControllerDidUpdateFilters(_ controller: SeismicFiltersViewController)
}
class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private enum RowIdentifier: Int {
case magnitudoMinima
case distanzaMassima
case periodoTemporale
case sismiFortiAbilita
case sismiFortiDistanza
case sismiQualsiasiMagnitudo
case modificaImpostazioni
}
@objc weak var delegate: SeismicFiltersViewControllerDelegate?
/// Tells if delegate needs to redownload data when filter is dismissed
@objc private(set) var needsDataUpdate = false
// MARK: - Internal
@IBOutlet private weak var containerView: UIView!
@IBOutlet private weak var tableView: UITableView!
private var settings = [
SettingItem(type: .slider, title: NSLocalizedString("Magnitudo minima", comment: "")),
SettingItem(type: .slider, title: NSLocalizedString("Distanza massima", comment: "")),
SettingItem(type: .slider, title: NSLocalizedString("Periodo temporale", comment: "")),
SettingItem(type: .enable, title: NSLocalizedString("Mostra sismi forti a qualsiasi distanza se di", comment: "")),
SettingItem(type: .slider, title: NSLocalizedString("Magnitudo", comment: "")),
SettingItem(type: .enable, title: NSLocalizedString("Mostra sismi di qualsiasi magnitudo se a meno di 50 km", comment: "")),
SettingItem(type: .enable, title: NSLocalizedString("Modifica le impostazioni di notifica dei sismi in accordo con i filtri", comment: ""))
]
private let dataSourceMagnitudoMinima = EQNData.magitudoDeboli()
private let dataSourceDistanzaMassima = EQNData.raggioSismi()
private let dataSourcePeriodoTemporale = EQNData.periodiTemporali()
private let dataSourceSismiForti = EQNData.magitudoForti()
private var currentMagnitudoMinima = EQNData.DefaultMagitudoDebole
private var currentDistanzaMassima = EQNData.DefaultRaggioSisma
private var currentPeriodoTemporale = EQNData.DefaultPeriodoTemporale
private var currentSismiFortiAbilitati = false
private var currentSismiFortiDistanza = EQNData.DefaultMagitudoForte
private var currentSismiQualsiasiMagnitudo = false
private var currentModificaImpostazioni = false
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
updateUI()
}
private func setupUI() {
containerView.layer.cornerRadius = AppTheme.shared.borderCornerRadius
containerView.layer.masksToBounds = true
tableView.estimatedRowHeight = 100.0
tableView.rowHeight = UITableView.automaticDimension
tableView.register(SettingEnableTableViewCell.self, forCellReuseIdentifier: SettingEnableTableViewCell.Identifier)
tableView.register(SettingSliderTableViewCell.self, forCellReuseIdentifier: SettingSliderTableViewCell.Identifier)
}
private func updateUI() {
currentMagnitudoMinima = EQNData.magitudoDebole(for: EQNSeismic.shared.magnitudoMinima)
currentDistanzaMassima = EQNData.raggioSisma(for: EQNSeismic.shared.distanzaMassima)
currentPeriodoTemporale = EQNData.periodoTemporale(for: EQNSeismic.shared.periodoTemporale)
currentSismiFortiAbilitati = EQNSeismic.shared.sismiFortiAbilitati
currentSismiFortiDistanza = EQNData.magitudoForte(for: EQNSeismic.shared.sismiFortiMagnitudo)
currentSismiQualsiasiMagnitudo = EQNSeismic.shared.sismiQualsiasiAbilitati
currentModificaImpostazioni = EQNSeismic.shared.modificaImpostazioniAbilitato
tableView.reloadData()
}
// MARK: - Table view delegate and data source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
settings.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let setting = settings[indexPath.row]
switch setting.type {
case .slider:
let cell = tableView.dequeueReusableCell(withIdentifier: SettingSliderTableViewCell.Identifier, for: indexPath) as! SettingSliderTableViewCell
cell.titleLabel.text = setting.displayTitle
if indexPath.row == RowIdentifier.magnitudoMinima.rawValue {
cell.configureSlider(with: dataSourceMagnitudoMinima, current: currentMagnitudoMinima)
cell.valueChanged = { [unowned self] value in
needsDataUpdate = true
currentMagnitudoMinima = value
EQNSeismic.shared.magnitudoMinima = value.value
EQNSeismic.shared.saveFilters()
updateUI()
}
cell.dragEnded = { [unowned self] in
showWarningAlertIfNeeded(for: currentMagnitudoMinima)
}
} else if indexPath.row == RowIdentifier.distanzaMassima.rawValue {
cell.configureSlider(with: dataSourceDistanzaMassima, current: currentDistanzaMassima)
cell.valueChanged = { [unowned self] value in
currentDistanzaMassima = value
EQNSeismic.shared.distanzaMassima = value.value
EQNSeismic.shared.saveFilters()
updateUI()
}
} else if indexPath.row == RowIdentifier.periodoTemporale.rawValue {
cell.configureSlider(with: dataSourcePeriodoTemporale, current: currentPeriodoTemporale)
cell.valueChanged = { [unowned self] value in
currentPeriodoTemporale = value
EQNSeismic.shared.periodoTemporale = value.value
EQNSeismic.shared.saveFilters()
updateUI()
}
} else if indexPath.row == RowIdentifier.sismiFortiDistanza.rawValue {
cell.isDisabled = !currentSismiFortiAbilitati
cell.configureSlider(with: dataSourceSismiForti, current: currentSismiFortiDistanza)
cell.valueChanged = { [unowned self] value in
currentSismiFortiDistanza = value
EQNSeismic.shared.sismiFortiMagnitudo = value.value
EQNSeismic.shared.saveFilters()
updateUI()
}
}
return cell
case .enable:
let cell = tableView.dequeueReusableCell(withIdentifier: SettingEnableTableViewCell.Identifier, for: indexPath) as! SettingEnableTableViewCell
cell.titleLabel.text = setting.displayTitle
cell.detailTextLabel?.text = setting.subtitle
if indexPath.row == RowIdentifier.sismiFortiAbilita.rawValue {
cell.toggleSwitch.isOn = currentSismiFortiAbilitati
cell.valueChanged = { [unowned self] value in
currentSismiFortiAbilitati = value
EQNSeismic.shared.sismiFortiAbilitati = value
EQNSeismic.shared.saveFilters()
updateUI()
}
} else if indexPath.row == RowIdentifier.sismiQualsiasiMagnitudo.rawValue {
cell.toggleSwitch.isOn = currentSismiQualsiasiMagnitudo
cell.valueChanged = { [unowned self] value in
currentSismiQualsiasiMagnitudo = value
EQNSeismic.shared.sismiQualsiasiAbilitati = value
EQNSeismic.shared.saveFilters()
updateUI()
}
} else if indexPath.row == RowIdentifier.modificaImpostazioni.rawValue {
cell.toggleSwitch.isOn = currentModificaImpostazioni
cell.valueChanged = { [unowned self] value in
currentModificaImpostazioni = value
EQNSeismic.shared.modificaImpostazioniAbilitato = value
EQNSeismic.shared.saveFilters()
updateUI()
}
}
return cell
default:
fatalError("Setting type not handled")
}
}
// MARK: - Actions
@IBAction func exitTapped(_ sender: UIButton) {
delegate?.seismicFiltersControllerDidUpdateFilters(self)
updateNotificationSettingsIfNeeded()
dismiss(animated: true, completion: nil)
}
// MARK: - Private
private func showWarningAlertIfNeeded(for value: EQNGenericValue) {
guard let magnitude = Double(value.value), magnitude < 2.0 else { return }
let alert = UIAlertController(title: NSLocalizedString("Attenzione", comment: ""), message: NSLocalizedString("options_low_magnitude", comment: ""), preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("main_understood", comment: ""), style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
private func updateNotificationSettingsIfNeeded() {
// if the switch is enabled, update also the settings notification
guard currentModificaImpostazioni == true else { return }
// update notification settings with current filters
EQNNotificheReteSismiche.shared().energiaSisma = EQNSeismic.shared.magnitudoMinima;
EQNNotificheReteSismiche.shared().distanzaPosizione = EQNSeismic.shared.distanzaMassima
EQNNotificheReteSismiche.shared().isAbilitaVicini = EQNSeismic.shared.sismiQualsiasiAbilitati
EQNNotificheReteSismiche.shared().isTerremortiForti = EQNSeismic.shared.sismiFortiAbilitati
EQNNotificheReteSismiche.shared().energiaTerremotiForti = EQNSeismic.shared.sismiFortiMagnitudo
}
}
@@ -0,0 +1,346 @@
//
// SeismicNetworksViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 22/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
import EventKitUI
import DZNEmptyDataSet
class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate, UITableViewDataSource {
private static let SegueIdentifierMap = "ShowMapDetail"
private static let SegueIdentifierFilters = "ShowFilters"
private static let SegueIdentifierSettings = "ShowSettings"
private static let SegueIdentifierSeismicNetworks = "ShowSeismicNetworks"
private static let SegueIdentifierCardSettings = "ShowCardSettings"
// MARK: - Internal
@IBOutlet private weak var tableView: UITableView?
@IBOutlet private weak var expandeCollapseButton: UIBarButtonItem!
/// Seismisc to display
private var seismics = [EQNSisma]()
/// Informations to display on a single cell
private var informations = [SeismicNetworkTableViewCell.InformationType]()
/// Index path of row with map expanded
private var openMapIndexPath: IndexPath?
/// Index path of row with weather expanded
private var openWeatherIndexPath: IndexPath?
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(didReceiveDownloadCompletedNotification(_:)),
name: NSNotification.Name(rawValue: NOTIFICA_DOWNLOAD_TERMINATO),
object: nil)
setupUI()
refreshUI()
// only the first time, show the popup for country selection
let alreadyPresented = UserDefaults.standard.bool(forKey: EQNUserDefaultKeyOneShotShowCountry)
if !alreadyPresented {
performSegue(withIdentifier: Self.SegueIdentifierSettings, sender: nil)
UserDefaults.standard.setValue(true, forKey: EQNUserDefaultKeyOneShotShowCountry)
}
}
private func setupUI() {
title = NSLocalizedString("tab_official", comment: "")
tableView?.estimatedRowHeight = 300.0;
tableView?.rowHeight = UITableView.automaticDimension
tableView?.register(SeismicNetworkTableViewCell.self, forCellReuseIdentifier: SeismicNetworkTableViewCell.Identifier)
tableView?.emptyDataSetSource = self
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case Self.SegueIdentifierMap:
if let seismic = sender as? EQNSisma, let navController = segue.destination as? UINavigationController, let controller = navController.viewControllers.first as? ReteSismiDettagliMappa {
controller.sisma = seismic
}
case Self.SegueIdentifierFilters:
if let controller = segue.destination as? SeismicFiltersViewController {
controller.delegate = self
}
case Self.SegueIdentifierSettings:
if let controller = segue.destination as? SeismicSettingsViewController {
controller.delegate = self
}
case Self.SegueIdentifierSeismicNetworks:
if let navController = segue.destination as? UINavigationController, let controller = navController.viewControllers.first as? SeismicSettingsNetworksViewController {
controller.delegate = self
}
case Self.SegueIdentifierCardSettings:
if let controller = segue.destination as? SeismicCardSettingsViewController {
controller.delegate = self
}
default:
break
}
}
// MARK: - Notification
@objc func didReceiveDownloadCompletedNotification(_ notification: NSNotification) {
DispatchQueue.main.async {
self.openMapIndexPath = nil
self.openWeatherIndexPath = nil
self.refreshUI()
}
}
// MARK: - Private
override func refreshUI() {
super.refreshUI()
let allSeismics = EQNManager.manager().retiSismiche
seismics = EQNSeismic.shared.filterSeismicList(allSeismics ?? [])
if let saved = UserDefaults.standard.array(forKey: EQNUserDefaultKeySesmicInformations) as? [Int] {
informations = saved.compactMap { SeismicNetworkTableViewCell.InformationType(rawValue: $0) }
}
if informations.contains(.buttons) {
expandeCollapseButton.image = UIImage(named: "navbar-icon-arrow-collapse")
} else {
expandeCollapseButton.image = UIImage(named: "navbar-icon-arrow-expand")
}
tableView?.reloadData()
}
// MARK: - Actions
@IBAction func refreshDataTapped(_ sender: Any) {
EQNManager.manager().sincronizza()
}
@IBAction func openFilterTapped(_ sender: Any) {
performSegue(withIdentifier: Self.SegueIdentifierFilters, sender: nil)
}
@IBAction func openSettingsTapped(_ sender: Any) {
performSegue(withIdentifier: Self.SegueIdentifierSettings, sender: nil)
}
@IBAction func collapseExpandTapped(_ sender: Any) {
if informations.contains(.buttons) {
informations.removeAll(where: { $0 == .buttons })
} else {
informations.append(.buttons)
}
UserDefaults.standard.set(informations.map { $0.rawValue }, forKey: EQNUserDefaultKeySesmicInformations)
refreshUI()
}
// MARK: - Table view delegate and data source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
seismics.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: SeismicNetworkTableViewCell.Identifier, for: indexPath) as! SeismicNetworkTableViewCell
let seismic = seismics[indexPath.row]
var type = SeismicNetworkTableViewCell.DisplayType.normal
if openMapIndexPath == indexPath {
type = .mapExpanded
} else if openWeatherIndexPath == indexPath {
type = .weatherExpanded
}
cell.configure(with: seismic, type: type, informations: informations)
cell.delegate = self
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let seismic = seismics[indexPath.row]
performSegue(withIdentifier: Self.SegueIdentifierMap, sender: seismic)
}
// MARK: - Private
private func openCalendar(for seismic: EQNSisma) {
checkCalendarPermission {
self.createCalendarEvent(for: seismic)
} failure: {
let alert = UIAlertController(title: NSLocalizedString("Attenzione", comment: ""),
message: "Non è possibile aprire il calendario, assicurarsi di aver impostato i permessi corretti",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default))
self.present(alert, animated: true)
}
}
private func checkCalendarPermission(success: @escaping () -> Void, failure: @escaping () -> Void) {
let authorization = EKEventStore.authorizationStatus(for: .event)
switch authorization {
case .notDetermined:
let eventStore = EKEventStore()
eventStore.requestAccess(to: .event) { (granted, error) in
DispatchQueue.main.async {
if granted {
success()
} else {
failure()
}
}
}
case .authorized:
success()
default:
failure()
}
}
private func createCalendarEvent(for seismic: EQNSisma) {
let eventStore = EKEventStore()
// calendar event
let event = EKEvent(eventStore: eventStore)
event.title = seismic.place
event.startDate = seismic.date
event.endDate = seismic.date
event.notes = String(format: NSLocalizedString("calendar_description_nogeo_km", comment: ""), seismic.magnitude, seismic.depth)
// controller to present
let eventVC = EKEventEditViewController()
eventVC.editViewDelegate = self
eventVC.eventStore = eventStore
eventVC.event = event
present(eventVC, animated: true)
}
}
extension SeismicNetworksViewController: SeismicNetworkTableViewCellDelegate {
func seismicNetworkCellDidTapShare(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
// create a snapshot of the cell and share with default share sheet
let snapshot = cell.createSnapshot()
// text to share with the snapshot
let seismic = seismics[index.row]
let shareHashtag = NSLocalizedString("share_hashtag", comment: "")
let magnitude = String(format: "%.1f", seismic.magnitude.doubleValue)
let location = seismic.place
let notified = NSLocalizedString("share_notified", comment: "")
let shareMessage = "\(shareHashtag) M\(magnitude), \(location). \(notified)"
let controller = UIActivityViewController(activityItems: [snapshot, shareMessage], applicationActivities: [])
present(controller, animated: true)
}
func seismicNetworkCellDidTapWeather(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
let indexToReloads = [openMapIndexPath, openWeatherIndexPath, index].compactMap { $0 }
openWeatherIndexPath = index
openMapIndexPath = nil
tableView?.reloadRows(at: indexToReloads, with: .automatic)
}
func seismicNetworkCellDidTapMap(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
let indexToReloads = [openMapIndexPath, openWeatherIndexPath, index].compactMap { $0 }
openMapIndexPath = index
openWeatherIndexPath = nil
tableView?.reloadRows(at: indexToReloads, with: .automatic)
}
func seismicNetworkCellDidTapMapDetail(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
let seismic = seismics[index.row]
performSegue(withIdentifier: Self.SegueIdentifierMap, sender: seismic)
}
func seismicNetworkCellDidTapCalendar(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
let seismic = seismics[index.row]
openCalendar(for: seismic)
}
func seismicNetworkCellDidTapSettings(_ cell: SeismicNetworkTableViewCell) {
performSegue(withIdentifier: Self.SegueIdentifierCardSettings, sender: nil)
}
func seismicNetworkCellDidTapClose(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
let indexToReloads = [openMapIndexPath, openWeatherIndexPath, index].compactMap { $0 }
openMapIndexPath = nil
openWeatherIndexPath = nil
tableView?.reloadRows(at: indexToReloads, with: .automatic)
}
}
extension SeismicNetworksViewController: EKEventEditViewDelegate {
func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
dismiss(animated: true, completion: nil)
}
}
extension SeismicNetworksViewController: SeismicFiltersViewControllerDelegate {
func seismicFiltersControllerDidUpdateFilters(_ controller: SeismicFiltersViewController) {
if controller.needsDataUpdate {
EQNManager.manager().sincronizza()
}
refreshUI()
}
}
extension SeismicNetworksViewController: SeismicSettingsViewControllerDelegate {
func seismicSettingsControllerDidComplete(_ controller: SeismicSettingsViewController) {
refreshUI()
}
func seismicSettingsControllerWillOpenProviders(_ controller: SeismicSettingsViewController) {
performSegue(withIdentifier: Self.SegueIdentifierSeismicNetworks, sender: nil)
}
}
extension SeismicNetworksViewController: SeismicSettingsNetworksViewControllerDelegate {
func seismicSettingsNetworksControllerDidComplete(_ controller: SeismicSettingsNetworksViewController) {
refreshUI()
}
}
extension SeismicNetworksViewController: SeismicCardSettingsViewControllerDelegate {
func seismicCardSettingsDidComplete(_ controller: SeismicCardSettingsViewController) {
refreshUI()
}
}
extension SeismicNetworksViewController: DZNEmptyDataSetSource {
func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let attributes = [ NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .body) ]
let string = NSAttributedString(string: NSLocalizedString("filter_empty", comment: ""), attributes: attributes)
return string
}
}
@@ -0,0 +1,112 @@
//
// SeismicSettingsNetworksViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 14/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
@objc protocol SeismicSettingsNetworksViewControllerDelegate: class {
func seismicSettingsNetworksControllerDidComplete(_ controller: SeismicSettingsNetworksViewController)
}
class SeismicSettingsNetworksViewController: UITableViewController {
@objc weak var delegate: SeismicSettingsNetworksViewControllerDelegate?
// MARK: - Private
private var networks = [EQNSeismicNetwork]()
private var savedNetworks = [String]()
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(SettingDetailTableViewCell.self, forCellReuseIdentifier: SettingDetailTableViewCell.Identifier)
tableView.register(SettingSectionHeaderView.self, forHeaderFooterViewReuseIdentifier: SettingSectionHeaderView.Identifier)
loadData()
}
// MARK: - Private
private func loadData() {
networks = EQNData.seismicNetworks().sorted(by: { $0.acronym < $1.acronym })
// load saved selected networks or fill with all available networks
if let savedNetworks = UserDefaults.standard.object(forKey: IMPOSTAZIONE_ENTI_RETI_SISMICHEI) as? [String] {
self.savedNetworks = savedNetworks
} else {
self.savedNetworks = EQNData.seismicNetworkAcronyms()
}
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: SettingSectionHeaderView.Identifier) as! SettingSectionHeaderView
headerView.titleLabel.text = NSLocalizedString("Reti sismiche", comment: "");
return headerView
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
CGFloat(SettingSectionHeaderView.Height)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
networks.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let network = networks[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: SettingDetailTableViewCell.Identifier, for: indexPath) as! SettingDetailTableViewCell
cell.textLabel?.text = "\(network.acronym) (\(network.country))"
if savedNetworks.contains(network.acronym) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let network = networks[indexPath.row]
if let index = savedNetworks.firstIndex(of: network.acronym) {
savedNetworks.remove(at: index)
} else {
savedNetworks.append(network.acronym)
}
tableView.reloadRows(at: [indexPath], with: .automatic)
}
// MARK: - Actions
@IBAction func cancelTapped(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
@IBAction func saveTapped(_ sender: Any) {
// save selected networks
UserDefaults.standard.set(savedNetworks, forKey: IMPOSTAZIONE_ENTI_RETI_SISMICHEI)
// se solo un'ente è selezionato, salviamolo anche come nazione
if savedNetworks.count == 1 {
UserDefaults.standard.set(savedNetworks.first!, forKey: IMPOSTAZIONE_NAZIONE_RETI_SISMICHE)
} else {
UserDefaults.standard.removeObject(forKey: IMPOSTAZIONE_NAZIONE_RETI_SISMICHE)
}
delegate?.seismicSettingsNetworksControllerDidComplete(self)
dismiss(animated: true, completion: nil)
}
}
@@ -0,0 +1,116 @@
//
// SeismicSettingsViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 13/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objc protocol SeismicSettingsViewControllerDelegate: class {
func seismicSettingsControllerDidComplete(_ controller: SeismicSettingsViewController)
func seismicSettingsControllerWillOpenProviders(_ controller: SeismicSettingsViewController)
}
class SeismicSettingsViewController: UIViewController {
@objc weak var delegate: SeismicSettingsViewControllerDelegate?
// MARK: - Private
@IBOutlet private weak var containerView: UIView!
@IBOutlet private weak var countryTextField: UITextField!
private let networks = EQNData.seismicNetworks().sorted(by: { $0.country < $1.country })
private let picker = EQNGenericPickerViewController()
private var selectedNetwork: EQNSeismicNetwork?
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
// MARK: - Private
private func setupUI() {
containerView.layer.cornerRadius = AppTheme.shared.borderCornerRadius
containerView.layer.masksToBounds = true
// load saved country (if exists)
let savedCountry = UserDefaults.standard.object(forKey: IMPOSTAZIONE_NAZIONE_RETI_SISMICHE) as? String
selectedNetwork = EQNData.seismic(for: savedCountry)
countryTextField.text = selectedNetwork?.country
countryTextField.inputView = picker.view
let selectedIndex: Int? = selectedNetwork != nil ? networks.firstIndex(of: selectedNetwork!) : nil
picker.configure(with: networks, selectedIndex: selectedIndex) { [unowned self] (network) in
guard let network = network as? EQNSeismicNetwork else { return }
self.view.endEditing(true)
self.selectedNetwork = network
self.countryTextField.text = self.selectedNetwork?.country
}
picker.onCancel = { [unowned self] in
self.view.endEditing(true)
}
}
private func performSave(for network: EQNSeismicNetwork) {
// salviamo la sigla dell'ente selezionato
UserDefaults.standard.set(network.acronym, forKey: IMPOSTAZIONE_NAZIONE_RETI_SISMICHE)
// gli enti selezionati conterranno solo l'ente della nazione selezionata
let selectedNetworks = [network.acronym]
UserDefaults.standard.set(selectedNetworks, forKey: IMPOSTAZIONE_ENTI_RETI_SISMICHEI)
// aggiorniamo le impostazioni di notifica
EQNNotificheReteSismiche.shared().listaEnti = selectedNetworks
EQNNotificheReteSismiche.shared().saveUserInfo()
SettingsBaseViewController.saveSettings()
// informiamo il delegato
delegate?.seismicSettingsControllerDidComplete(self)
dismiss(animated: true, completion: nil)
}
// MARK: - Actions
@IBAction func confirmCountryTapped(_ sender: UIButton) {
guard let network = selectedNetwork else {
let alert = UIAlertController(title: NSLocalizedString("Attenzione ", comment: ""),
message: NSLocalizedString("Non hai seleziato nessuna nazione", comment: ""),
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .cancel, handler: { [unowned self] (action) in
self.countryTextField.becomeFirstResponder()
}))
present(alert, animated: true, completion: nil)
return
}
// ask confirm to change settings for notifications
let alert = UIAlertController(title: NSLocalizedString("Attenzione ", comment: ""),
message: NSLocalizedString("official_select_message", comment: ""),
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("Annulla", comment: ""), style: .cancel))
alert.addAction(UIAlertAction(title: NSLocalizedString("official_select_confirm", comment: ""), style: .default, handler: { [unowned self] (action) in
self.performSave(for: network)
}))
present(alert, animated: true, completion: nil)
}
@IBAction func selectNetworksTapped(_ sender: UIButton) {
delegate?.seismicSettingsControllerWillOpenProviders(self)
dismiss(animated: true, completion: nil)
}
@IBAction func cancelTapped(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
}
@@ -18,7 +18,7 @@ class SettingSectionHeaderView: UITableViewHeaderFooterView {
@objc lazy var titleLabel: UILabel = {
let titleLabel = UILabel()
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
titleLabel.textColor = UIColor(named: "Light blue")
titleLabel.textColor = AppTheme.Colors.lightBlue
return titleLabel
}()
@@ -18,6 +18,7 @@ class SettingSliderTableViewCell: UITableViewCell {
}
}
@objc var valueChanged: ((EQNGenericValue) -> Void)?
@objc var dragEnded: (() -> Void)?
private var items = [EQNGenericValue]()
@@ -45,6 +46,7 @@ class SettingSliderTableViewCell: UITableViewCell {
let slider = UISlider()
slider.isContinuous = true
slider.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
slider.addTarget(self, action: #selector(sliderEnded(_:)), for: .touchUpInside)
return slider
}()
@@ -101,6 +103,10 @@ class SettingSliderTableViewCell: UITableViewCell {
valueChanged?(item)
}
@objc private func sliderEnded(_ sender: UISlider) {
dragEnded?()
}
// MARK: - Public
@objc func configureSlider(with items: [EQNGenericValue], current: EQNGenericValue) {
@@ -12,6 +12,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface SettingsBaseViewController : UITableViewController
+ (void)saveSettings;
@end
NS_ASSUME_NONNULL_END
@@ -24,13 +24,13 @@
// when controller is dismissed, save settings
if (self.isMovingFromParentViewController) {
[self saveSettings];
[SettingsBaseViewController saveSettings];
}
}
#pragma mark - Private
- (void)saveSettings
+ (void)saveSettings
{
[[ServerRequest defaultServerConnectionSingleton] inviaInformazioniAlServerWithURL:[EQNGeneratoreURLServer urlInvioImpostazioniNotifiche] richiesta:impostazioniNotifiche success:^(id result){
NSLog(@"Settings saved successfully");
@@ -99,29 +99,29 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
- (void)updateUI
{
self.notificationEnabled = [EQNAllertaSismica center].isAbilitato;
self.doNotDisturbEnabled = [EQNAllertaSismica center].isintervalloAllarme;
self.notificationEnabled = [EQNAllertaSismica sharedInstance].isAbilitato;
self.doNotDisturbEnabled = [EQNAllertaSismica sharedInstance].isintervalloAllarme;
// sismi da notificare
EQNGenericValue *sismiDaNotificare = [EQNData seismicToNotifyFor:[EQNAllertaSismica center].sismiDaNotificare];
EQNGenericValue *sismiDaNotificare = [EQNData seismicToNotifyFor:[EQNAllertaSismica sharedInstance].sismiDaNotificare];
self.currentSeismicToNotify = sismiDaNotificare;
// raggio sismi lievi
EQNGenericValue *raggioSismiLievi = [EQNData raggioSismaFor:[EQNAllertaSismica center].raggioSismiLievi];
EQNGenericValue *raggioSismiLievi = [EQNData raggioSismaFor:[EQNAllertaSismica sharedInstance].raggioSismiLievi];
self.currentLowSeismicRadius = raggioSismiLievi;
// raggio sismi forti
EQNGenericValue *raggioSismiForti = [EQNData raggioSismaFor:[EQNAllertaSismica center].raggioSismiForti];
EQNGenericValue *raggioSismiForti = [EQNData raggioSismaFor:[EQNAllertaSismica sharedInstance].raggioSismiForti];
self.currentStrongSeismicRadius = raggioSismiForti;
// non disturbare, orari
NSDate *startTime = [EQNData doNotDisturbEndDateFrom:[EQNAllertaSismica center].oraioInizio];
NSDate *startTime = [EQNData doNotDisturbEndDateFrom:[EQNAllertaSismica sharedInstance].oraioInizio];
self.currentStartTime = startTime;
NSDate *endTime = [EQNData doNotDisturbEndDateFrom:[EQNAllertaSismica center].orarioFine];
NSDate *endTime = [EQNData doNotDisturbEndDateFrom:[EQNAllertaSismica sharedInstance].orarioFine];
self.currentEndTime = endTime;
[[EQNAllertaSismica center] saveUserInfo];
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self.tableView reloadData];
}
@@ -159,8 +159,8 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
cell.toggleSwitch.on = self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.notificationEnabled = enabled;
[EQNAllertaSismica center].isAbilitato = self.notificationEnabled;
[[EQNAllertaSismica center] saveUserInfo];
[EQNAllertaSismica sharedInstance].isAbilitato = self.notificationEnabled;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
} else if (indexPath.row == RowIdentifierNonDisturbare) {
@@ -168,8 +168,8 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
cell.isDisabled = !self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.doNotDisturbEnabled = enabled;
[EQNAllertaSismica center].isintervalloAllarme = self.doNotDisturbEnabled;
[[EQNAllertaSismica center] saveUserInfo];
[EQNAllertaSismica sharedInstance].isintervalloAllarme = self.doNotDisturbEnabled;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
}
@@ -250,36 +250,36 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
- (void)updateSismicToNotify:(EQNGenericValue *)seismic
{
[EQNAllertaSismica center].sismiDaNotificare = seismic.value;
[[EQNAllertaSismica center] saveUserInfo];
[EQNAllertaSismica sharedInstance].sismiDaNotificare = seismic.value;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateLowSeismicRadius:(EQNGenericValue *)radius
{
[EQNAllertaSismica center].raggioSismiLievi = radius.value;
[[EQNAllertaSismica center] saveUserInfo];
[EQNAllertaSismica sharedInstance].raggioSismiLievi = radius.value;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateStrongSeismicRadius:(EQNGenericValue *)radius
{
[EQNAllertaSismica center].raggioSismiForti = radius.value;
[[EQNAllertaSismica center] saveUserInfo];
[EQNAllertaSismica sharedInstance].raggioSismiForti = radius.value;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateStartTime:(NSDate *)date
{
[EQNAllertaSismica center].oraioInizio = date;
[[EQNAllertaSismica center] saveUserInfo];
[EQNAllertaSismica sharedInstance].oraioInizio = date;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateEndTime:(NSDate *)date
{
[EQNAllertaSismica center].orarioFine = date;
[[EQNAllertaSismica center] saveUserInfo];
[EQNAllertaSismica sharedInstance].orarioFine = date;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
@@ -7,7 +7,7 @@
//
#import "SettingsSeismicNetworkAlertsViewController.h"
#import "EQNNotificeReteSismiche.h"
#import "EQNNotificheReteSismiche.h"
@interface SettingsSeismicNetworkAlertsViewController ()
@@ -22,7 +22,6 @@
@property (nonatomic, strong) EQNGenericValue *currentUserPositionRadius;
@property (nonatomic, strong) EQNGenericValue *currentSeismicEnergy;
@property (nonatomic, strong) EQNGenericValue *currentNearEarthquakeDistance;
@property (nonatomic, strong) EQNGenericValue *currentStrongEarthquakeDistance;
@end
@@ -69,7 +68,8 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData];
[self updateUI];
}
#pragma mark - Private
@@ -88,32 +88,28 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
- (void)updateUI
{
self.notificationEnabled = [EQNNotificeReteSismiche center].isAbilitato;
self.notificationNearEarthquakeEnabled = [EQNNotificeReteSismiche center].isAbilitaVicini;
self.notificationStrongEarthquakeEnabled = [EQNNotificeReteSismiche center].isTerremortiForti;
self.notificationEnabled = [EQNNotificheReteSismiche sharedInstance].isAbilitato;
self.notificationNearEarthquakeEnabled = [EQNNotificheReteSismiche sharedInstance].isAbilitaVicini;
self.notificationStrongEarthquakeEnabled = [EQNNotificheReteSismiche sharedInstance].isTerremortiForti;
// raggio dalla tua posizione
EQNGenericValue *raggioSisma = [EQNData raggioSismaFor:[EQNNotificeReteSismiche center].distanzaPosizione];
EQNGenericValue *raggioSisma = [EQNData raggioSismaFor:[EQNNotificheReteSismiche sharedInstance].distanzaPosizione];
self.currentUserPositionRadius = raggioSisma;
// energia sisma
EQNGenericValue *energiaSisma = [EQNData magitudoDeboleFor:[EQNNotificeReteSismiche center].energiaSisma];
EQNGenericValue *energiaSisma = [EQNData magitudoDeboleFor:[EQNNotificheReteSismiche sharedInstance].energiaSisma];
self.currentSeismicEnergy = energiaSisma;
// terremoti vicini
EQNGenericValue *terremotiVicini = [EQNData raggioSismaFor:[EQNNotificeReteSismiche center].distanzaVicini];
self.currentNearEarthquakeDistance = terremotiVicini;
// terremoti forti
EQNGenericValue *terremotiForti = [EQNData magitudoForteFor:[EQNNotificeReteSismiche center].energiaTerremotiForti];
EQNGenericValue *terremotiForti = [EQNData magitudoForteFor:[EQNNotificheReteSismiche sharedInstance].energiaTerremotiForti];
self.currentStrongEarthquakeDistance = terremotiForti;
// enti
if (![EQNNotificeReteSismiche center].listaEnti) {
[EQNNotificeReteSismiche center].listaEnti = [EQNData.seismicNetworkAcronyms copy];
if (![EQNNotificheReteSismiche sharedInstance].listaEnti) {
[EQNNotificheReteSismiche sharedInstance].listaEnti = [EQNData.seismicNetworkAcronyms copy];
}
[[EQNNotificeReteSismiche center] saveUserInfo];
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self.tableView reloadData];
}
@@ -151,8 +147,8 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
cell.toggleSwitch.on = self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.notificationEnabled = enabled;
[EQNNotificeReteSismiche center].isAbilitato = self.notificationEnabled;
[[EQNNotificeReteSismiche center] saveUserInfo];
[EQNNotificheReteSismiche sharedInstance].isAbilitato = self.notificationEnabled;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
} else if (indexPath.row == RowIdentifierTerremotiVicini) {
@@ -160,8 +156,8 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
cell.isDisabled = !self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.notificationNearEarthquakeEnabled = enabled;
[EQNNotificeReteSismiche center].isAbilitaVicini = self.notificationNearEarthquakeEnabled;
[[EQNNotificeReteSismiche center] saveUserInfo];
[EQNNotificheReteSismiche sharedInstance].isAbilitaVicini = self.notificationNearEarthquakeEnabled;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
} else if (indexPath.row == RowIdentifierTerremotiForti) {
@@ -169,8 +165,8 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
cell.isDisabled = !self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.notificationStrongEarthquakeEnabled = enabled;
[EQNNotificeReteSismiche center].isTerremortiForti = self.notificationStrongEarthquakeEnabled;
[[EQNNotificeReteSismiche center] saveUserInfo];
[EQNNotificheReteSismiche sharedInstance].isTerremortiForti = self.notificationStrongEarthquakeEnabled;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
}
@@ -230,31 +226,31 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
- (void)updateUserPositionRadius:(EQNGenericValue *)radius
{
[EQNNotificeReteSismiche center].distanzaPosizione = radius.value;
[[EQNNotificeReteSismiche center] saveUserInfo];
[EQNNotificheReteSismiche sharedInstance].distanzaPosizione = radius.value;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateSeismicEnergy:(EQNGenericValue *)energy
{
[EQNNotificeReteSismiche center].energiaSisma = energy.value;
[[EQNNotificeReteSismiche center] saveUserInfo];
[EQNNotificheReteSismiche sharedInstance].energiaSisma = energy.value;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateStrongEarthquakeEnergy:(EQNGenericValue *)energy
{
[EQNNotificeReteSismiche center].energiaTerremotiForti = energy.value;
[[EQNNotificeReteSismiche center] saveUserInfo];
[EQNNotificheReteSismiche sharedInstance].energiaTerremotiForti = energy.value;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self updateUI];
}
- (NSString *)stringOfSelectedNetworks
{
NSArray *networks = [EQNNotificeReteSismiche center].listaEnti;
NSArray *networks = [EQNNotificheReteSismiche sharedInstance].listaEnti;
networks = [networks sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
return [networks componentsJoinedByString:@", "];
}
@@ -41,9 +41,8 @@ class SettingsSeismicNetworksViewController: UITableViewController {
let network = networks[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: SettingDetailTableViewCell.Identifier, for: indexPath) as! SettingDetailTableViewCell
cell.textLabel?.text = "\(network.acronym) (\(network.country))"
cell.detailTextLabel?.text = "Prova"
if EQNNotificeReteSismiche.center().listaEnti.contains(network.acronym) {
if EQNNotificheReteSismiche.shared().listaEnti.contains(network.acronym) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
@@ -57,15 +56,15 @@ class SettingsSeismicNetworksViewController: UITableViewController {
let network = networks[indexPath.row]
var savedNetworks = EQNNotificeReteSismiche.center().listaEnti
var savedNetworks = EQNNotificheReteSismiche.shared().listaEnti
if let index = savedNetworks.firstIndex(where: { $0 == network.acronym }) {
savedNetworks.remove(at: index)
} else {
savedNetworks.append(network.acronym)
}
EQNNotificeReteSismiche.center().listaEnti = savedNetworks
EQNNotificeReteSismiche.center().saveUserInfo()
EQNNotificheReteSismiche.shared().listaEnti = savedNetworks
EQNNotificheReteSismiche.shared().saveUserInfo()
tableView.reloadData()
}
@@ -50,11 +50,11 @@
- (void)updateUI
{
self.notificationsEnabled = [EQNNotificheSegnalazioniUtente center].isAbilitato;
self.notificationsEnabled = [EQNNotificheSegnalazioniUtente sharedInstance].isAbilitato;
EQNGenericValue *distanzaPosizione = [EQNData raggioSismaFor:[EQNNotificheSegnalazioniUtente center].distanzaPosizione];
EQNGenericValue *distanzaPosizione = [EQNData raggioSismaFor:[EQNNotificheSegnalazioniUtente sharedInstance].distanzaPosizione];
self.currentRadius = distanzaPosizione;
[[EQNNotificheSegnalazioniUtente center] saveUserInfo];
[[EQNNotificheSegnalazioniUtente sharedInstance] saveUserInfo];
[self.tableView reloadData];
}
@@ -62,8 +62,8 @@
- (void)updateRadius:(EQNGenericValue *)radius
{
self.currentRadius = radius;
[EQNNotificheSegnalazioniUtente center].distanzaPosizione = radius.value;
[[EQNNotificheSegnalazioniUtente center] saveUserInfo];
[EQNNotificheSegnalazioniUtente sharedInstance].distanzaPosizione = radius.value;
[[EQNNotificheSegnalazioniUtente sharedInstance] saveUserInfo];
[self.tableView reloadData];
}
@@ -98,8 +98,8 @@
cell.descriptionLabel.text = setting.subtitle;
cell.valueChanged = ^(BOOL enabled) {
self.notificationsEnabled = enabled;
[EQNNotificheSegnalazioniUtente center].isAbilitato = self.notificationsEnabled;
[[EQNNotificheSegnalazioniUtente center] saveUserInfo];
[EQNNotificheSegnalazioniUtente sharedInstance].isAbilitato = self.notificationsEnabled;
[[EQNNotificheSegnalazioniUtente sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
return cell;
@@ -105,7 +105,7 @@ class SettingsViewController: UITableViewController {
let cell = tableView.dequeueReusableCell(withIdentifier: SettingDetailTableViewCell.Identifier, for: indexPath) as! SettingDetailTableViewCell
cell.textLabel?.text = setting.displayTitle
if let icon = setting.icon {
cell.imageView?.tintColor = .darkGray
cell.imageView?.tintColor = cell.textLabel?.textColor
cell.imageView?.image = UIImage(named: icon)
}
cell.accessoryType = .disclosureIndicator
@@ -0,0 +1,115 @@
//
// EQNGenericPickerViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 13/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
/// Protocollo per rappresentare elementi nel picker generico
protocol PickerRepresentable {
var pickerTitle: String { get }
}
class EQNGenericPickerViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
typealias DoneCompletion = (PickerRepresentable) -> Void
var onCompletion: DoneCompletion?
var onCancel: (() -> Void)?
// MARK: - Properties
private var selectedIndex: Int?
private var items = [PickerRepresentable]()
private lazy var pickerView: UIPickerView = {
let picker = UIPickerView(frame: .zero)
picker.delegate = self
picker.dataSource = self
return picker
}()
private lazy var toolbar: UIToolbar = {
let toolbar = UIToolbar()
toolbar.barStyle = .default
toolbar.isTranslucent = true
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneTapped(_:)))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped(_:)))
toolbar.setItems([cancelButton, spaceButton, doneButton], animated: false)
return toolbar
}()
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .clear
toolbar.translatesAutoresizingMaskIntoConstraints = false
pickerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pickerView)
view.addSubview(toolbar)
pickerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
pickerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
pickerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
toolbar.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
toolbar.trailingAnchor.constraint(equalTo: pickerView.trailingAnchor).isActive = true
toolbar.leadingAnchor.constraint(equalTo: pickerView.leadingAnchor).isActive = true
}
// MARK: - Public
public func configure(with items: [PickerRepresentable], selectedIndex: Int? = nil, completion: @escaping DoneCompletion) {
self.onCompletion = completion
self.items = items
self.selectedIndex = items.count > 0 ? 1 : nil
self.pickerView.reloadAllComponents()
if let selectedIndex = selectedIndex, 0..<items.count ~= selectedIndex {
self.selectedIndex = selectedIndex
self.pickerView.selectRow(selectedIndex, inComponent: 0, animated: false)
}
}
// MARK: - Actions
@objc func doneTapped(_ sender: Any) {
guard let index = selectedIndex else {
return
}
onCompletion?(items[index])
}
@objc func cancelTapped(_ sender: Any) {
onCancel?()
}
// MARK: - UIPickerViewDataSource
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
items.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
items[row].pickerTitle
}
// MARK: - UIPickerViewDataDelegate
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedIndex = row
}
}
+38 -93
View File
@@ -9,8 +9,38 @@
#ifndef Costanti_h
#define Costanti_h
// costante gravitazionale
#define G 9.81
#pragma mark - Debug
/// Stampa le risposte delle chiamate al server
static BOOL const EQNDebugPrintResponse = NO;
#pragma mark - Urls
static NSString * const EQNWebsiteAddress = @"https://www.sismo.app";
static NSString * const EQNTwitterProfileUrl = @"https://twitter.com/SismoDetector";
#pragma mark - Math Constants
/// Costante gravitazionale
static double const EQNMathGravitational = 9.81;
/// Costante conversione gradi Celsius/Kelvin
static double const EQNMathKelvin = 273.15;
#pragma mark - Server APIs
/// Download reti sismiche
static NSString * const EQNServerUrlDownloadRetiSismiche = @"https://srv.earthquakenetwork.it/distquake_download_automatic18%@.php";
/// Recupera il tempo ancora disponibile per la versione Pro scontata
static NSString * const EQNServerUrlOfferTimeRemaining = @"https://srv.earthquakenetwork.it/distquake_download_offer_time_remaining.php";
/// Recupera il numero di sottoscrizioni ancora disponibili per ogni prodotto
static NSString * const EQNServerUrlAvailableSubscriptionsCounter = @"https://srv.earthquakenetwork.it/distquake_count_top_redis.php";
/// Carica le impostazioni delle notifiche definite dall'utente
static NSString * const EQNServerUrlUploadSettings = @"https://srv.earthquakenetwork.it/distquake_upload_settings_ios.php";
#pragma mark - UserDefaults Keys
static NSString * const EQNUserDefaultKeySesmicInformations = @"EQNetwork.SeismicInformations";
static NSString * const EQNUserDefaultKeyOneShotShowCountry = @"EQNetwork.OneShot.CountrySelection";
// URL registrazione server
#define URL_SERVER_REGISTRAZIONE @"http://srv.earthquakenetwork.it/distquake_upload_gcm_regid2.php"
@@ -26,43 +56,16 @@
#define URL_SERVER_AREA_CHECK @"http://srv.earthquakenetwork.it/distquake_download_areacheck.php"
// download pastquakes
#define URL_SERVER_PAST_QUAKES @"http://srv.earthquakenetwork.it/distquake_download_pastquakes.php"
// download Utenti disponibili
#define URL_SERVER_UTENTI_DISPONIBILI @"http://srv.earthquakenetwork.it/distquake_count_top_redis.php"
// download tempo disponibili passare a Pro
#define URL_SERVER_TEMPO_DISPONIBILI @"http://srv.earthquakenetwork.it/distquake_download_offer_status.php"
// download segnalazioni
#define URL_SERVER_DOWNLOAD_SEGNALAZIONI_UTENTE @"http://srv.earthquakenetwork.it/distquake_download_manual.php"
// Invio segnalazione
#define URL_SERVER_UPLOAD_SEGNALAZIONI_UTENTE @"http://srv.earthquakenetwork.it/distquake_upload_manual3.php"
#define URL_SERVER_UPLOAD_SEGNALAZIONI_COMMENTO_UTENTE @"http://srv.earthquakenetwork.it/distquake_upload_manual_message.php"
#define URL_SERVER_DOWNLOAD_OFFER_TIME_REMAINING @"http://srv.earthquakenetwork.it/distquake_download_offer_time_remaining.php"
// upload impostazioni // http://srv.earthquakenetwork.it/distquake_upload_settings8.php
#define URL_SERVER_UPLOAD_IMPOSTAZIONI @"http://srv.earthquakenetwork.it/distquake_upload_settings9.php"
#define URL_LINK_MESSAGGIO @"http://www.finazzieng.it/mysql/distquake_download_message.php"
// twitter
#define TWITTER_LINK @"https://twitter.com/SismoDetector"
#define TEMPO_INVIO_MESSAGGIO 5
#define TEMPO_INVIO_COMMENTO 30
// informazioni menu sinistra
static NSString * const EQNWebsiteAddress = @"https://www.sismo.app";
// download reti sismiche
#define URL_SERVER_DOWNLOAD_RETI_SISMICHE @"http://srv.earthquakenetwork.it/distquake_download_automatic14.php"
// Tsunami
#define URL_SERVER_DOWNLOAD_TSUNAMI @"http://srv.earthquakenetwork.it/distquake_download_tsunami.php"
// colori navigation bar
#define COLORE_BARRA_NAVIGAZIONE [UIColor colorWithRed:198.0/255.0 green:213.0/255.0 blue:247.0/255.0 alpha:1.0]
// colori celle tableview rete sismi
#define COLORE_CELLA_MAGNITUTE_LEGGERA [UIColor colorWithRed:208.0/255.0 green:234.0/255.0 blue:201.0/255.0 alpha:1.0]
#define COLORE_CELLA_MAGNITUTE_LEGGERA_ETI [UIColor colorWithRed:215.0/255.0 green:253.0/255.0 blue:210.0/255.0 alpha:1.0]
@@ -98,15 +101,6 @@ typedef enum : NSInteger {
unAnno
} EQNFiltriMappa;
// cella tipo Rete sismica
typedef enum : NSInteger {
defaultCell = 0,
mappaCell,
meteoCell
} EQNReteSismicaCell;
// dettagli Mappa tipo
typedef enum : NSInteger {
reteSmartphone = 0,
@@ -115,36 +109,7 @@ typedef enum : NSInteger {
} EQNTipoDettagliMappa;
// IMPOSTAZIONI NAZIONE RETE SISMICA
typedef enum : NSInteger {
mondo = 0,
italia,
spagna,
cina,
giappone,
nicaragua,
messico,
colombia,
costaRica,
chile,
venezuela,
nuovaZelanda,
argentina,
equador,
filippine,
perù,
repubblicaDomenicana,
altro
} EQNNazioneSelect;
typedef enum : NSInteger {
annulla = 0,
nazione,
enti
} EQNfiltroEnti;
// Chiave googleMaps
#define GOOGLE_MAP_KEY @"AIzaSyDc2V2vpBmbSnAisiN18rY17Dm7lzVWNAg"
@@ -173,15 +138,6 @@ typedef enum : NSInteger {
offerTimeRemaining
} EQNTipoChiamata;
// Manager
#define MANAGER_DATA_RETE_SMARTPHONE @"MANAGER_DATA_RETE_SMARTPHONE"
#define MANAGER_DATA_AREA_CHECK @"MANAGER_DATA_AREA_CHECK"
#define MANAGER_DATA_DATI_GRAFICO_UTENTI @"MANAGER_DATA_DATI_GRAFICO_UTENTI"
#define MANAGER_DATA_DATI_PASTQUAKES @"MANAGER_DATA_DATI_PASTQUAKES"
#define MANAGER_DATA_ELENCO_SEGNALAZIONI_MANUALI @"MANAGER_DATA_ELENCO_SEGNALAZIONI_MANUALI"
#define MANAGER_DATA_RETI_SISMICHE @"MANAGER_DATA_RETI_SISMICHE"
#define MANAGER_DATA_LISTA_TSUNAMI @"MANAGER_DATA_LISTA_TSUNAMI"
// chiavi rMax e rMin
#define rMax @"rMax"
@@ -265,19 +221,10 @@ typedef enum : NSInteger {
#define NOTIFICHE_ATTIVA_RETI_ENERGIA_FORTI @"NOTIFICHE_ATTIVA_RETI_ENERGIA_FORTI"
#define NOTIFICHE_ATTIVA_RETI_LISTA_ENTI @"NOTIFICHE_ATTIVA_RETI_LISTA_ENTI"
// Sigla della rete sismica selezionata
#define IMPOSTAZIONE_NAZIONE_RETI_SISMICHE @"IMPOSTAIONE_NAZIONE_RETI_SISMICHE"
#define IMPOSTAZIONE_NAZIONE_RETI_SISMICHEI @"IMPOSTAZIONE_NAZIONE_RETI_SISMICHEI"
#define IMPOSTAZIONE_ENTI_RETI_SISMICHEI @"IMPOSTAZIONE_ENTI_RETI_SISMICHEI"
#define IMPOSTAZIONE_TIPO_FILTRO_RETI_SISMICHEI @"IMPOSTAZIONE_TIPO_FILTRO_RETI_SISMICHEI"
/////////////////// Tsunami ////////////////////////////
#define NOTIFICHE_ORA_INIZIO_TSUNAMI @"NOTIFICHE_ORA_INIZIO_TSUNAMI"
#define NOTIFICHE_ORA_FINE_TSUNAMI @"NOTIFICHE_ORA_FINE_TSUNAMI"
#define NOTIFICHE_ABILITATO_TSUNAMI @"NOTIFICHE_ABILITATO_TSUNAMI"
#define NOTIFICHE_ABILITATO_ITERVALLO_TSUNAMI @"NOTIFICHE_ABILITATO_ITERVALLO_TSUNAMI"
#define NOTIFICHE_LISTA_MESSAGGI__TSUNAMI @"NOTIFICHE_LISTA_MESSAGGI__TSUNAMI"
#define NOTIFICHE_LISTA_AREE_INTERESSE_TSUNAMI @"NOTIFICHE_LISTA_AREE_INTERESSE_TSUNAMI"
/////////////////// Allera sismica ////////////////////////////
#define NOTIFICHE_ALLERA_SISMICA_ABILITATO @"NOTIFICHE_ALLERA_SISMICA_ABILITATO"
@@ -312,9 +259,7 @@ typedef enum : NSInteger {
#define EQN_MAGNITUDO_MINIMA @"EQN_MAGNITUDO_MINIMA"
#define EQN_DISTANZA_MASSIMA @"EQN_DISTANZA_MASSIMA"
#define EQN_ETA_MASSIMA @"EQN_ETA_MASSIMA"
#define EQN_SISMI_FORTI_ABILITATI @"EQN_SISMI_FORTI_ABILITATI"
#define EQN_SISMI_FORTI @"EQN_SISMI_FORTI"
#define IS_IPHONE ( [[[UIDevice currentDevice] model] isEqualToString:@"iPhone"] )
#define IS_HEIGHT_GTE_568 [[UIScreen mainScreen ] bounds].size.height <= 570.0f
#define IS_IPHONE_5 ( IS_IPHONE && IS_HEIGHT_GTE_568 )
#define EQN_SISMI_QUALSIASI_MAGNITUDO @"EQN_SISMI_QUALSIASI_MAGNITUDO"
#define EQN_SISMI_MODIFICA_IMPOSTAZIONI @"EQN_SISMI_MODIFICA_IMPOSTAZIONI"
@@ -6,4 +6,8 @@
#import "Costanti.h"
#import "EQNUser.h"
#import "EQNManager.h"
#import "EQNNotificeReteSismiche.h"
#import "EQNNotificheReteSismiche.h"
#import "EQNSisma.h"
#import "EQNBaseViewController.h"
#import "ReteSismiDettagliMappa.h"
#import "SettingsBaseViewController.h"
+6
View File
@@ -36,12 +36,18 @@
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSCalendarsUsageDescription</key>
<string>L'accesso al calendario è richiesto per poter salvare le informazioni dei sismi di interesse</string>
<key>NSContactsUsageDescription</key>
<string>L'accesso ai contatti è richiesto per poter aggiungere persone agli eventi creati</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string> Ci occorre la tua posizione per inviare messaggi precisi in caso di terremoto</string>
<key>NSLocationAlwaysUsageDescription</key>
<string> Ci occorre la tua posizione per inviare messaggi precisi in caso di terremoto</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string> Ci occorre la tua posizione per inviare messaggi precisi in caso di terremoto</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>L'accesso alla libreria è richiesto per poter salvare le immagini generate dall'app</string>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
@@ -0,0 +1,19 @@
//
// UIFont+Extensions.swift
// Earthquake Network
//
// Created by Busi Andrea on 25/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
extension UIFont {
static func preferredFont(for style: TextStyle, weight: Weight) -> UIFont {
let metrics = UIFontMetrics(forTextStyle: style)
let desc = UIFontDescriptor.preferredFontDescriptor(withTextStyle: style)
let font = UIFont.systemFont(ofSize: desc.pointSize, weight: weight)
return metrics.scaledFont(for: font)
}
}
@@ -11,7 +11,6 @@ import Foundation
public class EQNAppearanceCommand: EQNCommandProtocol {
// MARK: - Public
func execute() {
@@ -29,28 +28,28 @@ public class EQNAppearanceCommand: EQNCommandProtocol {
let navAppearance = UINavigationBarAppearance()
navAppearance.configureWithOpaqueBackground()
navAppearance.titleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.darkGray
NSAttributedString.Key.foregroundColor: AppTheme.Colors.darkGray
]
navAppearance.largeTitleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.darkGray
NSAttributedString.Key.foregroundColor: AppTheme.Colors.darkGray
]
navAppearance.backgroundColor = UIColor.eqn_primary
navAppearance.backgroundColor = AppTheme.Colors.primary
navAppearance.shadowColor = UIColor.clear
proxyNavBar.isTranslucent = false
proxyNavBar.tintColor = UIColor.darkGray
proxyNavBar.tintColor = AppTheme.Colors.darkGray
proxyNavBar.standardAppearance = navAppearance
proxyNavBar.scrollEdgeAppearance = navAppearance
} else {
proxyNavBar.tintColor = UIColor.darkGray
proxyNavBar.tintColor = AppTheme.Colors.darkGray
proxyNavBar.isTranslucent = false
proxyNavBar.barTintColor = UIColor.eqn_primary
proxyNavBar.barTintColor = AppTheme.Colors.primary
proxyNavBar.titleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.white
]
}
let proxyTabBar = UITabBar.appearance()
proxyTabBar.tintColor = UIColor(named: "Red")!
proxyTabBar.tintColor = AppTheme.Colors.red
}
}
@@ -16,7 +16,8 @@ public class EQNStartupCommandsBuilder: NSObject {
@objc
func build() -> [EQNCommandProtocol] {
return [
EQNAppearanceCommand()
EQNAppearanceCommand(),
EQNUserDefaultsCommand()
]
}
@@ -0,0 +1,40 @@
//
// EQNUserDefaultsCommand.swift
// Earthquake Network
//
// Created by Busi Andrea on 26/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
public class EQNUserDefaultsCommand: EQNCommandProtocol {
// MARK: - Public
func execute() {
print("EQNUserDefaultsCommand: start execute")
applyDefaultSettings()
saveMissingValues()
}
// MARK: - Private
private func applyDefaultSettings() {
// seismic card settings
if UserDefaults.standard.array(forKey: EQNUserDefaultKeySesmicInformations) == nil {
let informations: [SeismicNetworkTableViewCell.InformationType] = [.buttons, .distance, .coordinate, .population]
UserDefaults.standard.set(informations.map { $0.rawValue }, forKey: EQNUserDefaultKeySesmicInformations)
}
}
private func saveMissingValues() {
// `raggio sismi forti` was not saved before v2.3
if UserDefaults.standard.object(forKey: NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_FORTI) == nil {
UserDefaults.standard.set("600", forKey: NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_FORTI)
}
}
}
@@ -11,12 +11,13 @@ import Foundation
@objc class EQNData: NSObject {
private static let DefaultRaggioSisma = EQNGenericValue(value:"100000", display:"Qualsiasi distanza")
private static let DefaultMagitudoDebole = EQNGenericValue(value:"2.0", display:"Magnitudo >= 2.0")
private static let DefaultMagitudoForte = EQNGenericValue(value:"5.5", display:"Magnitudo >= 5.5")
private static let DefaultSeismicToNotify = EQNGenericValue(value: "0", display: "Qualsiasi intensità")
private static let DefaultDoNotDisturbStartTime = 8
private static let DefaultDoNotDisturbEndTime = 22
@objc public static let DefaultRaggioSisma = EQNGenericValue(value:"100000", display:"Qualsiasi distanza")
@objc public static let DefaultMagitudoDebole = EQNGenericValue(value:"2.0", display:"Magnitudo >= 2.0")
@objc public static let DefaultMagitudoForte = EQNGenericValue(value:"5.5", display:"Magnitudo >= 5.5")
@objc public static let DefaultSeismicToNotify = EQNGenericValue(value: "0", display: "Qualsiasi intensità")
@objc public static let DefaultDoNotDisturbStartTime = 8
@objc public static let DefaultDoNotDisturbEndTime = 22
@objc public static let DefaultPeriodoTemporale = EQNGenericValue(value: "1440", display: "Un giorno")
// MARK: - Public
@@ -49,6 +50,7 @@ import Foundation
@objc class func magitudoDeboli() -> [EQNGenericValue] {
[
EQNGenericValue(value:"0.0", display:"Magnitudo >= 0.0"),
EQNGenericValue(value:"0.5", display:"Magnitudo >= 0.5"),
EQNGenericValue(value:"1.0", display:"Magnitudo >= 1.0"),
EQNGenericValue(value:"1.5", display:"Magnitudo >= 1.5"),
@@ -95,7 +97,7 @@ import Foundation
@objc class func seismicNetworks() -> [EQNSeismicNetwork] {
[
EQNSeismicNetwork(acronym: "USGS", country: NSLocalizedString("Globale", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "USGS", country: NSLocalizedString("Stati Uniti", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "INGV", country: NSLocalizedString("Italia", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "IGN", country: NSLocalizedString("Spagna", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "CSI", country: NSLocalizedString("Cina", comment: ""), extended: ""),
@@ -111,7 +113,10 @@ import Foundation
EQNSeismicNetwork(acronym: "IGEPN", country: NSLocalizedString("Ecuador", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "IGP", country: NSLocalizedString("Perù", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "UASD", country: NSLocalizedString("Repubblica Dominicana", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "EMSC", country: NSLocalizedString("Globale", comment: ""), extended: "")
EQNSeismicNetwork(acronym: "NCS", country: NSLocalizedString("India", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "RSPR", country: NSLocalizedString("Porto Rico", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "BDTIM", country: NSLocalizedString("Turchia", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "EMSC", country: NSLocalizedString("Altro", comment: ""), extended: "")
]
}
@@ -119,6 +124,15 @@ import Foundation
Self.seismicNetworks().map { $0.acronym }
}
@objc class func seismicNetworkCountries() -> [String] {
Self.seismicNetworks().map { $0.country }
}
@objc class func seismic(for acronym: String?) -> EQNSeismicNetwork? {
guard let acronym = acronym else { return nil }
return Self.seismicNetworks().first(where: { $0.acronym == acronym })
}
@objc class func seismicToNotify() -> [EQNGenericValue] {
[
EQNGenericValue(value:"0", display:"Qualsiasi intensità"),
@@ -161,4 +175,25 @@ import Foundation
components.minute = 00
return calendar.date(from: components)!
}
@objc class func periodiTemporali() -> [EQNGenericValue] {
[
EQNGenericValue(value: "10", display: "10 minuti"),
EQNGenericValue(value: "60", display: "Un ora"),
EQNGenericValue(value: "120", display: "Due ore"),
EQNGenericValue(value: "360", display: "Sei ore"),
EQNGenericValue(value: "720", display: "Dodici ore"),
EQNGenericValue(value: "1440", display: "Un giorno")
]
}
/// Returns the EQNGenericValue for the given value, or the default one
/// - Parameter value: Temporal unit value to search
/// - Returns: Found value or default
@objc class func periodoTemporale(for value: String?) -> EQNGenericValue {
if let value = value, let genericValue = Self.periodiTemporali().first(where: { $0.value == value }) {
return genericValue
}
return Self.DefaultPeriodoTemporale
}
}
@@ -45,7 +45,7 @@ public class EQNPurchaseUtility: NSObject {
/// Returns availabilities for active subscriptions
/// - Parameter completion: Completion
static func availableSubscriptions(completion: @escaping (_ availability: EQNPurchaseAvailability?) -> Void) {
guard let url = URL(string: URL_SERVER_UTENTI_DISPONIBILI) else {
guard let url = URL(string: EQNServerUrlAvailableSubscriptionsCounter) else {
completion(nil)
return
}
@@ -0,0 +1,171 @@
//
// EQNSeismic.swift
// Earthquake Network
//
// Created by Busi Andrea on 20/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objc class EQNSeismic: NSObject {
@objc static let shared = EQNSeismic()
@objc var magnitudoMinima: String
@objc var distanzaMassima: String
@objc var periodoTemporale: String
@objc var sismiFortiAbilitati: Bool
@objc var sismiFortiMagnitudo: String
@objc var sismiQualsiasiAbilitati: Bool
@objc var modificaImpostazioniAbilitato: Bool
// MARK: - Init
override init() {
Self.migrateOldDistanza()
Self.migrateOldPeriodo()
magnitudoMinima = Self.userDefaults(for: EQN_MAGNITUDO_MINIMA, or: EQNData.DefaultMagitudoDebole.value)
distanzaMassima = Self.userDefaults(for: EQN_DISTANZA_MASSIMA, or: EQNData.DefaultRaggioSisma.value)
periodoTemporale = Self.userDefaults(for: EQN_ETA_MASSIMA, or: EQNData.DefaultPeriodoTemporale.value)
sismiFortiAbilitati = Self.userDefaults(for: EQN_SISMI_FORTI_ABILITATI, or: false)
sismiFortiMagnitudo = Self.userDefaults(for: EQN_SISMI_FORTI, or: EQNData.DefaultMagitudoForte.value)
sismiQualsiasiAbilitati = Self.userDefaults(for: EQN_SISMI_QUALSIASI_MAGNITUDO, or: false)
modificaImpostazioniAbilitato = Self.userDefaults(for: EQN_SISMI_MODIFICA_IMPOSTAZIONI, or: false)
super.init()
}
// MARK: - Public
public func saveFilters() {
UserDefaults.standard.set(magnitudoMinima, forKey:EQN_MAGNITUDO_MINIMA)
UserDefaults.standard.set(distanzaMassima, forKey:EQN_DISTANZA_MASSIMA)
UserDefaults.standard.set(periodoTemporale, forKey:EQN_ETA_MASSIMA)
UserDefaults.standard.set(sismiFortiMagnitudo, forKey:EQN_SISMI_FORTI)
UserDefaults.standard.set(sismiFortiAbilitati, forKey:EQN_SISMI_FORTI_ABILITATI)
UserDefaults.standard.set(sismiQualsiasiAbilitati, forKey:EQN_SISMI_QUALSIASI_MAGNITUDO)
UserDefaults.standard.set(modificaImpostazioniAbilitato, forKey:EQN_SISMI_MODIFICA_IMPOSTAZIONI)
}
// MARK: - Private
private static func userDefaults<T>(for key: String, or defaultValue: T) -> T {
if let value = UserDefaults.standard.object(forKey: key) as? T {
return value
}
return defaultValue
}
private static func migrateOldDistanza() {
guard let savedValue = UserDefaults.standard.object(forKey: EQN_DISTANZA_MASSIMA) as? String else {
print("[EQNSeismic] Distanza massima: nessun valore da convertire")
return
}
if savedValue.lowercased() == NSLocalizedString("Qualsiasi distanza", comment: "").lowercased() {
print("[EQNSeismic] Distanza massima: trovato qualsiasi distanza, salvo valore")
UserDefaults.standard.set("100000", forKey: EQN_DISTANZA_MASSIMA)
} else {
print("[EQNSeismic] Distanza massima: valore da non convertire (value: \(savedValue))")
}
}
private static func migrateOldPeriodo() {
guard let savedValue = UserDefaults.standard.object(forKey: EQN_ETA_MASSIMA) as? String else {
print("[EQNSeismic] Età massima: nessun valore da convertire");
return
}
var convertedValue: String?
if savedValue.lowercased() == NSLocalizedString("Un giorno", comment: "").lowercased() {
convertedValue = "1440"
} else if savedValue.lowercased() == NSLocalizedString("Dodici ore", comment: "").lowercased() {
convertedValue = "720"
} else if savedValue.lowercased() == NSLocalizedString("Sei ore", comment: "").lowercased() {
convertedValue = "360"
} else if savedValue.lowercased() == NSLocalizedString("Due ore", comment: "").lowercased() {
convertedValue = "120"
} else if savedValue.lowercased() == NSLocalizedString("Un ora", comment: "").lowercased() {
convertedValue = "60"
} else if savedValue.lowercased() == NSLocalizedString("Dieci minuti", comment: "").lowercased() {
convertedValue = "10"
}
if let convertedValue = convertedValue {
print("[EQNSeismic] Età massima: salvo valore convertito (old: \(savedValue) - new: \(convertedValue)")
UserDefaults.standard.set(convertedValue, forKey: EQN_ETA_MASSIMA)
} else {
print("[EQNSeismic] Età massima: valore già convertito")
}
}
// MARK: - Class
@objc func filterSeismicList(_ list: [EQNSisma]) -> [EQNSisma] {
// enti abilitati
let networks: [String]
if let savedNetworks = UserDefaults.standard.object(forKey: IMPOSTAZIONE_ENTI_RETI_SISMICHEI) as? [String] {
networks = savedNetworks
} else {
networks = EQNData.seismicNetworkAcronyms()
}
// filtri
let filterDistance = Double(distanzaMassima)
let filterMagnitude = Double(magnitudoMinima)
let filterShowNear = sismiQualsiasiAbilitati
let filterShowNearRadius: Double = 50.0
let filterStrongEarthquake = Double(sismiFortiMagnitudo)
let filterStrongEarthquakeEnabled = sismiFortiAbilitati
let filterTime = Double(periodoTemporale)
// filter seismic list
var filtered = [EQNSisma]()
for seismic in list {
var keep = true
if !networks.contains(seismic.provider) {
keep = false
}
// filtro distanza massima
if let filterDistance = filterDistance, seismic.userDistance > filterDistance {
keep = false
}
// filtro magnitudo minima e mostra sismi di qualsiasi magnitudo
if let filterMagnitude = filterMagnitude, seismic.magnitude.doubleValue < filterMagnitude {
if !filterShowNear {
keep = false
} else {
if seismic.userDistance > filterShowNearRadius {
keep = false
}
}
}
// filtro sismi forti
if let filterStrongEarthquake = filterStrongEarthquake, seismic.provider == "EMSC" && filterStrongEarthquakeEnabled && seismic.magnitude.doubleValue > filterStrongEarthquake {
keep = true
}
// filtro tempo
if let filterTime = filterTime, seismic.timeDifference > filterTime {
keep = false
}
if keep {
filtered.append(seismic)
}
}
return filtered
}
}
@@ -0,0 +1,49 @@
//
// EQNSisma.h
// Earthquake Network
//
// Refactored by Andrea Busi
// Copyright © 2020 Earthquake Network. All rights reserved.
//
@import Foundation;
@import CoreLocation;
NS_ASSUME_NONNULL_BEGIN
@interface EQNSisma : NSObject
/// Seismic latitude and longitude
@property (nonatomic, strong) CLLocation *coordinate;
/// Distance from user location (in km)
@property (nonatomic) CLLocationDistance userDistance;
@property (nonatomic, strong) NSNumber *depth;
@property (nonatomic, strong) NSNumber *magnitude;
@property (nonatomic, strong) NSString *magnitudeType;
/// Population inside the 100 km radius of the seismic
@property (nonatomic) double population100km;
@property (nonatomic, strong) NSNumber *intensity;
@property (nonatomic, strong) NSString *place;
@property (nonatomic, strong) NSString *provider;
/// Date of the seismic
@property (nonatomic, strong) NSDate *date;
/// Difference between seismic and user time (ex. 1 hour ago)
@property (nonatomic) NSTimeInterval timeDifference;
@property (nonatomic, strong) NSNumber *magnitudeRange;
@property (nonatomic, strong) NSNumber *preliminary;
@property (nonatomic, strong) NSNumber *smartphoneNumber;
@property (nonatomic, strong) NSNumber *userNumber;
@property (nonatomic, strong) NSString *weatherCode;
@property (nonatomic, strong) NSString *weatherIcon;
@property (nonatomic, strong) NSNumber *weatherCloud;
@property (nonatomic, strong) NSNumber *weatherWindSpeed;
@property (nonatomic, strong) NSNumber *weatherPressure;
@property (nonatomic, strong) NSNumber *weatherHumidity;
@property (nonatomic, strong) NSNumber *weatherTemperature;
@property (nonatomic, strong) NSNumber *pictureCount;
- (instancetype)initWithInfo:(NSDictionary *)info;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,118 @@
//
// EQNSisma.m
// Earthquake Network
//
// Refactored by Andrea Busi
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "EQNSisma.h"
#import "EQNUser.h"
#import "EQNUtility.h"
@implementation EQNSisma
#pragma mark - Init
- (instancetype)initWithInfo:(NSDictionary *)info
{
self = [super init];
if (self) {
double latitude = [info[@"la"] doubleValue];
double longitude = [info[@"lo"] doubleValue];
self.coordinate = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
CLLocationDistance distance = [[EQNUser defaultUser].lastPosition distanceFromLocation:self.coordinate];
self.userDistance = distance/1000;
self.depth = info[@"de"];
self.magnitude = info[@"ma"];
self.magnitudeType = info[@"mt"];
// convert from log base 10
double pop100 = [info[@"p1"] doubleValue];
self.population100km = pow(10, pop100 / 1000);
self.intensity = info[@"it"];
self.place = info[@"pl"];
self.provider = info[@"pr"];
self.date = [EQNUtility getDataFromString:info[@"dt"]];
self.timeDifference = [info[@"di"] doubleValue];
self.magnitudeRange = info[@"mr"];
self.preliminary = info[@"py"];
self.smartphoneNumber = info[@"sm"];
self.userNumber = info[@"rp"];
self.weatherCode = info[@"wc"];
self.weatherIcon = info[@"ic"];
self.weatherCloud = info[@"cl"];
self.weatherWindSpeed = info[@"ws"];
self.weatherPressure = info[@"pe"];
self.weatherHumidity = info[@"hu"];
self.weatherTemperature = info[@"te"];
self.pictureCount = info[@"pc"];
}
return self;
}
#pragma mark - NSCoding
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.coordinate forKey:@"coordinate"];
[encoder encodeDouble:self.userDistance forKey:@"distance"];
[encoder encodeObject:self.depth forKey:@"depth"];
[encoder encodeObject:self.magnitude forKey:@"magnitude"];
[encoder encodeObject:self.magnitudeType forKey:@"magnitudeType"];
[encoder encodeDouble:self.population100km forKey:@"population100km"];
[encoder encodeObject:self.intensity forKey:@"intensity"];
[encoder encodeObject:self.place forKey:@"place"];
[encoder encodeObject:self.provider forKey:@"provider"];
[encoder encodeObject:self.date forKey:@"date"];
[encoder encodeDouble:self.timeDifference forKey:@"timeDifference"];
[encoder encodeObject:self.magnitudeRange forKey:@"magnitudeRange"];
[encoder encodeObject:self.preliminary forKey:@"preliminary"];
[encoder encodeObject:self.smartphoneNumber forKey:@"smartphoneNumber"];
[encoder encodeObject:self.userNumber forKey:@"userNumber"];
[encoder encodeObject:self.weatherCode forKey:@"weatherCode"];
[encoder encodeObject:self.weatherIcon forKey:@"weatherIcon"];
[encoder encodeObject:self.weatherCloud forKey:@"weatherCloud"];
[encoder encodeObject:self.weatherWindSpeed forKey:@"weatherWindSpeed"];
[encoder encodeObject:self.weatherPressure forKey:@"weatherPressure"];
[encoder encodeObject:self.weatherHumidity forKey:@"weatherHumidity"];
[encoder encodeObject:self.weatherTemperature forKey:@"weatherTemperature"];
[encoder encodeObject:self.pictureCount forKey:@"pictureCount"];
}
- (instancetype)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if(self) {
self.coordinate = [decoder decodeObjectForKey:@"coordinate"];
self.userDistance = [decoder decodeDoubleForKey:@"distance"];
self.depth = [decoder decodeObjectForKey:@"depth"];
self.magnitude = [decoder decodeObjectForKey:@"magnitude"];
self.magnitudeType = [decoder decodeObjectForKey:@"magnitudeType"];
self.population100km = [decoder decodeDoubleForKey:@"population100km"];
self.intensity = [decoder decodeObjectForKey:@"intensity"];
self.place = [decoder decodeObjectForKey:@"intensity"];
self.provider = [decoder decodeObjectForKey:@"provider"];
self.date = [decoder decodeObjectForKey:@"date"];
self.timeDifference = [decoder decodeDoubleForKey:@"timeDifference"];
self.magnitudeRange = [decoder decodeObjectForKey:@"magnitudeRange"];
self.preliminary = [decoder decodeObjectForKey:@"preliminary"];
self.smartphoneNumber = [decoder decodeObjectForKey:@"smartphoneNumber"];
self.userNumber = [decoder decodeObjectForKey:@"userNumber"];
self.weatherCode = [decoder decodeObjectForKey:@"weatherCode"];
self.weatherIcon = [decoder decodeObjectForKey:@"weatherIcon"];
self.weatherCloud = [decoder decodeObjectForKey:@"weatherCloud"];
self.weatherWindSpeed = [decoder decodeObjectForKey:@"weatherWindSpeed"];
self.weatherPressure = [decoder decodeObjectForKey:@"weatherPressure"];
self.weatherHumidity = [decoder decodeObjectForKey:@"weatherHumidity"];
self.weatherTemperature = [decoder decodeObjectForKey:@"weatherTemperature"];
self.pictureCount = [decoder decodeObjectForKey:@"pictureCount"];
}
return self;
}
@end
@@ -1,18 +0,0 @@
//
// UIColor+EQN.swift
// Earthquake Network
//
// Created by Busi Andrea on 14/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
extension UIColor {
@objc(eqn_primaryColor)
class var eqn_primary: UIColor {
UIColor(red: 198.0/255.0, green: 213.0/255.0, blue: 247.0/255.0, alpha: 1.0)
}
}
@@ -22,4 +22,24 @@ class EQNSeismicNetwork: NSObject {
self.country = country
self.extended = extended
}
// MARK: - Equatable
override func isEqual(_ object: Any?) -> Bool {
if let anObject = object as? EQNSeismicNetwork {
return anObject.acronym.lowercased() == acronym.lowercased()
}
return false
}
override var hash: Int {
acronym.hash
}
}
extension EQNSeismicNetwork: PickerRepresentable {
var pickerTitle: String {
country
}
}
@@ -2,8 +2,8 @@
// EQNAllertaSismica.h
// Earthquake Network
//
// Created by Luca Beretta on 15/01/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 21/09/2020
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -13,7 +13,6 @@ NS_ASSUME_NONNULL_BEGIN
@interface EQNAllertaSismica : NSObject
@property (nonatomic, assign) BOOL isAbilitato;
@property (nonatomic, assign) BOOL isSimiSenzaIntensita;
@property (nonatomic, assign) BOOL isintervalloAllarme;
@property (nonatomic, strong) NSString *sismiDaNotificare;
@@ -26,9 +25,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong) NSArray *listaMessaggi;
@property (nonatomic, strong) NSArray *listaAreeInteresse;
+ (instancetype)center;
+ (instancetype)sharedInstance NS_SWIFT_NAME(shared());
- (void)saveUserInfo;
+ (void)saveDefaultValues;
@end
NS_ASSUME_NONNULL_END
@@ -2,18 +2,19 @@
// EQNAllertaSismica.m
// Earthquake Network
//
// Created by Luca Beretta on 15/01/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 21/09/2020
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "EQNAllertaSismica.h"
#import "Costanti.h"
@implementation EQNAllertaSismica
#pragma mark - Singleton
+ (instancetype)center
+ (instancetype)sharedInstance
{
static EQNAllertaSismica *instance = nil;
static dispatch_once_t onceToken;
@@ -29,10 +30,10 @@
{
self = [super init];
if (self) {
self.isAbilitato = [[NSUserDefaults standardUserDefaults] boolForKey:NOTIFICHE_ALLERA_SISMICA_ABILITATO];
self.isSimiSenzaIntensita = NO; // parametro rimosso dalle impostazioni, manteniamo l'invio al server come false
self.isAbilitato = [[NSUserDefaults standardUserDefaults] boolForKey:NOTIFICHE_ALLERA_SISMICA_ABILITATO];
self.sismiDaNotificare = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_ALLERA_SISMICA_SISMI_DA_NOTIFICARE];
self.raggioSismiLievi = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_LIEVI];
self.raggioSismiForti = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_FORTI];
self.tonoAllarme = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_ALLERA_SISMICA_TONO_ALLARME];
if (!self.tonoAllarme) {
self.tonoAllarme = @"alert_star_trek.wav";
@@ -51,6 +52,7 @@
[[NSUserDefaults standardUserDefaults] setBool:self.isAbilitato forKey:NOTIFICHE_ALLERA_SISMICA_ABILITATO];
[[NSUserDefaults standardUserDefaults] setObject:self.sismiDaNotificare forKey:NOTIFICHE_ALLERA_SISMICA_SISMI_DA_NOTIFICARE];
[[NSUserDefaults standardUserDefaults] setObject:self.raggioSismiLievi forKey:NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_LIEVI];
[[NSUserDefaults standardUserDefaults] setObject:self.raggioSismiLievi forKey:NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_FORTI];
[[NSUserDefaults standardUserDefaults] setObject:self.tonoAllarme forKey:NOTIFICHE_ALLERA_SISMICA_TONO_ALLARME];
[[NSUserDefaults standardUserDefaults] setBool:self.isintervalloAllarme forKey:NOTIFICHE_ALLERA_SISMICA_ABILITA_INTERVALLO];
[[NSUserDefaults standardUserDefaults] setObject:self.oraioInizio forKey:NOTIFICHE_ALLERA_SISMICA_ORA_INIZIO];
@@ -58,4 +60,15 @@
[[NSUserDefaults standardUserDefaults] synchronize];
}
#pragma mark - Class
+ (void)saveDefaultValues
{
[EQNAllertaSismica sharedInstance].isAbilitato = YES;
[EQNAllertaSismica sharedInstance].sismiDaNotificare = @"0";
[EQNAllertaSismica sharedInstance].raggioSismiLievi = @"300";
[EQNAllertaSismica sharedInstance].raggioSismiForti = @"600";
[[EQNAllertaSismica sharedInstance] saveUserInfo];
}
@end
@@ -1,16 +1,16 @@
//
// EQNNotificeReteSismiche.h
// EQNNotificheReteSismiche.h
// Earthquake Network
//
// Created by Luca Beretta on 10/01/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 21/09/2020
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface EQNNotificeReteSismiche : NSObject
@interface EQNNotificheReteSismiche : NSObject
@property (nonatomic, assign) BOOL isAbilitato;
@property (nonatomic, assign) BOOL isAbilitaVicini;
@@ -18,12 +18,12 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong) NSArray<NSString *> *listaEnti;
@property (nonatomic, strong) NSString *distanzaPosizione;
@property (nonatomic, strong) NSString *energiaSisma;
@property (nonatomic, strong) NSString *distanzaVicini;
@property (nonatomic, strong) NSString *energiaTerremotiForti;
+(EQNNotificeReteSismiche *)center;
-(void)saveUserInfo;
-(void)removeUser;
+ (instancetype)sharedInstance NS_SWIFT_NAME(shared());
- (void)saveUserInfo;
+ (void)saveDefaultValues;
@end
@@ -0,0 +1,72 @@
//
// EQNNotificheReteSismiche.m
// Earthquake Network
//
// Refactored by Andrea Busi on 21/09/2020
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "EQNNotificheReteSismiche.h"
#import "Costanti.h"
#import "EQNUtility.h"
@implementation EQNNotificheReteSismiche
#pragma mark - Singleton
+ (instancetype)sharedInstance
{
static EQNNotificheReteSismiche *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
#pragma mark - Init
- (instancetype)init
{
self = [super init];
if (self) {
self.isAbilitato = [[NSUserDefaults standardUserDefaults] boolForKey:NOTIFICHE_ATTIVA_RETI_SISMICHE];
self.isAbilitaVicini = [[NSUserDefaults standardUserDefaults] boolForKey:NOTIFICHE_ATTIVA_RETI_SISMICHE_VICINE];
self.isTerremortiForti = [[NSUserDefaults standardUserDefaults] boolForKey:NOTIFICHE_ATTIVA_RETI_TERREMOTI_FORTI];
self.distanzaPosizione = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_DISTANZA_POSIZIONE_RETI_SISMICHE];
self.energiaSisma = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_ATTIVA_RETI_ENERGIA_SISMI];
self.energiaTerremotiForti = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_ATTIVA_RETI_ENERGIA_FORTI];
self.listaEnti = (NSArray *)[EQNUtility loadCustomObjectWithKey:NOTIFICHE_ATTIVA_RETI_LISTA_ENTI];
}
return self;
}
#pragma mark - Public
- (void)saveUserInfo
{
[[NSUserDefaults standardUserDefaults] setObject:self.distanzaPosizione forKey:NOTIFICHE_DISTANZA_POSIZIONE_RETI_SISMICHE];
[[NSUserDefaults standardUserDefaults] setObject:self.energiaSisma forKey:NOTIFICHE_ATTIVA_RETI_ENERGIA_SISMI];
[[NSUserDefaults standardUserDefaults] setObject:self.energiaTerremotiForti forKey:NOTIFICHE_ATTIVA_RETI_ENERGIA_FORTI];
[[NSUserDefaults standardUserDefaults] setBool:self.isAbilitato forKey:NOTIFICHE_ATTIVA_RETI_SISMICHE];
[[NSUserDefaults standardUserDefaults] setBool:self.isAbilitaVicini forKey:NOTIFICHE_ATTIVA_RETI_SISMICHE_VICINE];
[[NSUserDefaults standardUserDefaults] setBool:self.isTerremortiForti forKey:NOTIFICHE_ATTIVA_RETI_TERREMOTI_FORTI];
[EQNUtility saveCustomObject:self.listaEnti key:NOTIFICHE_ATTIVA_RETI_LISTA_ENTI];
[[NSUserDefaults standardUserDefaults] synchronize];
}
#pragma mark - Class
+ (void)saveDefaultValues
{
[EQNNotificheReteSismiche sharedInstance].isAbilitato = YES;
[EQNNotificheReteSismiche sharedInstance].distanzaPosizione = @"1000";
[EQNNotificheReteSismiche sharedInstance].energiaSisma = @"3.5";
[EQNNotificheReteSismiche sharedInstance].isAbilitaVicini = NO;
[EQNNotificheReteSismiche sharedInstance].isTerremortiForti = NO;
[EQNNotificheReteSismiche sharedInstance].energiaTerremotiForti = @"7.5";
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
}
@end
@@ -2,8 +2,8 @@
// EQNNotificheSegnalazioniUtente.h
// Earthquake Network
//
// Created by Luca Beretta on 10/01/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 21/09/2020
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -16,9 +16,10 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong) NSString *distanzaPosizione;
+(EQNNotificheSegnalazioniUtente *)center;
-(void)saveUserInfo;
-(void)removeUser;
+ (instancetype)sharedInstance NS_SWIFT_NAME(shared());
- (void)saveUserInfo;
+ (void)saveDefaultValues;
@end
@@ -0,0 +1,56 @@
//
// EQNNotificheSegnalazioniUtente.m
// Earthquake Network
//
// Refactored by Andrea Busi on 21/09/2020
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "EQNNotificheSegnalazioniUtente.h"
#import "Costanti.h"
@implementation EQNNotificheSegnalazioniUtente
#pragma mark - Singleton
+ (instancetype)sharedInstance
{
static EQNNotificheSegnalazioniUtente *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
#pragma mark - Init
- (instancetype)init
{
self = [super init];
if (self) {
self.isAbilitato = [[NSUserDefaults standardUserDefaults] boolForKey:NOTIFICHE_SU_ATTIVA_SEGNALAZIONE_UTENTE];
self.distanzaPosizione = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_SU_DISTANZA_POSIZIONE];
}
return self;
}
#pragma mark - Public
- (void)saveUserInfo
{
[[NSUserDefaults standardUserDefaults] setObject:self.distanzaPosizione forKey:NOTIFICHE_SU_DISTANZA_POSIZIONE];
[[NSUserDefaults standardUserDefaults] setBool:self.isAbilitato forKey:NOTIFICHE_SU_ATTIVA_SEGNALAZIONE_UTENTE];
[[NSUserDefaults standardUserDefaults] synchronize];
}
#pragma mark - Class
+ (void)saveDefaultValues
{
[EQNNotificheSegnalazioniUtente sharedInstance].isAbilitato = YES;
[EQNNotificheSegnalazioniUtente sharedInstance].distanzaPosizione = @"300";
[[EQNNotificheSegnalazioniUtente sharedInstance] saveUserInfo];
}
@end
@@ -1,6 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "navbar-icon-arrow-collapse.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "navbar-icon-arrow-collapse@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "navbar-icon-arrow-collapse@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "navbar-icon-arrow-expand.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "navbar-icon-arrow-expand@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "navbar-icon-arrow-expand@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "navbar-icon-earth.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "navbar-icon-earth@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "navbar-icon-earth@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "bell.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "bell@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "bell@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "bell_disabled.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "bell_disabled@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "bell_disabled@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "icon-arrow-down.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
@@ -0,0 +1,50 @@
%PDF-1.4
%Óëéá
1 0 obj
<</Producer (Adobe XD)>>
endobj
3 0 obj
<</ca 1
/BM /Normal>>
endobj
4 0 obj
<</Filter /FlateDecode
/Length 97>> stream
xœEK
€@ C÷9E/`í´'píu1³ï:H „—„5<ø ®´6œðv4›©XoÆÙh¿ ;4jðÀbIS¢ÉÙÒ¤¹PEQ–¬ÁýÖÿSq`ÂÁª
endstream
endobj
2 0 obj
<</Type /Page
/Resources <</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
/ExtGState <</G3 3 0 R>>>>
/MediaBox [0 0 83 42]
/Contents 4 0 R
/StructParents 0
/Parent 5 0 R>>
endobj
5 0 obj
<</Type /Pages
/Count 1
/Kids [2 0 R]>>
endobj
6 0 obj
<</Type /Catalog
/Pages 5 0 R>>
endobj
xref
0 7
0000000000 65535 f
0000000015 00000 n
0000000258 00000 n
0000000055 00000 n
0000000092 00000 n
0000000444 00000 n
0000000499 00000 n
trailer
<</Size 7
/Root 6 0 R
/Info 1 0 R>>
startxref
546
%%EOF
@@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "share_icon.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
@@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "255",
"green" : "200",
"red" : "131"
"blue" : "0x26",
"green" : "0x22",
"red" : "0x1C"
}
},
"idiom" : "universal"
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0xFF",
"green" : "0xCE",
"red" : "0xA3"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
+12 -11
View File
@@ -1,30 +1,31 @@
//
// ServerRequest.h
// Telegea
// Earthquake Network
//
// Created by Luca Beretta on 15/02/17.
// Copyright © 2017 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 25/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "Costanti.h"
NS_ASSUME_NONNULL_BEGIN
typedef void (^successCompletionHandler)(id _Nullable result);
typedef void (^errorCompletionHandler)(NSError * _Nullable error);
@interface ServerRequest : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate>
@property (nonatomic) BOOL isConnect;
+(ServerRequest *) defaultServerConnectionSingleton;
+ (instancetype)defaultServerConnectionSingleton;
-(void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata )chiamata success:(void(^)(id result)) success failure:(void(^)(NSError *))failure;
- (void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata)chiamata success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure;
-(void)inviaRicevuta:(NSData *)ricevuta success:(void(^)(id result)) success failure:(void(^)(NSError *))failure;
- (void)inviaRicevuta:(NSData *)ricevuta success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure;
/*
-(void)sendGetMethod:(NSURLRequest *)request typeRequest:(TypeRequest)type success:(void(^)(id dictionary)) success failure:(void(^)(NSError *))failure;
-(UIAlertController *)mostraAllertWithMessage:(NSString *)messaggio close:(void(^)(BOOL terminato))terminato;
*/
@end
NS_ASSUME_NONNULL_END
+122 -424
View File
@@ -1,9 +1,9 @@
//
// ServerRequest.m
// Telegea
// Earthquake Network
//
// Created by Luca Beretta on 15/02/17.
// Copyright © 2017 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 25/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "ServerRequest.h"
@@ -12,91 +12,76 @@
#import "EQNUtility.h"
#import "NSDictionary+BVJSONString.h"
//#import "User.h"
//#import "Portachiavi.h"
@interface ServerRequest (){
NSURLSession *session;
}
@property (nonatomic) Reachability *hostReachability;
@interface ServerRequest ()
@property (strong, nonatomic) NSURLSession *session;
@property (nonatomic) Reachability *internetReachability;
@end
@implementation ServerRequest
static ServerRequest *_sharedInstance = nil;
#pragma mark - Singleton
+(ServerRequest *) defaultServerConnectionSingleton{
@synchronized (_sharedInstance) {
+ (instancetype)defaultServerConnectionSingleton
{
static ServerRequest *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
#pragma mark - Init
- (instancetype)init
{
self = [super init];
if (self) {
NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:config];
if (_sharedInstance == nil){
_sharedInstance = [[ServerRequest alloc] init];
}
[_sharedInstance initSingleton];
return _sharedInstance;
// registro notifiche rilevamento connessione
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
self.internetReachability = [Reachability reachabilityForInternetConnection];
[self.internetReachability startNotifier];
[self setValue:@([self updateConnectionReachability:self.internetReachability]) forKey:@"isConnect"];
}
return self;
}
#pragma mark - Reachability notifications
/// Called by Reachability whenever status changes.
- (void)reachabilityChanged:(NSNotification *)notification
{
if ([notification.object isKindOfClass:[Reachability class]]) {
Reachability *curReach = [notification object];
[self setValue:@([self updateConnectionReachability:curReach]) forKey:@"isConnect"];
}
}
-(void)initSingleton{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
session = [NSURLSession sessionWithConfiguration:config];
// registro notifiche rilevamento connessione
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
NSString *remoteHostName = @"http://srv.earthquakenetwork.it";
self.hostReachability = [Reachability reachabilityWithHostName:remoteHostName];
[self.hostReachability startNotifier];
[self setValue:@([self updateConnectionhReachability:self.hostReachability]) forKey:@"isConnect"];
// self.isConnect = [self updateConnectionhReachability:self.hostReachability];
self.internetReachability = [Reachability reachabilityForInternetConnection];
[self.internetReachability startNotifier];
// self.isConnect = [self updateConnectionhReachability:self.internetReachability];
[self setValue:@([self updateConnectionhReachability:self.internetReachability]) forKey:@"isConnect"];
#pragma mark - Private
}
/*!
* Called by Reachability whenever status changes.
*/
- (void) reachabilityChanged:(NSNotification *)note
{
Reachability* curReach = [note object];
NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
// self.isConnect = [self updateConnectionhReachability:curReach];
[self setValue:@([self updateConnectionhReachability:curReach]) forKey:@"isConnect"];
}
- (BOOL)updateConnectionhReachability:(Reachability *)reachability
- (BOOL)updateConnectionReachability:(Reachability *)reachability
{
NetworkStatus netStatus = [reachability currentReachabilityStatus];
switch (netStatus) {
case NotReachable:
return NO;
break;
default:
return YES;
break;
case NotReachable: return NO;
default: return YES;
}
}
-(void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata )chiamata success:(void(^)(id result)) success failure:(void(^)(NSError *))failure{
#pragma mark - Public
- (void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata)chiamata success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure
{
if (!self.isConnect) {
NSLog(@"[ServerRequest] not connected, return error");
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:401 userInfo:@{MESSAGGIO : NSLocalizedString(@"Nessuna connessione", @"messaggio assenza connesione")}];
failure(error);
onFailure(error);
// todo Andrea: perchè non viene fatto return? era già così
}
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
@@ -106,166 +91,76 @@ static ServerRequest *_sharedInstance = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
});
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
if (error) {
NSLog(@"[ServerRequest] response error: %@", error.localizedDescription);
onFailure(error);
return;
}
if(!error){
NSError *jsonError;
// NSData *myRequestData = [response dataUsingEncoding:NSUTF8StringEncoding];
id JSON = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&jsonError];
if (!jsonError){
switch (httpResp.statusCode) {
case 200:
switch (chiamata) {
case registrazione:
success(JSON);
break;
case posizione:
success(@"success");
break;
case calibrazione:
success(JSON);
break;
case rilevamento:
success(JSON);
break;
case downloadDati:
success(JSON);
break;
case graficoSmartPhone:
success(JSON);
break;
case areaCheck:
success(JSON);
break;
case pastquakes:
success(JSON);
break;
case utentiDisponibili:
success(JSON);
break;
case segnalazioneManuale:
success(JSON);
break;
case tsunami:
success(JSON);
break;
case segnalazzioneTerremoto:
success(JSON);
break;
case commentoTerremoto:
success(JSON);
break;
case tempoDisponibile:
success(JSON);
break;
case impostazioniNotifiche:
success(JSON);
break;
case offerTimeRemaining:
success(JSON);
default:
break;
}
// NSLog(@"Risultato richiesta server %@", JSON);
// success(@"");
dispatch_async(dispatch_get_main_queue(), ^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
}
NSError *jsonError;
id JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
if (!jsonError){
if (EQNDebugPrintResponse) {
NSLog(@"[ServerRequest] response json: %@", JSON);
}
else{
NSString* newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (newStr) {
if (chiamata == segnalazzioneTerremoto) {
NSLog(@"risultato segnalazione %@", [EQNUtility clearStringMessaggi:newStr]);
success([EQNUtility clearStringMessaggi:newStr]);
switch (httpResp.statusCode) {
case 200:
switch (chiamata) {
case posizione:
onSuccess(@"success");
break;
default:
onSuccess(JSON);
break;
}
if (chiamata == rilevamento) {
/// NSLog(@"newStr %@", newStr);
success([EQNUtility clearStringMessaggi:newStr]);
}
if (chiamata == registrazione) {
NSLog(@"newStr %@", newStr);
}
if (chiamata == tempoDisponibile) {
NSLog(@"newStr %@", newStr);
}
if (chiamata == calibrazione) {
NSLog(@"calibrazione %@", newStr);
success(newStr);
}
if (chiamata == rilevamento) {
success(newStr);
}
if (chiamata == impostazioniNotifiche) {
NSLog(@"impostazioniNotifiche %@", newStr);
success(newStr);
}
if (chiamata == segnalazioneManuale) {
NSLog(@"segnalazioneManuale %@", newStr);
}
} else{
NSLog(@"Error %@", [jsonError description]);
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:0 userInfo:@{MESSAGGIO : NSLocalizedString(@"Username e Password sbagliati", @"messaggio errore inserimento credenziali")}];
failure(error);
dispatch_async(dispatch_get_main_queue(), ^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
}
}
} else {
NSString *newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (newStr) {
if (EQNDebugPrintResponse) {
NSLog(@"[ServerRequest] response string: %@", newStr);
}
switch (chiamata) {
case segnalazzioneTerremoto:
onSuccess([EQNUtility clearStringMessaggi:newStr]);
break;
case rilevamento:
onSuccess([EQNUtility clearStringMessaggi:newStr]);
break;
case calibrazione:
onSuccess(newStr);
break;
case impostazioniNotifiche:
onSuccess(newStr);
default:
// don't call the callback
break;
}
} else {
NSLog(@"[ServerRequest] Unable to create string with response: %@", [jsonError description]);
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:0 userInfo:@{MESSAGGIO : NSLocalizedString(@"Username e Password sbagliati", @"messaggio errore inserimento credenziali")}];
onFailure(error);
dispatch_async(dispatch_get_main_queue(), ^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
}
}
}];
[dataTask resume];
}
-(void)inviaRicevuta:(NSData *)ricevuta success:(void(^)(id result)) success failure:(void(^)(NSError *))failure{
- (void)inviaRicevuta:(NSData *)ricevuta success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure
{
NSString *jsonObjectString = [ricevuta base64EncodedStringWithOptions:0];
// NSString* BASEURl = @"XXXXXXXXX/XXX/XXXX";
// NSString *testReceipt= [BASEURl stringByAppendingString:@"/InApp/iOS/updatePurchase"];
NSDictionary *params = @{@"ricevuta" :jsonObjectString};
NSString *parametri = [params bv_jsonStringWithPrettyPrint:YES];
@@ -275,226 +170,29 @@ static ServerRequest *_sharedInstance = nil;
[urlRequest addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[urlRequest setHTTPBody:[parametri dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
if(!error){
NSError *jsonError;
// NSData *myRequestData = [response dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&jsonError];
if (!jsonError){
switch (httpResp.statusCode) {
case 200:
success(JSON);
break;
default:
NSLog(@"httpResp.statusCode %ld", (long)httpResp.statusCode);
break;
}
}
}
else{
failure(error.userInfo[@"NSLocalizedDescription"]);
NSLog(@"Error %@", error.userInfo);
if (error) {
NSLog(@"[ServerRequest] inviaRicevuta | response error: %@", error.localizedDescription);
onFailure(error.userInfo[@"NSLocalizedDescription"]);
return;
}
}];
[dataTask resume];
}
/*
-(void)sendGetMethod:(NSURLRequest *)request typeRequest:(TypeRequest)type success:(void(^)(id dictionary)) success failure:(void(^)(NSError *))failure{
if (!self.isConnect) {
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:401 userInfo:@{MESSAGGIO : NSLocalizedString(@"Nessuna connessione", @"messaggio assenza connesione")}];
failure(error);
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
if(!error){
NSError *jsonError;
NSDictionary *showJSON = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&jsonError];
if (!jsonError){
switch (httpResp.statusCode) {
case 200:
success(showJSON);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
break;
}
NSError *jsonError;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
if (!jsonError) {
switch (httpResp.statusCode) {
case 200:
onSuccess(JSON);
break;
default:
NSLog(@"[ServerRequest] inviaRicevuta | response error, status code: %ld", (long)httpResp.statusCode);
break;
}
else{
NSError *error;
switch (type) {
case login:
error = [NSError errorWithDomain:NSMachErrorDomain code:login userInfo:@{MESSAGGIO : NSLocalizedString(@"Username e Password sbagliati", @"messaggio errore inserimento credenziali")}];
break;
case reading:
error = [NSError errorWithDomain:NSMachErrorDomain code:reading userInfo:@{MESSAGGIO : NSLocalizedString(@"Errore! Impossibile accedere all'impianto", @"messaggio errore richiesta apikey impianto")}];
break;
case sending:
// error = [NSError errorWithDomain:NSMachErrorDomain code:httpResp.statusCode userInfo:@{MESSAGGIO : NSLocalizedString(@"sending", @"")}];
case zona:
error = [NSError errorWithDomain:NSMachErrorDomain code:zona userInfo:@{MESSAGGIO : NSLocalizedString(@"Sì è verificato un errore sulla centralina", @"messaggio errore richiesta dev_cmd")}];
break;
default:
error = [NSError errorWithDomain:NSMachErrorDomain code:httpResp.statusCode userInfo:@{MESSAGGIO : NSLocalizedString(@"Errore sconosciuto", @"")}];
break;
}
failure(error);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
}
}];
[dataTask resume];
}
-(void)caricaImpianto:(Plant *)plant success:(void(^)(BOOL))success failure:(void(^)(NSError *))failure{
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:[self urlWithInfo:plant]];
[urlRequest setHTTPMethod:@"GET"];
[self sendGetMethod:urlRequest
typeRequest:login
success:^(NSDictionary *result){
plant.apikey = result[@"apikey"];
[self caricaZoneiWithPlant:plant success:^(BOOL result){
// caricamento zone
success(result);
}failure:^(NSError *error){
// caricamento zone
failure(error);
}];
}
failure:^(NSError *error){
// caricamento impianto
failure(error);
}];
}
-(NSURL *)urlWithInfo:(Plant *)plant{
NSURL *url =[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@=%@&%@=%@&%@=%@", LOGIN_URL, USERNAME, [User defaultUser].nome, PSW, [Portachiavi getCredenziali:[User defaultUser].nome], PLANT_ID, plant.plant_id]];
return url;
}
-(void)caricaZoneiWithPlant:(Plant *)plant success:(void(^)(BOOL))success failure:(void(^)(NSError *))failure{
NSString *url = [NSString stringWithFormat:@"%@?%@=%@&%@=%@&%@=[{\"mod\":10,\"reg\":100}]", DEVICE_COMMANDS_URL, APIKEY, plant.apikey, PLANT_ID, plant.plant_id, DEV_CMD];
NSURL *theUrl = [NSURL URLWithString:[url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:theUrl];
[urlRequest setHTTPMethod:@"GET"];
[self sendGetMethod:urlRequest
typeRequest:reading
success:^(NSDictionary *result){
NSArray *valori = result[@"result"];
NSNumber *numeroZone;
if(valori.count == 0){
//numeroZone = @1;
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:0 userInfo:@{MESSAGGIO : NSLocalizedString(@"Errore! Impossibile accedere all'impianto", @"messaggio errore richiesta apikey impianto")}];
failure(error);
return ;
}
else if([[valori firstObject][@"val"] isEqual:[NSNull null]]){
//numeroZone = @1;
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:0 userInfo:@{MESSAGGIO : NSLocalizedString(@"Errore! Impossibile accedere all'impianto", @"messaggio errore richiesta apikey impianto")}];
failure(error);
return ;
}
else
numeroZone = [valori firstObject][@"val"];
[plant creaZone:[numeroZone intValue]];
success(YES);
}
failure:^(NSError *error){
failure(error);
}];
}
-(UIAlertController *)mostraAllertWithMessage:(NSString *)messaggio close:(void(^)(BOOL terminato))terminato{
NSString *titolo = @"";
if ([messaggio isEqualToString:NSLocalizedString(@"Nessuna connessione", @"messaggio assenza connesione")])
titolo = NSLocalizedString(@"Attenzione", @"");
UIAlertController* alert = [UIAlertController alertControllerWithTitle:titolo//NSLocalizedString(@"Attenzione", @"")
message:messaggio
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
terminato(YES);
}];
[alert addAction:defaultAction];
return alert;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];
}
*/
@end
File diff suppressed because it is too large Load Diff
@@ -544,3 +544,11 @@
"oaL-SG-Zpq.title" = "Informes";
"eed-sY-0Ua.title" = "Redes Sísmicas";
"5VO-yI-kw5.title" = "Ajustes";
"3tl-cp-QLk.text" = "Filtros";
"MVi-r1-SFm.normalTitle" = "Cerrar";
"pYc-TM-AIW.text" = "Configuración tarjeta";
"dRl-jP-icD.text" = "Distancia";
"vyf-82-r1X.text" = "Coordenadas";
"Hpe-Qx-6yX.text" = "Población";
"l7i-w5-sp0.normalTitle" = "Cerrar";
@@ -288,7 +288,7 @@
"bgA-WP-7Ut.text" = "Label";
/* Class = "UILabel"; text = "oppure"; ObjectID = "c39-TN-fIZ"; */
"c39-TN-fIZ.text" = "otherwise";
"c39-TN-fIZ.text" = "oppure";
/* Class = "UILabel"; text = "Label"; ObjectID = "cOC-hS-Gxk"; */
"cOC-hS-Gxk.text" = "Label";
@@ -544,3 +544,11 @@
"oaL-SG-Zpq.title" = "Segnalazioni";
"eed-sY-0Ua.title" = "Reti Sismiche";
"5VO-yI-kw5.title" = "Impostazioni";
"3tl-cp-QLk.text" = "Filtri";
"MVi-r1-SFm.normalTitle" = "Chiudi";
"pYc-TM-AIW.text" = "Configurazione scheda";
"dRl-jP-icD.text" = "Distanza";
"vyf-82-r1X.text" = "Coordinate";
"Hpe-Qx-6yX.text" = "Popolazione";
"l7i-w5-sp0.normalTitle" = "Chiudi";
@@ -11,6 +11,14 @@ import Foundation
@objcMembers
class AppTheme: NSObject {
enum Colors {
static let primary = UIColor(named: "Primary")!
static let lightBlue = UIColor(named: "Light blue")!
static let red = UIColor(named: "Red")!
static let green = UIColor(named: "Green")!
static let darkGray = UIColor(named: "Gray (dark)")!
}
static let shared = AppTheme()
/// Color used for standard text
@@ -19,4 +27,7 @@ class AppTheme: NSObject {
var textDisabledColor: UIColor = .lightGray
/// Color used for label that contains value (ex. in settings page)
var valueColor: UIColor = .blue
var borderWidth: CGFloat = 1.0
var borderCornerRadius: CGFloat = 8.0
}
@@ -0,0 +1,36 @@
//
// EQNRoundedButton.swift
// Earthquake Network
//
// Created by Busi Andrea on 11/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
class EQNRoundedButton: UIButton {
// MARK: - Init
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupUI()
}
// MARK: - Private
private func setupUI() {
backgroundColor = .white
layer.masksToBounds = true
layer.borderWidth = AppTheme.shared.borderWidth
layer.borderColor = AppTheme.Colors.darkGray.cgColor
layer.cornerRadius = AppTheme.shared.borderCornerRadius
setTitle(titleLabel?.text?.uppercased(), for: .normal)
}
}
@@ -32,8 +32,6 @@
textForNavi.text = NSLocalizedString(@"Rilevatore Terremoti", @"titolo navigation bar");
[viewNavigationBar addSubview:textForNavi];
self.navigationItem.titleView = viewNavigationBar;
[[UINavigationBar appearance] setBarTintColor:COLORE_BARRA_NAVIGAZIONE];
[[UINavigationBar appearance] setTranslucent:NO];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back"]
style:UIBarButtonItemStyleDone
@@ -1,98 +0,0 @@
//
// ReteSismiDettagliMappa.m
// Earthquake Network
//
// Created by Luca Beretta on 07/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "ReteSismiDettagliMappa.h"
#import "SismaAnnotation.h"
@interface ReteSismiDettagliMappa ()
@property(nonatomic, strong) GADBannerView *bannerView;
@end
@implementation ReteSismiDettagliMappa
- (void)viewDidLoad {
self.mapView.delegate = self;
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back"]
style:UIBarButtonItemStyleDone
target:self
action:@selector(chiudi:)];
for (EQNSisma *sismi in [EQNManager defaultManager].retiSismiche ) {
[self creaMarcherWithSegnalazione:sismi];
}
self.bannerView = [EQNUtility ottieniBannerWithController:self position:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)creaMarcherWithSegnalazione:(id)segnalazione{
[super creaMarcherWithSegnalazione:segnalazione];
CLLocationCoordinate2D location = CLLocationCoordinate2DMake([self.sisma.latitude doubleValue], [self.sisma.longitude doubleValue]);
SismaAnnotation *anAnnotation = [[SismaAnnotation alloc] initWithTitle:self.sisma.place location:location intensita:[self.sisma.magnitude doubleValue]];
[self.mapView addAnnotation:anAnnotation];
CLLocation *coordinate = [[CLLocation alloc] initWithLatitude:[self.sisma.latitude doubleValue] longitude:[self.sisma.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];
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
if ([annotation isKindOfClass:[SismaAnnotation class]]) {
SismaAnnotation *anLocation = (SismaAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_SISMI];
if (annotationView == nil)
annotationView = anLocation.annotationView;
else
annotationView.annotation = anLocation;
return annotationView;
}
else
return nil;
}
// apriImpostazioni
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
@@ -1,15 +0,0 @@
//
// EQNRetiSismiViewController.h
// Earthquake Network
//
// Created by Luca Beretta on 25/10/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "EQNBaseViewController.h"
@interface EQNRetiSismiViewController : EQNBaseViewController
@end
@@ -1,256 +0,0 @@
//
// EQNRetiSismiViewController.m
// Earthquake Network
//
// Created by Luca Beretta on 25/10/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "EQNRetiSismiViewController.h"
#import "EQNManager.h"
#import "EQNSisma.h"
#import "Costanti.h"
#import "CellDettagliMappaTableViewCell.h"
#import "Cell_Reti_sismicheTableViewCell.h"
#import "Cell_Meteo_TableViewCell.h"
#import "ReteSismiDettagliMappa.h"
#import "SismaAnnotation.h"
#import "MenuFiltroEntiViewController.h"
#import "MenuSelezioneEntiViewController.h"
#import "ElencoFiltroEntiTableViewController.h"
#import <GoogleMaps/GoogleMaps.h>
#import <QuartzCore/QuartzCore.h>
@interface EQNRetiSismiViewController () <UITableViewDelegate, UITableViewDataSource, MenuFiltroEntiDelegate, MenuSelezioneEntiDelegate, MenuListaEntiDelegate>
@property (nonatomic, strong) NSArray *listaSismi;
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@property (nonatomic, strong) NSIndexPath *selectIndex;
@property (nonatomic, assign) EQNReteSismicaCell tipoCell;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *fooTable;
@end
@implementation EQNRetiSismiViewController
static NSString * const SegueIdentifierFilters = @"FiltriEntiSismici";
static NSString * const SegueIdentifierSettings = @"impostazioniEntiSismi";
static NSString * const SegueIdentifierSeismicNetworks = @"elencoRetiSismiche";
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = NSLocalizedString(@"tab_official", nil);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshUI) name:NOTIFICA_DOWNLOAD_TERMINATO object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setupView) name:IAPHelperPurchaseNotification object:nil];
[self setupView];
[self refreshUI];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"apri_mappa_dettagli"]) {
EQNSisma *sisma = (EQNSisma *)sender;
UINavigationController *nav = (UINavigationController *)segue.destinationViewController;
ReteSismiDettagliMappa *mappaDett = (ReteSismiDettagliMappa *)nav.topViewController;
mappaDett.sisma = sisma;
} else if ([segue.identifier isEqualToString:SegueIdentifierFilters]) {
MenuFiltroEntiViewController *controller = (MenuFiltroEntiViewController *)segue.destinationViewController;
controller.delegate = self;
} else if ([segue.identifier isEqualToString:SegueIdentifierSettings]) {
MenuSelezioneEntiViewController *controller = (MenuSelezioneEntiViewController *)segue.destinationViewController;
controller.delegate = self;
} else if([segue.identifier isEqualToString:SegueIdentifierSeismicNetworks]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
ElencoFiltroEntiTableViewController *controller = (ElencoFiltroEntiTableViewController *)navController.topViewController;
controller.delegate = self;
}
}
#pragma mark - Private
- (void)setupView
{
if ([EQNPurchaseUtility isProVersionEnabled]) {
self.fooTable.constant = 0;
}
}
- (void)refreshUI
{
[super refreshUI];
self.listaSismi = [EQNUtility arrayRetisismicheFiltrate:[EQNManager defaultManager].retiSismiche];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
-(void)apriDettagli:(id)sender{
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)[[[button superview] superview] superview];
self.selectIndex = [self.tableView indexPathForCell:cell];
switch (button.tag) {
case 12:
self.tipoCell = mappaCell;
break;
case 14:
self.tipoCell = meteoCell;
break;
default:
self.tipoCell = defaultCell;
[self chiudiMappa];
return;
break;
}
[self.tableView reloadRowsAtIndexPaths:@[self.selectIndex] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView scrollToRowAtIndexPath:self.selectIndex
atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
-(void)apriDettagliMappa:(id)sender{
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
NSIndexPath *index = [self.tableView indexPathForCell:cell];
EQNSisma *sisma = self.listaSismi[index.row];
[self performSegueWithIdentifier:@"apri_mappa_dettagli" sender:sisma];
}
-(void)chiudiMappa{
NSIndexPath *indexDelete = [self.selectIndex copy];
self.selectIndex = nil;
[self.tableView reloadRowsAtIndexPaths:@[indexDelete] withRowAnimation:UITableViewRowAnimationNone];
indexDelete = nil;
self.tipoCell = defaultCell;
[self.tableView scrollToRowAtIndexPath:indexDelete
atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
#pragma mark - Actions
- (IBAction)refreshDataTapped:(id)sender
{
[[EQNManager defaultManager] sincronizza];
}
- (IBAction)openFilterTapped:(id)sender
{
// apriManu
[self performSegueWithIdentifier:SegueIdentifierFilters sender:nil];
}
- (IBAction)openSettingsTapped:(id)sender
{
// apriImpostazioni
[self performSegueWithIdentifier:SegueIdentifierSettings sender:nil];
}
#pragma table view
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.listaSismi.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (self.selectIndex && self.selectIndex.row == indexPath.row)
return 368;
return 180;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
EQNSisma *sisma = self.listaSismi[indexPath.row];
Cell_Reti_sismicheTableViewCell *cell;
if (self.selectIndex && self.selectIndex.row == indexPath.row){
switch (self.tipoCell)
case mappaCell:{
cell = (CellDettagliMappaTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"sismaCell_mappa" forIndexPath:indexPath];
break;
default:
cell = (Cell_Meteo_TableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"sismaCell_meteo" forIndexPath:indexPath];
break;
}
[cell createOtherButton];
}
else
cell = [tableView dequeueReusableCellWithIdentifier:@"sismaCell" forIndexPath:indexPath];
cell.sisma = sisma;
[cell setupView];
[cell.chiudi addTarget:self action:@selector(chiudiMappa) forControlEvents:UIControlEventTouchDown];
[cell.mappaButton addTarget:self action:@selector(apriDettagli:) forControlEvents:UIControlEventTouchDown];
[cell.meteoButton addTarget:self action:@selector(apriDettagli:) forControlEvents:UIControlEventTouchDown];
[cell.dettagliMappa addTarget:self action:@selector(apriDettagliMappa:) forControlEvents:UIControlEventTouchDown];
[cell.clickMappa addTarget:self action:@selector(apriDettagliMappa:) forControlEvents:UIControlEventTouchDown];
[cell.condividi addTarget:self action:@selector(condividiView:) forControlEvents:UIControlEventTouchDown];
return cell;
}
-(void)condividiView:(id)sender{
UIButton *button = (UIButton *)sender;
CellDettagliMappaTableViewCell *cell = (CellDettagliMappaTableViewCell *)button.superview.superview.superview;
[self presentViewController:[EQNUtility shareFileWithPath:[cell condividiViewPath]] animated:YES completion:^{}];
}
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark MenuFiltroEntiDelegate
- (void)menuFiltroEntiDidUpdateFilter:(MenuFiltroEntiViewController *)controller
{
[self refreshUI];
}
#pragma mark MenuSelezioneEntiDelegate
- (void)menuSelezioneEnti:(MenuSelezioneEntiViewController *)controller willSendData:(EQNfiltroEnti)filtro
{
[[NSUserDefaults standardUserDefaults] setInteger:filtro forKey:IMPOSTAZIONE_TIPO_FILTRO_RETI_SISMICHEI];
[self refreshUI];
}
- (void)menuSelezioneEntiWillOpenProviders:(MenuSelezioneEntiViewController *)controller
{
[self performSegueWithIdentifier:SegueIdentifierSeismicNetworks sender:nil];
}
#pragma mark MenuListaEntiDelegate
- (void)elencoFiltroEnti:(ElencoFiltroEntiTableViewController *)controller willSendData:(EQNfiltroEnti)filtro
{
[[NSUserDefaults standardUserDefaults] setInteger:filtro forKey:IMPOSTAZIONE_TIPO_FILTRO_RETI_SISMICHEI];
[self refreshUI];
}
@end
@@ -1,26 +0,0 @@
//
// ElencoFiltroEntiTableViewController.h
// Earthquake Network
//
// Created by Luca Beretta on 06/02/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "costanti.h"
NS_ASSUME_NONNULL_BEGIN
@class ElencoFiltroEntiTableViewController;
@protocol MenuListaEntiDelegate <NSObject>
- (void)elencoFiltroEnti:(ElencoFiltroEntiTableViewController *)controller willSendData:(EQNfiltroEnti)filtro; // inviaDatiLista
@end
@interface ElencoFiltroEntiTableViewController : UITableViewController
@property (strong, nonatomic) id<MenuListaEntiDelegate> delegate;
@end
NS_ASSUME_NONNULL_END
@@ -1,114 +0,0 @@
//
// ElencoFiltroEntiTableViewController.m
// Earthquake Network
//
// Created by Luca Beretta on 06/02/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
//
#import "ElencoFiltroEntiTableViewController.h"
#import "EQNUtility.h"
#import "costanti.h"
@interface ElencoFiltroEntiTableViewController ()
@property (nonatomic, strong) NSArray *listaEnti;
-(IBAction)save:(id)sender;
-(IBAction)cancell:(id)sender;
@end
@implementation ElencoFiltroEntiTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
if([[NSUserDefaults standardUserDefaults] objectForKey:IMPOSTAZIONE_ENTI_RETI_SISMICHEI]){
self.listaEnti = [[NSUserDefaults standardUserDefaults] objectForKey:IMPOSTAZIONE_ENTI_RETI_SISMICHEI];
}else{
self.listaEnti = [EQNUtility arrayEnti];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [EQNUtility arrayEnti].count;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 70;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *descrizioni = [EQNUtility arrayDescrizioneEnti];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellaSelezioneAbilita" forIndexPath:indexPath];
UILabel *titolo = (UILabel *)[cell viewWithTag:1];
titolo.text = [EQNUtility arrayEnti][indexPath.row];
UILabel *stato = (UILabel *)[cell viewWithTag:2];
stato.text = descrizioni[indexPath.row];//NSLocalizedString(@"Ricevi le notifiche dei sismi rilevati dalle agenzie nazionalie internazionali", @"voce menu");
cell.accessoryType = UITableViewCellAccessoryNone;
if ([self.listaEnti containsObject:titolo.text]){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
titolo.textColor = [UIColor blackColor];
stato.textColor = [UIColor blackColor];
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
titolo.textColor = [UIColor grayColor];
stato.textColor = [UIColor grayColor];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSMutableArray *array = [self.listaEnti mutableCopy];
NSString *selezioneEnete = [EQNUtility arrayEnti][indexPath.row];
if ([array containsObject:selezioneEnete])
[array removeObject:selezioneEnete];
else
[array addObject:selezioneEnete];
self.listaEnti = [NSArray arrayWithArray:array];
[self.tableView reloadData];
}
-(IBAction)save:(id)sender{
[[NSUserDefaults standardUserDefaults] setObject:self.listaEnti forKey:IMPOSTAZIONE_ENTI_RETI_SISMICHEI];
if (self.listaEnti.count == 1){
NSArray *enti = [EQNUtility arrayEnti];
NSUInteger index = [enti indexOfObject:[self.listaEnti firstObject]];
[[NSUserDefaults standardUserDefaults] setInteger:index forKey:IMPOSTAZIONE_NAZIONE_RETI_SISMICHEI];
}else{
[[NSUserDefaults standardUserDefaults] removeObjectForKey:IMPOSTAZIONE_NAZIONE_RETI_SISMICHEI];
}
if ([self.delegate respondsToSelector:@selector(elencoFiltroEnti:willSendData:)]) {
[self.delegate elencoFiltroEnti:self willSendData:enti];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)cancell:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
@@ -1,13 +0,0 @@
//
// ImpostazioniViewController.h
// Earthquake Network
//
// Created by Luca Beretta on 08/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ImpostazioniViewController : UIViewController
@end
@@ -1,71 +0,0 @@
//
// ImpostazioniViewController.m
// Earthquake Network
//
// Created by Luca Beretta on 08/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "ImpostazioniViewController.h"
@interface ImpostazioniViewController ()
@property (weak, nonatomic) IBOutlet UILabel *titolo;
@property (weak, nonatomic) IBOutlet UILabel *nazione;
@property (weak, nonatomic) IBOutlet UIButton *buttonNazione;
@property (weak, nonatomic) IBOutlet UILabel *etichetta;
@property (weak, nonatomic) IBOutlet UIButton *buttonReteSismiche;
@property (weak, nonatomic) IBOutlet UIButton *buttonChiudi;
- (IBAction)selezionaNazione:(id)sender;
- (IBAction)selezionaRetiSismiche:(id)sender;
- (IBAction)chiudi:(id)sender;
@end
@implementation ImpostazioniViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.titolo.text = NSLocalizedString(@"Se vuoi filtrare la lista dei sismi, seleziona la nazione in cui vivi", @"");
self.etichetta.text = NSLocalizedString(@"oppure", @"");
[self.buttonNazione setTitle:[NSLocalizedString(@"Conferma nazione", @"") uppercaseString] forState:UIControlStateNormal];
[self.buttonReteSismiche setTitle:NSLocalizedString(@"Gestisci le reti sismiche", @"") forState:UIControlStateNormal];
[self.buttonChiudi setTitle:[NSLocalizedString(@"Annulla", @"") uppercaseString] forState:UIControlStateNormal];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)selezionaNazione:(id)sender {
}
- (IBAction)selezionaRetiSismiche:(id)sender {
}
- (IBAction)chiudi:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
@@ -1,24 +0,0 @@
//
// MenuFiltroEntiViewController.h
// Earthquake Network
//
// Created by Luca Beretta on 09/03/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class MenuFiltroEntiViewController;
@protocol MenuFiltroEntiDelegate <NSObject>
- (void)menuFiltroEntiDidUpdateFilter:(MenuFiltroEntiViewController *)controller;
@end
@interface MenuFiltroEntiViewController : UIViewController
@property (strong, nonatomic) id<MenuFiltroEntiDelegate> delegate;
@end
NS_ASSUME_NONNULL_END
@@ -1,111 +0,0 @@
//
// MenuFiltroEntiViewController.m
// Earthquake Network
//
// Created by Luca Beretta on 09/03/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
//
#import "MenuFiltroEntiViewController.h"
#import "PickerViewController.h"
#import "EQNUtility.h"
#import "FiltroEnti.h"
@interface MenuFiltroEntiViewController () <PickerViewDelegate>
@property (weak, nonatomic) IBOutlet UILabel *labelTitolo;
@property (weak, nonatomic) IBOutlet UILabel *labelMagnitudiMinima;
@property (weak, nonatomic) IBOutlet UITextField *textMagnitutiMinima;
@property (weak, nonatomic) IBOutlet UILabel *labelDistanzaMassima;
@property (weak, nonatomic) IBOutlet UITextField *textDistanzaMassima;
@property (weak, nonatomic) IBOutlet UILabel *labelEtaMassima;
@property (weak, nonatomic) IBOutlet UITextField *textEtaMassima;
@property (weak, nonatomic) IBOutlet UILabel *labelSismiForti;
@property (weak, nonatomic) IBOutlet UITextField *textSismiForti;
@property (weak, nonatomic) IBOutlet UIButton *buttonEsci;
@property (nonatomic, strong) PickerViewController *pikerMagnitudoMinima;
@property (nonatomic, strong) PickerViewController *pikerViewDistanza;
@property (nonatomic, strong) PickerViewController *etaMassima;
@property (nonatomic, strong) PickerViewController *pikerViewforti;
@end
@implementation MenuFiltroEntiViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.labelTitolo.text = NSLocalizedString(@"Filtro", @"");
self.labelMagnitudiMinima.text = NSLocalizedString(@"Magnitudo minima", @"");
self.labelDistanzaMassima.text = NSLocalizedString(@"Distanza massima", @"");
self.labelEtaMassima.text = NSLocalizedString(@"Età massima", @"");
self.labelSismiForti.text = NSLocalizedString(@"Mostra sismi forti a qualsiasi distanza se di", @"");
[self.buttonEsci setTitle:NSLocalizedString(@"Esci", @"") forState:UIControlStateNormal];
[self.buttonEsci addTarget:self action:@selector(chiudi:) forControlEvents:UIControlEventTouchUpInside];
self.pikerMagnitudoMinima = [[PickerViewController alloc] initWithNibName:@"PickerViewController" bundle:nil dati:@[@"2.0", @"3.0", @"3.5", @"4.0", @"4.5", @"5.5", @"6.0", @"6.5", @"7.5"]];
self.pikerMagnitudoMinima.delegate = self;
self.textMagnitutiMinima.inputView = self.pikerMagnitudoMinima.view;
self.pikerViewDistanza = [[PickerViewController alloc] initWithNibName:@"PickerViewController" bundle:nil dati:[EQNUtility arrayRaggioSismi]];
self.pikerViewDistanza.delegate = self;
self.textDistanzaMassima.inputView = self.pikerViewDistanza.view;
self.etaMassima = [[PickerViewController alloc] initWithNibName:@"PickerViewController" bundle:nil dati:@[NSLocalizedString(@"Un giorno", @""), NSLocalizedString(@"Dodici ore", @""),NSLocalizedString(@"Sei ore", @""),NSLocalizedString(@"Due ore", @""),NSLocalizedString(@"Un ora", @""), NSLocalizedString(@"Dieci minuti", @"")]];
self.etaMassima.delegate = self;
self.textEtaMassima.inputView = self.etaMassima.view;
self.pikerViewforti = [[PickerViewController alloc] initWithNibName:@"PickerViewController" bundle:nil dati:@[@"5.5", @"6.0", @"6.5", @"7.5"]];
self.pikerViewforti.delegate = self;
self.textSismiForti.inputView = self.pikerViewforti.view;
self.textMagnitutiMinima.text = [FiltroEnti defaultFiltro].magnitudoMinima;
self.textDistanzaMassima.text = [FiltroEnti defaultFiltro].distanzaMassima;
self.textEtaMassima.text = [FiltroEnti defaultFiltro].etaMassima;
self.textSismiForti.text = [NSString stringWithFormat:@"%@ >= %@", NSLocalizedString(@"Magnitudo", @"") , [FiltroEnti defaultFiltro].sismiForti];
}
- (void)chiudi:(id)sender
{
if ([self.delegate respondsToSelector:@selector(menuFiltroEntiDidUpdateFilter:)]) {
[self.delegate menuFiltroEntiDidUpdateFilter:self];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
# pragma mark pikerView string
-(void)inviaDati:(NSDictionary *)elementi{
NSString *elemento = elementi[@"elemento"];
// NSNumber *indice = elementi[@"indice"];
if (self.textMagnitutiMinima.isFirstResponder){
self.textMagnitutiMinima.text = elemento;
}
if (self.textDistanzaMassima.isFirstResponder){
self.textDistanzaMassima.text = elemento;
}
if (self.textEtaMassima.isFirstResponder){
self.textEtaMassima.text = elemento;
}
if (self.textSismiForti.isFirstResponder){
self.textSismiForti.text = [NSString stringWithFormat:@"%@ >= %@", NSLocalizedString(@"Magnitudo", @"") ,elemento];
[FiltroEnti defaultFiltro].sismiForti = elemento;
}
[self.view endEditing:YES];
[FiltroEnti defaultFiltro].magnitudoMinima = self.textMagnitutiMinima.text;
[FiltroEnti defaultFiltro].distanzaMassima = self.textDistanzaMassima.text;
[FiltroEnti defaultFiltro].etaMassima = self.textEtaMassima.text;
[[FiltroEnti defaultFiltro] saveFiltro];
}
-(void)chiudiView{
[self.view endEditing:YES];
}
@end
@@ -1,31 +0,0 @@
//
// MenuSelezioneEntiViewController.h
// Earthquake Network
//
// Created by Luca Beretta on 06/02/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "costanti.h"
NS_ASSUME_NONNULL_BEGIN
@class MenuSelezioneEntiViewController;
@protocol MenuSelezioneEntiDelegate <NSObject>
- (void)menuSelezioneEnti:(MenuSelezioneEntiViewController *)controller willSendData:(EQNfiltroEnti)filtro; // inviaDati
- (void)menuSelezioneEntiWillOpenProviders:(MenuSelezioneEntiViewController *)controller; // apriElencoEnti
@end
@interface MenuSelezioneEntiViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *textNazione;
@property (strong, nonatomic) id<MenuSelezioneEntiDelegate> delegate;
- (IBAction)selezionaNazione:(id)sender;
- (IBAction)selezionaEnte:(id)sender;
- (IBAction)annulla:(id)sender;
@end
NS_ASSUME_NONNULL_END
@@ -1,127 +0,0 @@
//
// MenuSelezioneEntiViewController.m
// Earthquake Network
//
// Created by Luca Beretta on 06/02/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
//
#import "MenuSelezioneEntiViewController.h"
#import "PickerViewController.h"
#import "costanti.h"
#import "EQNUtility.h"
@interface MenuSelezioneEntiViewController () <PickerViewDelegate>
@property (nonatomic, strong) PickerViewController *pikerViewNazione;
@property (nonatomic, assign) EQNNazioneSelect indice;
@property (nonatomic, assign) EQNfiltroEnti tipoFiltro;
@end
@implementation MenuSelezioneEntiViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSArray *nazioniList = [EQNUtility arrayNazioni];
self.pikerViewNazione = [[PickerViewController alloc] initWithNibName:@"PickerViewController" bundle:nil dati:nazioniList];
self.pikerViewNazione.delegate = self;
self.textNazione.inputView = self.pikerViewNazione.view;
if ([[NSUserDefaults standardUserDefaults] integerForKey:IMPOSTAZIONE_NAZIONE_RETI_SISMICHEI]) {
self.textNazione.text = nazioniList[[[NSUserDefaults standardUserDefaults] integerForKey:IMPOSTAZIONE_NAZIONE_RETI_SISMICHEI]];
}
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)selezionaNazione:(id)sender {
if (self.textNazione.text.length == 0) {
UIAlertController *messaggio = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Attenzione ", @"") message:NSLocalizedString(@"Non hai seleziato nessuna nazione", @"") preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self.textNazione becomeFirstResponder];
}];
[messaggio addAction:defaultAction];
[self presentViewController:messaggio animated:YES completion:nil];
}else{
NSArray *enti = [EQNUtility arrayEnti];
[[NSUserDefaults standardUserDefaults] setInteger:self.indice forKey:IMPOSTAZIONE_NAZIONE_RETI_SISMICHEI];
if (self.indice == 0) {
[[NSUserDefaults standardUserDefaults] setObject:enti forKey:IMPOSTAZIONE_ENTI_RETI_SISMICHEI];
}else{
NSArray *ente = @[enti[self.indice]];
[[NSUserDefaults standardUserDefaults] setObject:ente forKey:IMPOSTAZIONE_ENTI_RETI_SISMICHEI];
}
self.tipoFiltro = nazione;
[self chiudi];
}
}
- (IBAction)selezionaEnte:(id)sender {
self.tipoFiltro = enti;
if ([self.delegate respondsToSelector:@selector(menuSelezioneEntiWillOpenProviders:)]) {
[self.delegate menuSelezioneEntiWillOpenProviders:self];
}
[self annulla:sender];
}
- (IBAction)annulla:(id)sender {
// self.tipoFiltro = annulla;
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)chiudi
{
if ([self.delegate respondsToSelector:@selector(menuSelezioneEnti:willSendData:)]) {
[self.delegate menuSelezioneEnti:self willSendData:self.tipoFiltro];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
# pragma mark pikerView string
-(void)inviaDati:(NSDictionary *)elementi{
NSString *elemento = elementi[@"elemento"];
self.indice = [elementi[@"indice"] intValue];
self.textNazione.text = elemento;
[self.view endEditing:YES];
}
-(void)chiudiView{
[self.view endEditing:YES];
}
@end
@@ -472,12 +472,10 @@
[self presentViewController:alertController animated:YES completion:nil];
}
-(void)apriTwitter:(id)sender{
// TWITTER_LINK
- (void)apriTwitter:(id)sender
{
UIApplication *mySafari = [UIApplication sharedApplication];
NSURL *myURL = [[NSURL alloc]initWithString:TWITTER_LINK];
NSURL *myURL = [[NSURL alloc]initWithString:EQNTwitterProfileUrl];
[mySafari openURL:myURL options:@{} completionHandler:nil];
}
@@ -1,13 +0,0 @@
//
// WaitViewController.h
// Earthquake Network
//
// Refactored by Andrea Busi on 24/07/20.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface WaitViewController : UIViewController
@end
@@ -1,44 +0,0 @@
//
// WaitViewController.m
// Earthquake Network
//
// Refactored by Andrea Busi on 24/07/20.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "WaitViewController.h"
#import "Costanti.h"
@interface WaitViewController ()
@end
@implementation WaitViewController
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadCompletedNotification:) name:NOTIFICA_DOWNLOAD_TERMINATO object:nil];
[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(closeController) userInfo:nil repeats:NO];
}
#pragma mark - Notifications
- (void)downloadCompletedNotification:(NSNotification *)notifica
{
dispatch_async(dispatch_get_main_queue(), ^{
[self closeController];
});
}
#pragma mark - Private
- (void)closeController
{
[self dismissViewControllerAnimated:NO completion:nil];
}
@end
@@ -1,19 +0,0 @@
//
// CellDettagliMappaTableViewCell.h
// Earthquake Network
//
// Created by Luca Beretta on 31/10/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "Cell_Reti_sismicheTableViewCell.h"
#import <GoogleMaps/GoogleMaps.h>
#import "EQNSisma.h"
#import <MapKit/MapKit.h>
@interface CellDettagliMappaTableViewCell : Cell_Reti_sismicheTableViewCell <MKMapViewDelegate>
@property (nonatomic, strong) IBOutlet MKMapView *mapView;
-(UIImage *)condividiViewPath;
@end
@@ -1,55 +0,0 @@
//
// CellDettagliMappaTableViewCell.m
// Earthquake Network
//
// Created by Luca Beretta on 31/10/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "CellDettagliMappaTableViewCell.h"
#import "Costanti.h"
#import <QuartzCore/QuartzCore.h>
@implementation CellDettagliMappaTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self setupView];
}
-(void)setupView{
[super setupView];
CLLocation *coordinate = [[CLLocation alloc] initWithLatitude:[self.sisma.latitude doubleValue] longitude:[self.sisma.longitude doubleValue]];
MKCoordinateSpan span = MKCoordinateSpanMake(0.5, 0.5);
MKCoordinateRegion region = MKCoordinateRegionMake(coordinate.coordinate, span);
[self.mapView setCenterCoordinate:coordinate.coordinate animated:NO];
[self.mapView setRegion:region animated:YES];
self.mapView.scrollEnabled = NO;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(UIImage *)condividiViewPath{
// define the size and grab a UIImage from it
UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0.0);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
@end
@@ -1,13 +0,0 @@
//
// Cell_Meteo_TableViewCell.h
// Earthquake Network
//
// Created by Luca Beretta on 01/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "Cell_Reti_sismicheTableViewCell.h"
@interface Cell_Meteo_TableViewCell : Cell_Reti_sismicheTableViewCell
@end

Some files were not shown because too many files have changed in this diff Show More