Compare commits

...

146 Commits

Author SHA1 Message Date
Andrea Busi 8f711b988a release: Increase version for release 2020-10-08 14:22:26 +02:00
Andrea Busi e202ba8452 fix: Solve wrong url for settings upload 2020-10-08 14:21:49 +02:00
Andrea Busi eb8d8be800 fix: Make provider label fit required space 2020-10-08 14:01:52 +02:00
Andrea Busi a1b7a5ee70 fix: Seismic filter now use case-insensitive check for networks 2020-10-08 14:01:36 +02:00
Andrea Busi 7a117097e3 fix: Add missing translations 2020-10-08 14:01:24 +02:00
Andrea Busi 8070262a44 fix: Use proper time zone when parse web service date 2020-10-08 14:00:53 +02:00
Andrea Busi f768b15916 release: Increase version for release 2020-10-03 12:10:24 +02:00
Andrea Busi a07480f90a fix: Handle seismic date as nullable parameter to avoid crashes 2020-10-03 12:09:47 +02:00
Andrea Busi 4e5e93e3f1 refactor: Rename method to convert server string into date 2020-10-03 12:09:31 +02:00
Andrea Busi 68c9eb9bbc feat: Show alert when weather data are not available 2020-10-03 12:09:06 +02:00
Andrea Busi ba2fbfaa60 feat: Handle weather code as nullable parameter 2020-10-03 12:01:17 +02:00
Andrea Busi e194731bc8 refactor: Rename NSDictionary extension and improve code 2020-10-03 11:58:15 +02:00
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 a871f7b27b release: Increase version for release 2020-09-23 10:28:34 +02:00
Andrea Busi b88a1e197f fix: Solve issue when saving real time alert notification setting 2020-09-23 10:23:54 +02:00
Andrea Busi d4986ac610 refactor: Improve EQNAllertaSismica code 2020-09-23 10:21:41 +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
Andrea Busi 4a77692e23 release: Update version for release 2020-09-02 22:51:38 +02:00
Andrea Busi d6b6d6883f refactor: Remove distanza sismi vicini setting and change label
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-09-02 22:51:38 +02:00
Andrea Busi 5528756aad refactor: Change label for raggio sismi forti setting
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-09-02 22:51:38 +02:00
Andrea Busi 1970cc21ec refactor: Remove sismi senza intensità setting
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-09-02 22:51:38 +02:00
Andrea Busi bb54e78278 fix: Add missing case for new tab item 2020-09-02 22:51:38 +02:00
Andrea Busi 5cef7215df chore: Remove unused files from Git folder 2020-09-01 19:27:54 +02:00
Andrea Busi ffa63352b2 refactor: Remove unused CoreData initialization 2020-09-01 19:27:54 +02:00
Andrea Busi c6ee123eee refactor: Add class to share a theme across the app 2020-09-01 19:27:54 +02:00
Andrea Busi e9846cc75d refactor: Remove no longer user menu and SWRevealViewController 2020-09-01 19:27:54 +02:00
Andrea Busi 1792f4b4bb refactor: Move settings as tab section
- Rewrite Settings controller in Swift
- Move settings as tab bar item
- Force settings save when user change tab or back from a sub-setting controller
2020-09-01 19:27:54 +02:00
Andrea Busi 7e7747efcb Refactor: Update strings for 'Always allow' location permission
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/13
2020-09-01 19:26:19 +02:00
Andrea Busi 0d5bf272c1 refactor: Update app icon
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/9
2020-09-01 19:26:19 +02:00
Andrea Busi 8201ece916 release: Update version for release 2020-09-01 19:24:16 +02:00
Andrea Busi 0148ac65f7 refactor: Improve inititializers in SettingItem 2020-09-01 19:19:25 +02:00
Andrea Busi 8d0439f7f8 fix: Use new image in main menu
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/12
2020-09-01 19:19:25 +02:00
Andrea Busi 31f928fed9 refactor: Use new high-res images for app icon (in main menu) 2020-09-01 19:19:25 +02:00
Andrea Busi 93f72cddb7 refactor: Rename setupView to updateUI to be more consistent across controllers 2020-09-01 19:19:25 +02:00
Andrea Busi fe8f9f46fd refactor: Remove no longer needed imports 2020-09-01 19:19:25 +02:00
Andrea Busi 33f2d45cb9 fix: Solve missing load of notification saved value
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-09-01 19:19:25 +02:00
Andrea Busi 4b457286dd fix: Multiple fixes in settings section based on Finazzi's report
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-09-01 19:19:15 +02:00
Andrea Busi 6b2d690491 release: Update version for release 2020-08-29 14:27:24 +02:00
Andrea Busi b02d3dbb8e fix: Change title for a setting
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-08-28 13:47:42 +02:00
Andrea Busi b8feb2fa70 fix: Edit switch cell to support tile on multiple lines 2020-08-28 13:47:42 +02:00
Andrea Busi b1b7ddd8c1 refactor: Clean up setting classes
- Rename controllers to be "SettingsXXX"
- Remove unused controllers
- Remove old stuff from Storyboard
2020-08-28 13:47:42 +02:00
Andrea Busi 84ee7b7958 refactor: Merge "Notifiche sismi" items in the main settings page 2020-08-28 13:47:42 +02:00
Andrea Busi 4fbbb8e4fc fix: Sort by name selected networks
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-08-28 13:47:42 +02:00
Andrea Busi 6e1a982188 fix: Add "km" when display radius
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-08-28 13:47:42 +02:00
Andrea Busi de1167fcad fix: Continuous update for slider settings
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/11
2020-08-28 13:47:42 +02:00
Andrea Busi 031b731e30 fix: Allow title labels on multiple lines 2020-08-28 13:47:42 +02:00
Andrea Busi ccc74f6b39 refactor: New style for "Allerta in tempo reale" settings page 2020-08-28 13:47:42 +02:00
Andrea Busi 0a5902c5f1 refactor: Remove logic related to Tsunami from settings 2020-08-28 13:47:42 +02:00
Andrea Busi e494109a72 refactor: New style for "Reti sismiche" selection settings page 2020-08-28 09:19:34 +02:00
Andrea Busi 530ce3d56f refactor: New style for "Notifiche da reti sismiche" settings page 2020-08-27 18:43:45 +02:00
Andrea Busi 1c0a449c05 refactor: Add a type inside the SettingItem model 2020-08-27 18:43:45 +02:00
Andrea Busi b70bd95a6d refactor: New style for "Notifiche segnalazioni utente" settings page 2020-08-27 18:43:36 +02:00
Andrea Busi 87becee4fb refactor: New style for "Notifiche sismi" settings page 2020-08-27 18:43:15 +02:00
Andrea Busi 9344eae39a refactor: New style for main settings page
- renamed from DettadliMenuTableViewController to SettingsViewController
- used inset table view style
- improve code
2020-08-26 13:45:26 +02:00
Andrea Busi bed5198bbc release: Update version for release 2020-08-22 20:50:41 +02:00
Andrea Busi c416a12c1b fix: Solve tons of warnings in SWRevealViewController 2020-08-22 20:50:41 +02:00
Andrea Busi 6ebc4d319a fix: Solve warning due to deprecated methods 2020-08-22 20:50:41 +02:00
Andrea Busi e93ddc91d6 refactor: Remove commented and dead code 2020-08-22 20:50:41 +02:00
Andrea Busi aa765d7bac fix: Remove extra % in string interpolation 2020-08-22 20:50:41 +02:00
Andrea Busi 388fbfd2e5 fix: Solve warnings in Storyboard due to unused adjustsFontForContentSizeCategory 2020-08-22 20:50:41 +02:00
Andrea Busi e0661c138b dependency: Update Pods
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/10
2020-08-22 20:50:27 +02:00
Andrea Busi 9c7f9eaaf0 fix: Solve issue with pan gesture to open home menu 2020-08-16 11:38:19 +02:00
Andrea Busi 984c18e435 feat: Add new icon for AppStore 2020-08-16 11:38:05 +02:00
Andrea Busi 2f5e0f0492 refactor: Create base controller to handle banner view and refresh UI 2020-08-16 11:30:10 +02:00
Andrea Busi eadba2b1e7 refactor: Create helper method to get root view controller 2020-08-16 11:27:44 +02:00
Andrea Busi ed236371ed release: Update version for release 2020-08-15 16:39:24 +02:00
Andrea Busi b1772d7712 refactor: Remove old class MasterViewController 2020-08-15 16:37:27 +02:00
Andrea Busi 4672549f2d feat: Force UI refresh when change tab 2020-08-15 16:37:27 +02:00
Andrea Busi 08a493d0a3 feat: Add navigation bar style management using UIAppearance 2020-08-15 16:37:27 +02:00
Andrea Busi 6a056ec8d1 refactor: Remove old logic related to old MasterViewController 2020-08-15 16:37:27 +02:00
Andrea Busi 0636ea65da refactor: Use standard tab bar for main app interface 2020-08-15 16:37:27 +02:00
Andrea Busi 7f9543309a refactor: Improve delegate methods name to be more ObjC-style 2020-08-15 16:37:27 +02:00
Andrea Busi 8440c70fb2 fix: Solve crash when sending seismic report 2020-08-15 16:36:46 +02:00
Andrea Busi ac553df6c6 refactor: Improve code formatting 2020-08-15 16:36:46 +02:00
Andrea Busi 803843598c feat: Update icon with new version
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/9
2020-08-14 17:28:43 +02:00
Andrea Busi 11884cd897 docs: Use proper format in Changelog file 2020-08-14 17:14:25 +02:00
Andrea Busi 050b4467d6 refactor: Remove Tsunami section 2020-08-13 18:32:22 +02:00
Andrea Busi 2b01ffe621 refactor: Remove unused "Master" and "Detail" controllers 2020-08-13 18:25:24 +02:00
Andrea Busi 78abc28a7e refactor: Remove useless imports of MasterViewController 2020-08-13 13:31:18 +02:00
322 changed files with 7605 additions and 17669 deletions
+131 -4
View File
@@ -1,20 +1,147 @@
# Changelog
## Versione 2.3.2
### Build (41)
- Corretto caricamento parametri settings
- Corretto filtro per rete Geonet
- Fix minori
## Versione 2.3.1
### Build (35)
- Aggiunto controllo su data in schede sismi per evitare crash
- Aggiunta gestione dati meteo non disponibili
## 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)
- Corretto problema in salvataggio impostazione allerte in tempo reale
## Versione 2.2
### Build (19)
- Semplificate alcune voci nel menu Impostazioni
### Build (18)
- Impostazioni occupa ora un tab di navigazione
- Rimosso menu laterale e spostati link in sezione Impostazioni
- Rimossi riferimenti a CoraData inutilizzati
- Aggiornata icona app
- Aggiornati messaggi per permesso localizzatione (stato Consenti Sempre)
## Versione 2.1
### Build (17)
- Utilizzo nuove icone interne all'app
### Build (16)
- Correzioni varie a menu impostazioni
### Build (15)
- Completamento restyling sezione Impostazioni
- Correzioni varie in impostazioni (issue #11)
### Build (14)
- Inizio restyling sezione Impostazioni (Notifiche sismi con nuovo layout)
### Build (13)
- Aggiornate dipendenze (GMA SDK compatibile con iOS 14)
- Risolti warning Xcode 11.5
### Build (12)
- Migliorata gestione layout banner in sezioni principali (se banner è nascosto, tabella occupa tutto lo spazio disponibile)
- Corretta gesture per aprire menu laterale
- Aggiornate icone con nuova versione
### Build (11)
- Corretto crash in invio segnalazione sisma
### Build (10)
- Utilizzo tab bar nativa per gestione sezioni app
- Rimossa sezione Tsunami
## Versione 2.0
## Build (9)
### Build (9)
- Aggiunta integrazione con Crashlytics
- Risolto problema con mappa segnalazioni
## Build (8)
### Build (8)
- Aggiunti loader durante caricamenti prodotti
- Gestiti messaggi di conferma restore acquisti
## Build (7)
### Build (7)
- Abbonamenti annuali sbloccano versione pro
- Rivisto codice per gestione versione pro e rimosso codice duplicato
## Build (6)
### Build (6)
- Rifatti controller per versione Pro e abbonamenti
- Allineati comportamenti acquisti in-app con versione Android
- Fix crash alla prima installazione
+1 -1
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>2.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSAppTransportSecurity</key>
+1 -1
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>2.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSAppTransportSecurity</key>
@@ -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,12 +10,8 @@
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 */; };
8C14112E21ED2FA300A59729 /* AreaInteresseTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14112D21ED2FA300A59729 /* AreaInteresseTableViewController.m */; };
8C14113121ED3E5B00A59729 /* AllertaSismiTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113021ED3E5B00A59729 /* AllertaSismiTableViewController.m */; };
8C14113121ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113021ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m */; };
8C14113721EE502800A59729 /* EQNAllertaSismica.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113621EE502800A59729 /* EQNAllertaSismica.m */; };
8C149FA321E54E85002C44FD /* NotificheSismiTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C149FA221E54E85002C44FD /* NotificheSismiTableViewController.m */; };
8C2B251121938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2B251021938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m */; };
8C2B25142193927E00E0E25E /* ReteSismiDettagliMappa.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2B25132193927E00E0E25E /* ReteSismiDettagliMappa.m */; };
8C465D9A21F653AB00F04673 /* Assets.xcassets in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CBD3DD12149B9AD0070C963 /* Assets.xcassets */; };
@@ -25,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 */; };
@@ -46,53 +39,33 @@
8C4E344B2152EE5B008B0D2A /* EQNGeneratoreURLServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C4E344A2152EE5B008B0D2A /* EQNGeneratoreURLServer.m */; };
8C593E8A217BA2470008B260 /* EQNSegnalazione.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C593E89217BA2470008B260 /* EQNSegnalazione.m */; };
8C5EA22D21763103002DC156 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5EA22C21763102002DC156 /* MapKit.framework */; };
8C5EA23A2177B3ED002DC156 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C5EA2392177B3ED002DC156 /* MasterViewController.m */; };
8C5EA23D2177B51C002DC156 /* SegnalazioniViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C5EA23C2177B51C002DC156 /* SegnalazioniViewController.m */; };
8C602246218D9DB200C799C2 /* PastquakesDettagliMappa.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C602245218D9DB200C799C2 /* PastquakesDettagliMappa.m */; };
8C60224A218EDBE200C799C2 /* PastquakesAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C602249218EDBE200C799C2 /* PastquakesAnnotation.m */; };
8C6CBAE521597E79005C426A /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8C6CBAE421597E79005C426A /* GoogleService-Info.plist */; };
8C7A3B66225A5EA40045B266 /* NSDictionary+BVJSONString.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C7A3B64225A5EA30045B266 /* NSDictionary+BVJSONString.m */; };
8C7A3B66225A5EA40045B266 /* NSDictionary+EQNExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C7A3B64225A5EA30045B266 /* NSDictionary+EQNExtensions.m */; };
8C7CD64821F7D0F800835812 /* ReteSismicaAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD08637218B3BEE0000CB5E /* ReteSismicaAnnotation.m */; };
8C7CD64921F7D11700835812 /* ReteSismicaAnnotation.m in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CD08637218B3BEE0000CB5E /* ReteSismicaAnnotation.m */; };
8C7CD64A21F7D11700835812 /* ReteSismicaAnnotation.h in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CD08636218B3BEE0000CB5E /* ReteSismicaAnnotation.h */; };
8C7E945A21E548A600B0B770 /* DettadliMenuTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C7E945921E548A600B0B770 /* DettadliMenuTableViewController.m */; };
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 */; };
8CBD3DD02149B9AD0070C963 /* Earthquake_Network.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 8CBD3DCE2149B9AD0070C963 /* Earthquake_Network.xcdatamodeld */; };
8CBD3DD22149B9AD0070C963 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8CBD3DD12149B9AD0070C963 /* Assets.xcassets */; };
8CBD3DD52149B9AD0070C963 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8CBD3DD32149B9AD0070C963 /* LaunchScreen.storyboard */; };
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 */; };
8CCE164821E69AEC00173CD9 /* TempoRealeTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE164721E69AEC00173CD9 /* TempoRealeTableViewController.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 */; };
8CCE165521EA378800173CD9 /* SegnalazioniUtentiTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE165421EA378800173CD9 /* SegnalazioniUtentiTableViewController.m */; };
8CCE165821EB1E0000173CD9 /* RetiSismicheTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE165721EB1E0000173CD9 /* RetiSismicheTableViewController.m */; };
8CCE165B21EB7AD800173CD9 /* ListaEntiTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE165A21EB7AD800173CD9 /* ListaEntiTableViewController.m */; };
8CCE165E21EB9F2400173CD9 /* NotificheTsunamiTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE165D21EB9F2400173CD9 /* NotificheTsunamiTableViewController.m */; };
8CCE166121EBA37500173CD9 /* EQNNotificheTsunami.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE166021EBA37500173CD9 /* EQNNotificheTsunami.m */; };
8CCE166421EBEFBD00173CD9 /* MessaggioInformativoTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CCE166321EBEFBD00173CD9 /* MessaggioInformativoTableViewController.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 */; };
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 */; };
8CD08638218B3BEE0000CB5E /* ReteSismicaAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD08637218B3BEE0000CB5E /* ReteSismicaAnnotation.m */; };
8CEAE4D92163E23E001A42B9 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CEAE4D82163E23D001A42B9 /* SWRevealViewController.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 */; };
@@ -104,20 +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 */; };
8CFA63202197F9C10099EB0E /* TsunamiViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CFA631F2197F9C10099EB0E /* TsunamiViewController.m */; };
8CFA6323219A2C610099EB0E /* Tsunami.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CFA6322219A2C610099EB0E /* Tsunami.m */; };
8CFA6326219A41590099EB0E /* DettagliTsunamiViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CFA6325219A41590099EB0E /* DettagliTsunamiViewController.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 */; };
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 */; };
DCAB01E324CEBFE800E8B54C /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAB01E224CEBFE800E8B54C /* MenuViewController.swift */; };
DCAB01E524CEC12E00E8B54C /* MenuHeaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAB01E424CEC12E00E8B54C /* MenuHeaderTableViewCell.swift */; };
DCAB01E724CEC22100E8B54C /* MenuItemTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAB01E624CEC22100E8B54C /* MenuItemTableViewCell.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 */; };
@@ -125,9 +112,20 @@
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 */; };
DCEFF21A24F587E3009D3FE1 /* SettingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCEFF21924F587E3009D3FE1 /* SettingItem.swift */; };
DCF10DC624D2B8C7009F34C3 /* EQNPurchaseUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF10DC524D2B8C7009F34C3 /* EQNPurchaseUtility.swift */; };
DCF10DCD24D2C935009F34C3 /* EQNPurchaseAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF10DCC24D2C935009F34C3 /* EQNPurchaseAvailability.swift */; };
DCF4A54524F8DB8300B17326 /* SettingDateTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF4A54424F8DB8300B17326 /* SettingDateTableViewCell.swift */; };
DCF9E14D24F6D1AA002B6B1D /* EQNData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF9E14C24F6D1AA002B6B1D /* EQNData.swift */; };
DCF9E14F24F6EA07002B6B1D /* EQNSeismicNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF9E14E24F6EA07002B6B1D /* EQNSeismicNetwork.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -175,18 +173,10 @@
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>"; };
8C14112C21ED2FA300A59729 /* AreaInteresseTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AreaInteresseTableViewController.h; sourceTree = "<group>"; };
8C14112D21ED2FA300A59729 /* AreaInteresseTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AreaInteresseTableViewController.m; sourceTree = "<group>"; };
8C14112F21ED3E5B00A59729 /* AllertaSismiTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AllertaSismiTableViewController.h; sourceTree = "<group>"; };
8C14113021ED3E5B00A59729 /* AllertaSismiTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AllertaSismiTableViewController.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>"; };
8C14113621EE502800A59729 /* EQNAllertaSismica.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNAllertaSismica.m; sourceTree = "<group>"; };
8C149FA121E54E85002C44FD /* NotificheSismiTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificheSismiTableViewController.h; sourceTree = "<group>"; };
8C149FA221E54E85002C44FD /* NotificheSismiTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificheSismiTableViewController.m; sourceTree = "<group>"; };
8C2B250F21938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SegnalazioniUtenteDettagliMappa.h; sourceTree = "<group>"; };
8C2B251021938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SegnalazioniUtenteDettagliMappa.m; sourceTree = "<group>"; };
8C2B25122193927E00E0E25E /* ReteSismiDettagliMappa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReteSismiDettagliMappa.h; sourceTree = "<group>"; };
@@ -218,8 +208,6 @@
8C593E88217BA2470008B260 /* EQNSegnalazione.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNSegnalazione.h; sourceTree = "<group>"; };
8C593E89217BA2470008B260 /* EQNSegnalazione.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNSegnalazione.m; sourceTree = "<group>"; };
8C5EA22C21763102002DC156 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
8C5EA2382177B3ED002DC156 /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = "<group>"; };
8C5EA2392177B3ED002DC156 /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = "<group>"; };
8C5EA23B2177B51C002DC156 /* SegnalazioniViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SegnalazioniViewController.h; sourceTree = "<group>"; };
8C5EA23C2177B51C002DC156 /* SegnalazioniViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SegnalazioniViewController.m; sourceTree = "<group>"; };
8C602244218D9DB200C799C2 /* PastquakesDettagliMappa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PastquakesDettagliMappa.h; sourceTree = "<group>"; };
@@ -227,33 +215,22 @@
8C602248218EDBE200C799C2 /* PastquakesAnnotation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PastquakesAnnotation.h; sourceTree = "<group>"; };
8C602249218EDBE200C799C2 /* PastquakesAnnotation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PastquakesAnnotation.m; sourceTree = "<group>"; };
8C6CBAE421597E79005C426A /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
8C7A3B64225A5EA30045B266 /* NSDictionary+BVJSONString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+BVJSONString.m"; sourceTree = "<group>"; };
8C7A3B65225A5EA40045B266 /* NSDictionary+BVJSONString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+BVJSONString.h"; sourceTree = "<group>"; };
8C7E945821E548A600B0B770 /* DettadliMenuTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DettadliMenuTableViewController.h; sourceTree = "<group>"; };
8C7E945921E548A600B0B770 /* DettadliMenuTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DettadliMenuTableViewController.m; sourceTree = "<group>"; };
8C7A3B64225A5EA30045B266 /* NSDictionary+EQNExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+EQNExtensions.m"; sourceTree = "<group>"; };
8C7A3B65225A5EA40045B266 /* NSDictionary+EQNExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+EQNExtensions.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>"; };
8CBD3DC82149B9AD0070C963 /* ReteSmartphone.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReteSmartphone.h; sourceTree = "<group>"; };
8CBD3DC92149B9AD0070C963 /* ReteSmartphone.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReteSmartphone.m; sourceTree = "<group>"; };
8CBD3DCC2149B9AD0070C963 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
8CBD3DCF2149B9AD0070C963 /* Earthquake_Network.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Earthquake_Network.xcdatamodel; sourceTree = "<group>"; };
8CBD3DD12149B9AD0070C963 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
8CBD3DD42149B9AD0070C963 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
8CBD3DD72149B9AD0070C963 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
@@ -261,44 +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>"; };
8CCE164621E69AEC00173CD9 /* TempoRealeTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TempoRealeTableViewController.h; sourceTree = "<group>"; };
8CCE164721E69AEC00173CD9 /* TempoRealeTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TempoRealeTableViewController.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>"; };
8CCE165321EA378800173CD9 /* SegnalazioniUtentiTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SegnalazioniUtentiTableViewController.h; sourceTree = "<group>"; };
8CCE165421EA378800173CD9 /* SegnalazioniUtentiTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SegnalazioniUtentiTableViewController.m; sourceTree = "<group>"; };
8CCE165621EB1E0000173CD9 /* RetiSismicheTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RetiSismicheTableViewController.h; sourceTree = "<group>"; };
8CCE165721EB1E0000173CD9 /* RetiSismicheTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RetiSismicheTableViewController.m; sourceTree = "<group>"; };
8CCE165921EB7AD800173CD9 /* ListaEntiTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ListaEntiTableViewController.h; sourceTree = "<group>"; };
8CCE165A21EB7AD800173CD9 /* ListaEntiTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ListaEntiTableViewController.m; sourceTree = "<group>"; };
8CCE165C21EB9F2400173CD9 /* NotificheTsunamiTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificheTsunamiTableViewController.h; sourceTree = "<group>"; };
8CCE165D21EB9F2400173CD9 /* NotificheTsunamiTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificheTsunamiTableViewController.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>"; };
8CCE166221EBEFBD00173CD9 /* MessaggioInformativoTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MessaggioInformativoTableViewController.h; sourceTree = "<group>"; };
8CCE166321EBEFBD00173CD9 /* MessaggioInformativoTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MessaggioInformativoTableViewController.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>"; };
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>"; };
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>"; };
8CEAE4D72163E23D001A42B9 /* SWRevealViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWRevealViewController.h; sourceTree = "<group>"; };
8CEAE4D82163E23D001A42B9 /* SWRevealViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWRevealViewController.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>"; };
@@ -317,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>"; };
@@ -328,18 +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>"; };
8CFA631E2197F9C10099EB0E /* TsunamiViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TsunamiViewController.h; sourceTree = "<group>"; };
8CFA631F2197F9C10099EB0E /* TsunamiViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TsunamiViewController.m; 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>"; };
8CFA6324219A41590099EB0E /* DettagliTsunamiViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DettagliTsunamiViewController.h; sourceTree = "<group>"; };
8CFA6325219A41590099EB0E /* DettagliTsunamiViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DettagliTsunamiViewController.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>"; };
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>"; };
DCAB01E224CEBFE800E8B54C /* MenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuViewController.swift; sourceTree = "<group>"; };
DCAB01E424CEC12E00E8B54C /* MenuHeaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuHeaderTableViewCell.swift; sourceTree = "<group>"; };
DCAB01E624CEC22100E8B54C /* MenuItemTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemTableViewCell.swift; 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>"; };
@@ -347,10 +311,21 @@
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>"; };
DCDE0BD824E58CCE00209778 /* EQNMainTabBarController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNMainTabBarController.m; sourceTree = "<group>"; };
DCEFF21224F5821E009D3FE1 /* SettingDetailTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingDetailTableViewCell.swift; sourceTree = "<group>"; };
DCEFF21624F58569009D3FE1 /* SettingSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingSectionHeaderView.swift; sourceTree = "<group>"; };
DCEFF21924F587E3009D3FE1 /* SettingItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingItem.swift; sourceTree = "<group>"; };
DCF10DC524D2B8C7009F34C3 /* EQNPurchaseUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNPurchaseUtility.swift; sourceTree = "<group>"; };
DCF10DCC24D2C935009F34C3 /* EQNPurchaseAvailability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNPurchaseAvailability.swift; sourceTree = "<group>"; };
DCF10DDB24D2E7BE009F34C3 /* Earthquake Network-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Earthquake Network-Prefix.pch"; sourceTree = "<group>"; };
DCF4A54424F8DB8300B17326 /* SettingDateTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingDateTableViewCell.swift; sourceTree = "<group>"; };
DCF9E14C24F6D1AA002B6B1D /* EQNData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNData.swift; sourceTree = "<group>"; };
DCF9E14E24F6EA07002B6B1D /* EQNSeismicNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNSeismicNetwork.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -358,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 */,
);
@@ -414,36 +387,14 @@
8C5EA22E217645C8002DC156 /* ViewController */ = {
isa = PBXGroup;
children = (
8CCE164521E69A9300173CD9 /* impostazioniNotifiche */,
8C602247218D9DBF00C799C2 /* Dettagli mappa */,
8CF05B4A218C41E60055012B /* inputView */,
8CD08632218AF5C80000CB5E /* cellTableView */,
8CEAE4D72163E23D001A42B9 /* SWRevealViewController.h */,
8CEAE4D82163E23D001A42B9 /* SWRevealViewController.m */,
8CBD3DC82149B9AD0070C963 /* ReteSmartphone.h */,
8CBD3DC92149B9AD0070C963 /* ReteSmartphone.m */,
8CF4F4DC2175352E0057110B /* WaitViewController.h */,
8CF4F4DD2175352E0057110B /* WaitViewController.m */,
8C5EA2382177B3ED002DC156 /* MasterViewController.h */,
8C5EA2392177B3ED002DC156 /* MasterViewController.m */,
8C5EA23B2177B51C002DC156 /* SegnalazioniViewController.h */,
8C5EA23C2177B51C002DC156 /* SegnalazioniViewController.m */,
8CAFD7C62182648600F8BD29 /* EQNRetiSismiViewController.h */,
8CAFD7C72182648600F8BD29 /* EQNRetiSismiViewController.m */,
8CABD71F2194B7C700C3E09C /* ImpostazioniViewController.h */,
8CABD7202194B7C700C3E09C /* ImpostazioniViewController.m */,
8CFA631E2197F9C10099EB0E /* TsunamiViewController.h */,
8CFA631F2197F9C10099EB0E /* TsunamiViewController.m */,
8CFA6324219A41590099EB0E /* DettagliTsunamiViewController.h */,
8CFA6325219A41590099EB0E /* DettagliTsunamiViewController.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>";
@@ -457,8 +408,6 @@
8C602245218D9DB200C799C2 /* PastquakesDettagliMappa.m */,
8C2B250F21938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.h */,
8C2B251021938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m */,
8C2B25122193927E00E0E25E /* ReteSismiDettagliMappa.h */,
8C2B25132193927E00E0E25E /* ReteSismiDettagliMappa.m */,
);
path = "Dettagli mappa";
sourceTree = "<group>";
@@ -510,7 +459,6 @@
8CBD3DC52149B9AD0070C963 /* AppDelegate.h */,
8CBD3DC62149B9AD0070C963 /* AppDelegate.m */,
8C483CB021FDA8C700259FD2 /* Earthquake Network-Bridging-Header.h */,
8CBD3DCE2149B9AD0070C963 /* Earthquake_Network.xcdatamodeld */,
DCB6FBEA24D0B11300ED23B8 /* Controllers */,
DCB6FBE924D0B0DF00ED23B8 /* Models */,
DCC23DED24D28F41003A2404 /* UI */,
@@ -536,74 +484,12 @@
name = Frameworks;
sourceTree = "<group>";
};
8CCE164521E69A9300173CD9 /* impostazioniNotifiche */ = {
isa = PBXGroup;
children = (
8C7E945821E548A600B0B770 /* DettadliMenuTableViewController.h */,
8C7E945921E548A600B0B770 /* DettadliMenuTableViewController.m */,
8C149FA121E54E85002C44FD /* NotificheSismiTableViewController.h */,
8C149FA221E54E85002C44FD /* NotificheSismiTableViewController.m */,
8CCE164621E69AEC00173CD9 /* TempoRealeTableViewController.h */,
8CCE164721E69AEC00173CD9 /* TempoRealeTableViewController.m */,
8CCE165321EA378800173CD9 /* SegnalazioniUtentiTableViewController.h */,
8CCE165421EA378800173CD9 /* SegnalazioniUtentiTableViewController.m */,
8CCE165621EB1E0000173CD9 /* RetiSismicheTableViewController.h */,
8CCE165721EB1E0000173CD9 /* RetiSismicheTableViewController.m */,
8CCE165921EB7AD800173CD9 /* ListaEntiTableViewController.h */,
8CCE165A21EB7AD800173CD9 /* ListaEntiTableViewController.m */,
8CCE165C21EB9F2400173CD9 /* NotificheTsunamiTableViewController.h */,
8CCE165D21EB9F2400173CD9 /* NotificheTsunamiTableViewController.m */,
8CCE166221EBEFBD00173CD9 /* MessaggioInformativoTableViewController.h */,
8CCE166321EBEFBD00173CD9 /* MessaggioInformativoTableViewController.m */,
8C14112C21ED2FA300A59729 /* AreaInteresseTableViewController.h */,
8C14112D21ED2FA300A59729 /* AreaInteresseTableViewController.m */,
8C14112F21ED3E5B00A59729 /* AllertaSismiTableViewController.h */,
8C14113021ED3E5B00A59729 /* AllertaSismiTableViewController.m */,
);
path = impostazioniNotifiche;
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>";
@@ -623,7 +509,6 @@
8CF66049214C09E0009F4314 /* model */ = {
isa = PBXGroup;
children = (
8CCE165221EA370200173CD9 /* impostazioni notifiche */,
8C60224B218EDBF700C799C2 /* annotation */,
8C8EBBA521540039002784BA /* EQNUser.h */,
8C8EBBA621540039002784BA /* EQNUser.m */,
@@ -649,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>";
@@ -670,6 +549,39 @@
name = Pods;
sourceTree = "<group>";
};
DC10563F251E7EC0002579BB /* Extensions */ = {
isa = PBXGroup;
children = (
DC105640251E7ECE002579BB /* UIFont+Extensions.swift */,
8C7A3B65225A5EA40045B266 /* NSDictionary+EQNExtensions.h */,
8C7A3B64225A5EA30045B266 /* NSDictionary+EQNExtensions.m */,
);
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 = (
@@ -708,10 +620,9 @@
DC3ADD2F24CB1EFB00737919 /* Libs */ = {
isa = PBXGroup;
children = (
DC10563F251E7EC0002579BB /* Extensions */,
8CF66054214C566A009F4314 /* Reachability.h */,
8CF66056214C566A009F4314 /* Reachability.m */,
8C7A3B65225A5EA40045B266 /* NSDictionary+BVJSONString.h */,
8C7A3B64225A5EA30045B266 /* NSDictionary+BVJSONString.m */,
);
path = Libs;
sourceTree = "<group>";
@@ -724,23 +635,40 @@
path = Storyboards;
sourceTree = "<group>";
};
DCAB01E124CEBFD500E8B54C /* Menu */ = {
DC3CE508250EB78C005A7DD5 /* Shared */ = {
isa = PBXGroup;
children = (
DCAB01E224CEBFE800E8B54C /* MenuViewController.swift */,
DCAB01E424CEC12E00E8B54C /* MenuHeaderTableViewCell.swift */,
DCAB01E624CEC22100E8B54C /* MenuItemTableViewCell.swift */,
DC3CE509250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift */,
);
path = Menu;
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>";
};
DCB6FBE924D0B0DF00ED23B8 /* Models */ = {
isa = PBXGroup;
children = (
DCF9E15024F6EA0B002B6B1D /* Networks */,
DC99A50124E66DFB0071BC9F /* Commands */,
DCEFF21824F587CC009D3FE1 /* Settings */,
8C483CBB21FDACE500259FD2 /* VersioneProProducts.swift */,
8C483CB721FDACD300259FD2 /* IAPHelper.swift */,
DCF10DC524D2B8C7009F34C3 /* EQNPurchaseUtility.swift */,
DCF10DCC24D2C935009F34C3 /* EQNPurchaseAvailability.swift */,
DCD4571B24F6CF0D00B58304 /* EQNGenericValue.swift */,
DCF9E14C24F6D1AA002B6B1D /* EQNData.swift */,
DC4B67602517833F00634277 /* EQNSeismic.swift */,
8CAFD7C321825E4A00F8BD29 /* EQNSisma.h */,
8CAFD7C421825E4A00F8BD29 /* EQNSisma.m */,
);
path = Models;
sourceTree = "<group>";
@@ -748,8 +676,14 @@
DCB6FBEA24D0B11300ED23B8 /* Controllers */ = {
isa = PBXGroup;
children = (
DCDE0BD724E58CCE00209778 /* EQNMainTabBarController.h */,
DCDE0BD824E58CCE00209778 /* EQNMainTabBarController.m */,
DC886A5B24E92D5500F7A5D3 /* EQNBaseViewController.h */,
DC886A5C24E92D5500F7A5D3 /* EQNBaseViewController.m */,
DC3CE508250EB78C005A7DD5 /* Shared */,
DCD3E3BE24D1555F007C78D4 /* InApp */,
DCAB01E124CEBFD500E8B54C /* Menu */,
DCEFF21024F57163009D3FE1 /* Settings */,
DC141968250E769B0059E060 /* Seismic Networks */,
);
path = Controllers;
sourceTree = "<group>";
@@ -758,6 +692,8 @@
isa = PBXGroup;
children = (
DCC23DEE24D28F58003A2404 /* EQNEdgeInsetLabel.swift */,
DC03BEAA250BC0A60084769B /* EQNRoundedButton.swift */,
DC52B8A424FCCD6900ABEBA6 /* AppTheme.swift */,
);
path = UI;
sourceTree = "<group>";
@@ -776,6 +712,60 @@
path = InApp;
sourceTree = "<group>";
};
DCEFF21024F57163009D3FE1 /* Settings */ = {
isa = PBXGroup;
children = (
DCEFF21124F581F9009D3FE1 /* Cells */,
DCB28CED24FB8400001F557E /* SettingsViewController.swift */,
DC52B8A024FC145500ABEBA6 /* SettingsBaseViewController.h */,
DC52B8A124FC145500ABEBA6 /* SettingsBaseViewController.m */,
8CCE165321EA378800173CD9 /* SettingsUserReportAlertsViewController.h */,
8CCE165421EA378800173CD9 /* SettingsUserReportAlertsViewController.m */,
8CCE165621EB1E0000173CD9 /* SettingsSeismicNetworkAlertsViewController.h */,
8CCE165721EB1E0000173CD9 /* SettingsSeismicNetworkAlertsViewController.m */,
DC27EB2E24F6EBE000ACBFE0 /* SettingsSeismicNetworksViewController.swift */,
8C14112F21ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.h */,
8C14113021ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m */,
);
path = Settings;
sourceTree = "<group>";
};
DCEFF21124F581F9009D3FE1 /* Cells */ = {
isa = PBXGroup;
children = (
DCEFF21624F58569009D3FE1 /* SettingSectionHeaderView.swift */,
DCEFF21224F5821E009D3FE1 /* SettingDetailTableViewCell.swift */,
DC08803E24F5A89000186D97 /* SettingEnableTableViewCell.swift */,
DC08804024F5B41400186D97 /* SettingSliderTableViewCell.swift */,
DCAA913E24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift */,
DC0E551224F8063300D54270 /* SettingSegmentedTableViewCell.swift */,
DCF4A54424F8DB8300B17326 /* SettingDateTableViewCell.swift */,
);
path = Cells;
sourceTree = "<group>";
};
DCEFF21824F587CC009D3FE1 /* Settings */ = {
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>";
};
DCF9E15024F6EA0B002B6B1D /* Networks */ = {
isa = PBXGroup;
children = (
DCF9E14E24F6EA07002B6B1D /* EQNSeismicNetwork.swift */,
);
path = Networks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -843,7 +833,7 @@
8CBD3DBA2149B9AD0070C963 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1010;
LastUpgradeCheck = 1200;
ORGANIZATIONNAME = "Earthquake Network";
TargetAttributes = {
8C4B0B7921CACE3F00AED489 = {
@@ -919,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 */,
@@ -954,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",
@@ -961,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",
@@ -1035,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;
@@ -1044,83 +1035,84 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8CF05B54218C41FB0055012B /* TBDInputViewControllerData.m in Sources */,
8CCE166121EBA37500173CD9 /* EQNNotificheTsunami.m in Sources */,
DCEFF21324F5821E009D3FE1 /* SettingDetailTableViewCell.swift in Sources */,
DCC23DEF24D28F58003A2404 /* EQNEdgeInsetLabel.swift in Sources */,
DCAB01E524CEC12E00E8B54C /* MenuHeaderTableViewCell.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 /* RetiSismicheTableViewController.m in Sources */,
8CCE165521EA378800173CD9 /* SegnalazioniUtentiTableViewController.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 */,
8CCE165E21EB9F2400173CD9 /* NotificheTsunamiTableViewController.m in Sources */,
8C7E945A21E548A600B0B770 /* DettadliMenuTableViewController.m in Sources */,
8CABD7212194B7C700C3E09C /* ImpostazioniViewController.m in Sources */,
8CFA63202197F9C10099EB0E /* TsunamiViewController.m in Sources */,
8CCE164421E67F1300173CD9 /* EQNImpostazioniNotifiche.m in Sources */,
DCAA913F24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift in Sources */,
DCF9E14F24F6EA07002B6B1D /* EQNSeismicNetwork.swift in Sources */,
DC2814302519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift in Sources */,
8C14113721EE502800A59729 /* EQNAllertaSismica.m in Sources */,
8C483CBC21FDACE500259FD2 /* VersioneProProducts.swift in Sources */,
8C483CB821FDACD300259FD2 /* IAPHelper.swift in Sources */,
DCDE0BD924E58CCE00209778 /* EQNMainTabBarController.m in Sources */,
8C4E344B2152EE5B008B0D2A /* EQNGeneratoreURLServer.m in Sources */,
8CCE164821E69AEC00173CD9 /* TempoRealeTableViewController.m in Sources */,
DC99A50724E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift in Sources */,
8CF4F4D5216D336B0057110B /* EQNDatoGrafico.m in Sources */,
8CF66058214C566B009F4314 /* ServerRequest.m in Sources */,
8CD08638218B3BEE0000CB5E /* ReteSismicaAnnotation.m in Sources */,
8CD0862E218A41930000CB5E /* CellDettagliMappaTableViewCell.m in Sources */,
8CBD3DD02149B9AD0070C963 /* Earthquake_Network.xcdatamodeld in Sources */,
8C9B755F2233BFDE00F8FDEE /* FiltroEnti.m in Sources */,
DCAB01E724CEC22100E8B54C /* MenuItemTableViewCell.swift in Sources */,
DCF9E14D24F6D1AA002B6B1D /* EQNData.swift in Sources */,
DC52B8A524FCCD6900ABEBA6 /* AppTheme.swift in Sources */,
DC27EB2F24F6EBE000ACBFE0 /* SettingsSeismicNetworksViewController.swift in Sources */,
8CF66059214C566B009F4314 /* Reachability.m in Sources */,
DC886A5D24E92D5500F7A5D3 /* EQNBaseViewController.m in Sources */,
8C593E8A217BA2470008B260 /* EQNSegnalazione.m in Sources */,
8C14112E21ED2FA300A59729 /* AreaInteresseTableViewController.m in Sources */,
DCBB267C24D1E98300F04559 /* EQNBaseTableViewCell.swift in Sources */,
8CBD3DCA2149B9AD0070C963 /* ReteSmartphone.m in Sources */,
DCF10DCD24D2C935009F34C3 /* EQNPurchaseAvailability.swift in Sources */,
8C13E84F220B89360009CFE4 /* ElencoFiltroEntiTableViewController.m in Sources */,
8CFA6326219A41590099EB0E /* DettagliTsunamiViewController.m in Sources */,
DC08803F24F5A89000186D97 /* SettingEnableTableViewCell.swift in Sources */,
8CAFD7C521825E4A00F8BD29 /* EQNSisma.m in Sources */,
DCC23DEC24D281CE003A2404 /* SubscriptionsActiveTableViewCell.swift in Sources */,
8CF6604F214C0E58009F4314 /* EQNCalibrazione.m in Sources */,
DCD3E3C024D15576007C78D4 /* PurchaseProVersionViewController.swift in Sources */,
8C2B25142193927E00E0E25E /* ReteSismiDettagliMappa.m in Sources */,
8CF05B51218C41FB0055012B /* PickerViewController.m in Sources */,
8CF4F4DE2175352E0057110B /* WaitViewController.m in Sources */,
8CD08635218AF6030000CB5E /* Cell_Meteo_TableViewCell.m in Sources */,
8C149FA321E54E85002C44FD /* NotificheSismiTableViewController.m in Sources */,
8CD08631218ADFCA0000CB5E /* Cell_Reti_sismicheTableViewCell.m in Sources */,
DC99A50324E66E270071BC9F /* EQNCommandProtocol.swift in Sources */,
DCB45BC8250E86E100DB2D0C /* SeismicSettingsViewController.swift in Sources */,
DCF10DC624D2B8C7009F34C3 /* EQNPurchaseUtility.swift in Sources */,
8C2B251121938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m in Sources */,
8C5EA23A2177B3ED002DC156 /* MasterViewController.m in Sources */,
8C14113121ED3E5B00A59729 /* AllertaSismiTableViewController.m in Sources */,
8CCE164B21E7BAB200173CD9 /* EQNNotificheTempoReale.m in Sources */,
DC0E551324F8063300D54270 /* SettingSegmentedTableViewCell.swift in Sources */,
DCEFF21724F58569009D3FE1 /* SettingSectionHeaderView.swift in Sources */,
8C14113121ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m in Sources */,
DCBB267A24D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift in Sources */,
8CEAE4D92163E23E001A42B9 /* SWRevealViewController.m in Sources */,
DC65B391250F243E00251693 /* SeismicSettingsNetworksViewController.swift in Sources */,
8CF4F4D2216D2C780057110B /* EQNReteSmartphone.m in Sources */,
DC08804124F5B41400186D97 /* SettingSliderTableViewCell.swift in Sources */,
8CBD3DD82149B9AD0070C963 /* main.m in Sources */,
8CF05B57218C93BA0055012B /* EQNUtility.m in Sources */,
8C4E34422152B5E8008B0D2A /* EQNRilevamento.m in Sources */,
8C7A3B66225A5EA40045B266 /* NSDictionary+BVJSONString.m in Sources */,
8C7A3B66225A5EA40045B266 /* NSDictionary+EQNExtensions.m in Sources */,
8CF66053214C12DC009F4314 /* EQNMath.m in Sources */,
DCF4A54524F8DB8300B17326 /* SettingDateTableViewCell.swift in Sources */,
8C60224A218EDBE200C799C2 /* PastquakesAnnotation.m in Sources */,
8CC1B15A217CB09100F22178 /* DettagliMappaViewController.m in Sources */,
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 */,
8CCE165B21EB7AD800173CD9 /* ListaEntiTableViewController.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 */,
DCAB01E324CEBFE800E8B54C /* MenuViewController.swift in Sources */,
DCEFF21A24F587E3009D3FE1 /* SettingItem.swift in Sources */,
8C8EBBA721540039002784BA /* EQNUser.m in Sources */,
8CADAA9421B2627D0044E256 /* LogViewController.m in Sources */,
8CCE166421EBEFBD00173CD9 /* MessaggioInformativoTableViewController.m in Sources */,
DC3BA11124D1A9C90062EE7F /* SubscriptionsViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1210,11 +1202,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 41;
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.3.2;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1231,11 +1224,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 41;
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.3.2;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1272,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;
@@ -1330,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;
@@ -1366,13 +1362,14 @@
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 41;
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.3.2;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@@ -1393,12 +1390,13 @@
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 41;
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.3.2;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@@ -1414,11 +1412,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 41;
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.3.2;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationContent;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1435,11 +1434,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 41;
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.3.2;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationContent;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1490,19 +1490,6 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
8CBD3DCE2149B9AD0070C963 /* Earthquake_Network.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
8CBD3DCF2149B9AD0070C963 /* Earthquake_Network.xcdatamodel */,
);
currentVersion = 8CBD3DCF2149B9AD0070C963 /* Earthquake_Network.xcdatamodel */;
path = Earthquake_Network.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = 8CBD3DBA2149B9AD0070C963 /* Project object */;
}
@@ -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"
@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Termogea.ipa</key>
<array>
<dict>
<key>architectures</key>
<array>
<string>armv7</string>
<string>arm64</string>
</array>
<key>certificate</key>
<dict>
<key>SHA1</key>
<string></string>
<key>dateExpires</key>
<string></string>
<key>type</key>
<string>Unknown</string>
</dict>
<key>name</key>
<string>Telegea.app</string>
<key>team</key>
<dict>
<key>id</key>
<string>4E74YD2Y2V</string>
<key>name</key>
<string>DEK Italia S.R.L</string>
</dict>
</dict>
</array>
</dict>
</plist>
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<true/>
<key>destination</key>
<string>export</string>
<key>method</key>
<string>ad-hoc</string>
<key>signingStyle</key>
<string>automatic</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>4E74YD2Y2V</string>
<key>thinning</key>
<string>&lt;none&gt;</string>
</dict>
</plist>
File diff suppressed because it is too large Load Diff
+6 -9
View File
@@ -7,18 +7,15 @@
//
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "MasterViewController.h"
#import "ReteSmartphone.h"
@class EQNMainTabBarController;
@class ReteSmartphone;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) MasterViewController *masterViewController;
@property (strong, nonatomic) ReteSmartphone *reteSmartphone;
@property (readonly, strong) NSPersistentContainer *persistentContainer;
- (void)saveContext;
@property (weak, nonatomic) EQNMainTabBarController *mainTabBarController;
@property (weak, nonatomic) ReteSmartphone *reteSmartphone;
@end
+39 -98
View File
@@ -7,16 +7,18 @@
//
#import "AppDelegate.h"
#import "EQNUser.h"
#import "Costanti.h"
#import "ServerRequest.h"
#import "EQNGeneratoreURLServer.h"
#import "EQNUser.h"
#import "EQMAccelerometroManager.h"
#import "EQNManager.h"
#import "MasterViewController.h"
#import "EQNUtility.h"
#import "EQNAllertaSismica.h"
#import "EQNAllertaSismica.h"
#import "EQNNotificheSegnalazioniUtente.h"
#import "EQNNotificeReteSismiche.h"
#import "EQNNotificheReteSismiche.h"
#import "EQNMainTabBarController.h"
@import GoogleMaps;
@import Firebase;
@@ -24,7 +26,7 @@
@import GoogleMobileAds;
@interface AppDelegate () <FIRMessagingDelegate, UNUserNotificationCenterDelegate>
@property (strong, nonatomic) NSArray<id<EQNCommandProtocol>> *commands;
@end
@implementation AppDelegate
@@ -42,6 +44,11 @@
[FIRApp configure];
[FIRMessaging messaging].delegate = self;
// execute commands
EQNStartupCommandsBuilder *builder = [[EQNStartupCommandsBuilder alloc] init];
self.commands = [builder build];
[builder executeWithCommands:self.commands];
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
@@ -97,7 +104,6 @@
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
[self saveContext];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
@@ -154,8 +160,7 @@ fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
else if([userInfo[@"type"] isEqualToString:@"tsunami"])
indexPath = [NSIndexPath indexPathForRow:3 inSection:0];
// [self.masterViewController selezionaItem:indexPath];
[self.masterViewController sincronizza];
[self.mainTabBarController sincronizza];
// Change this to your preferred presentation option
@@ -169,121 +174,57 @@ 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;
NSIndexPath *indexPath;
EQNTabBarSection section = EQNTabBarSectionAllerte;
if ([userInfo[@"type"] isEqualToString:@"eqn"]) {
NSDate *dataRicezione = [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:dataRicezione forKey:NOTIFICHE_RETE_SMARTPHONE_DATA_NOTIFICA];
[EQNUtility writeArrayWithCustomObjToUserDefaults:NOTIFICHE_RETE_SMARTPHONE_DIZIONARIO_NOTIFICA withDict:userInfo];
indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
section = EQNTabBarSectionAllerte;
[[NSUserDefaults standardUserDefaults] synchronize];
} else if([userInfo[@"type"] isEqualToString:@"manual"]) {
section = EQNTabBarSectionSegnalazioni;
} else if([userInfo[@"type"] isEqualToString:@"official"]) {
section = EQNTabBarSectionRetiSismiche;
} else if([userInfo[@"type"] isEqualToString:@"tsunami"]) {
// not handled
}
else if([userInfo[@"type"] isEqualToString:@"manual"])
indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
else if([userInfo[@"type"] isEqualToString:@"official"])
indexPath = [NSIndexPath indexPathForRow:2 inSection:0];
else if([userInfo[@"type"] isEqualToString:@"tsunami"])
indexPath = [NSIndexPath indexPathForRow:3 inSection:0];
[self.masterViewController sincronizza];
[self.masterViewController selezionaItem:indexPath];
[self.mainTabBarController sincronizza];
[self.mainTabBarController selectSection:section];
// Print full message.
completionHandler();
}
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
[self.masterViewController 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 - Core Data stack
#pragma mark - FIRMessagingDelegate
@synthesize persistentContainer = _persistentContainer;
- (NSPersistentContainer *)persistentContainer {
// The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it.
@synchronized (self) {
if (_persistentContainer == nil) {
_persistentContainer = [[NSPersistentContainer alloc] initWithName:@"Earthquake_Network"];
[_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
if (error != nil) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
NSLog(@"Unresolved error %@, %@", error, error.userInfo);
abort();
}
}];
}
}
return _persistentContainer;
}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *context = self.persistentContainer.viewContext;
NSError *error = nil;
if ([context hasChanges] && ![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, error.userInfo);
abort();
}
}
- (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].isSimiSenzaIntensita = YES;;
[[EQNAllertaSismica center] saveUserInfo];
[EQNNotificheSegnalazioniUtente center].isAbilitato = YES;
[EQNNotificheSegnalazioniUtente center].distanzaPosizione = @"300";
[[EQNNotificheSegnalazioniUtente center] saveUserInfo];
[EQNNotificeReteSismiche center].isAbilitato = YES;
[EQNNotificeReteSismiche center].distanzaPosizione = @"1000";
[EQNNotificeReteSismiche center].distanzaVicini = @"100";
[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.
}
@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@@ -18,11 +16,11 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="distquake_app_wave" translatesAutoresizingMaskIntoConstraints="NO" id="Dzo-29-2FJ">
<rect key="frame" x="163.5" y="309.5" width="48" height="48"/>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="eq_icon" translatesAutoresizingMaskIntoConstraints="NO" id="Dzo-29-2FJ">
<rect key="frame" x="104.5" y="250.5" width="166" height="166"/>
<constraints>
<constraint firstAttribute="width" constant="48" id="LX1-1B-H0W"/>
<constraint firstAttribute="height" constant="48" id="UPu-Jc-qjT"/>
<constraint firstAttribute="width" constant="166" id="LX1-1B-H0W"/>
<constraint firstAttribute="height" constant="166" id="UPu-Jc-qjT"/>
</constraints>
</imageView>
</subviews>
@@ -40,6 +38,6 @@
</scene>
</scenes>
<resources>
<image name="distquake_app_wave" width="34.909091949462891" height="34.909091949462891"/>
<image name="eq_icon" width="166" height="166"/>
</resources>
</document>
@@ -0,0 +1,19 @@
//
// EQNBaseViewController.h
// Earthquake Network
//
// Created by Busi Andrea on 16/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface EQNBaseViewController : UIViewController
- (void)refreshUI;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,82 @@
//
// EQNBaseViewController.m
// Earthquake Network
//
// Created by Busi Andrea on 16/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "EQNBaseViewController.h"
#import "EQNUtility.h"
@import GoogleMobileAds;
@interface EQNBaseViewController ()
@property (weak, nonatomic) IBOutlet UIView *bannerContainerView;
@property (strong, nonatomic) GADBannerView *bannerView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bannerContainerHeightConstraint;
@end
@implementation EQNBaseViewController
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[self addBannerView];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didReceiveInAppNotification:)
name:IAPHelperPurchaseNotification object:nil];
}
#pragma mark - Public
- (void)refreshUI
{
// nope
}
#pragma mark - Notification
- (void)didReceiveInAppNotification:(NSNotification *)notification
{
[self.bannerView removeFromSuperview];
self.bannerView = nil;
self.bannerContainerHeightConstraint.constant = 0;
}
#pragma mark - Private
- (void)addBannerView
{
self.bannerView = [self createBannerView];
if (self.bannerView == nil) {
self.bannerContainerHeightConstraint.constant = 0;
return;
}
self.bannerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.bannerView];
[[self.bannerView.centerXAnchor constraintEqualToAnchor:self.bannerContainerView.centerXAnchor] setActive:YES];
[[self.bannerView.bottomAnchor constraintEqualToAnchor:self.bannerContainerView.safeAreaLayoutGuide.bottomAnchor] setActive:YES];
}
- (GADBannerView *)createBannerView
{
if ([EQNPurchaseUtility isProVersionEnabled]) {
return nil;
}
GADBannerView *bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
bannerView.adUnitID = EQN_ADMOB_ANNUNCIO_IDA;
bannerView.rootViewController = self;
bannerView.backgroundColor = [UIColor whiteColor];
[bannerView loadRequest:[GADRequest request]];
return bannerView;
}
@end
@@ -0,0 +1,28 @@
//
// EQNMainTabBarController.h
// Earthquake Network
//
// Created by Busi Andrea on 13/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/// Sections inside the app
typedef NS_ENUM(NSInteger, EQNTabBarSection) {
EQNTabBarSectionAllerte = 0,
EQNTabBarSectionSegnalazioni,
EQNTabBarSectionRetiSismiche,
EQNTabBarSectionImpostazioni
};
@interface EQNMainTabBarController : UITabBarController
- (void)sincronizza;
- (void)selectSection:(EQNTabBarSection)section;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,112 @@
//
// EQNMainTabBarController.m
// Earthquake Network
//
// Created by Busi Andrea on 13/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "EQNMainTabBarController.h"
#import "AppDelegate.h"
#import "EQNBaseViewController.h"
#import "SettingsBaseViewController.h"
#import "EQNUtility.h"
#import "EQNManager.h"
#import "EQNGeneratoreURLServer.h"
#import "ServerRequest.h"
@interface EQNMainTabBarController () <UITabBarControllerDelegate>
@property (nonatomic, strong) IBOutlet UIBarButtonItem *sidebarButton;
@end
@implementation EQNMainTabBarController
static NSString * const SegueIdentifierSettings = @"ShowSettings";
static NSString * const SegueIdentifierLogs = @"ShowLogs";
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.mainTabBarController = self;
[self sincronizza];
// check for an AppStore receipt
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
if (receipt) {
[[ServerRequest defaultServerConnectionSingleton] inviaRicevuta:receipt success:^(id result) {
// nope
} failure:^(NSError *error) {
// nope
}];
}
}
#pragma mark - Public
- (void)sincronizza
{
[[EQNManager defaultManager] sincronizza];
}
- (void)selectSection:(EQNTabBarSection)section
{
NSInteger index = 0;
switch (section) {
case EQNTabBarSectionAllerte: index = 0; break;
case EQNTabBarSectionSegnalazioni: index = 1; break;
case EQNTabBarSectionRetiSismiche: index = 2; break;
case EQNTabBarSectionImpostazioni: index = 3; break;
}
self.selectedIndex = index;
}
#pragma mark - Helpers
- (UIViewController *)getTopControllerFromController:(UIViewController *)viewController
{
// check if the given controller is a UINavigationController
// and, if yes, returns the top view controller
UIViewController *topController = viewController;
if ([viewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navController = (UINavigationController *)viewController;
topController = navController.viewControllers.firstObject;
}
return topController;
}
#pragma mark - UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
// if user switch from settings page, we need to force a settings save
UIViewController *controller = [self getTopControllerFromController:tabBarController.selectedViewController];
if ([controller isKindOfClass:[SettingsViewController class]]) {
[SettingsBaseViewController saveSettings];
}
return YES;
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
UIViewController *controller = [self getTopControllerFromController:viewController];
// force a UI refresh when tab is changed
if ([controller isKindOfClass:[EQNBaseViewController class]]) {
EQNBaseViewController *baseController = (EQNBaseViewController *)controller;
[baseController refreshUI];
}
}
@end
@@ -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
}
@@ -1,40 +0,0 @@
//
// MenuHeaderTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 27/07/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
class MenuHeaderTableViewCell: UITableViewCell {
@IBOutlet weak var appVersionLabel: UILabel!
@IBOutlet weak var appIdLabel: UILabel!
// MARK: - View Lifecycle
override func awakeFromNib() {
super.awakeFromNib()
// add a gradient for the background
let gradient = CAGradientLayer()
let blueColor = UIColor(red: 0.47, green: 0.72, blue: 0.98, alpha: 1.0)
gradient.frame = bounds
gradient.colors = [ blueColor.cgColor, UIColor.white.cgColor ]
layer.insertSublayer(gradient, at: 0)
}
// MARK: - Public
func updateUI() {
if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
let version = NSLocalizedString("Versione", comment: "etichetta versione app")
appVersionLabel.text = "\(version): \(appVersion)"
}
let userId = EQNUser.default().user_ID ?? "n.d."
appIdLabel.text = "ID: \(userId)"
}
}
@@ -1,45 +0,0 @@
//
// MenuItemTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 27/07/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
class MenuItemTableViewCell: UITableViewCell {
@IBOutlet private weak var itemIconImageView: UIImageView!
@IBOutlet private weak var itemTitleLabel: UILabel!
var item: MenuViewController.MenuItem? {
didSet {
updateUI()
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
// MARK: - Private
private func updateUI() {
guard let item = item else { return }
if let iconName = item.icon {
itemIconImageView.tintColor = .darkGray
itemIconImageView.image = UIImage(named: iconName)
}
itemTitleLabel.textColor = .darkGray
itemTitleLabel.text = item.title
}
}
@@ -1,125 +0,0 @@
//
// MenuViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 27/07/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
import SafariServices
class MenuViewController: UITableViewController {
enum MenuItem: CaseIterable {
case header
case settings
case informations
case faq
case help
case author
case sponsors
case disclaimer
case privacy
var title: String {
switch self {
case .header: return ""
case .settings: return NSLocalizedString("Impostazioni", comment: "voce menu")
case .informations: return NSLocalizedString("Informazioni", comment: "voce menu")
case .faq: return NSLocalizedString("F.A.Q.", comment: "voce menu")
case .help: return NSLocalizedString("Help", comment: "voce menu")
case .author: return NSLocalizedString("Autore", comment: "voce menu")
case .sponsors: return NSLocalizedString("Patrocinatori", comment: "voce menu")
case .disclaimer: return NSLocalizedString("Disclaimer", comment: "voce menu")
case .privacy: return NSLocalizedString("Privacy", comment: "voce menu")
}
}
var icon: String? {
switch self {
case .header: return nil
case .settings: return "menu-icon-settings"
case .informations: return "menu-icon-info"
case .faq: return "menu-icon-faq"
case .help: return "menu-icon-help"
case .author: return "menu-icon-author"
case .sponsors: return "menu-icon-sponsors"
case .disclaimer: return "menu-icon-terms"
case .privacy: return "menu-icon-privacy"
}
}
}
private let items = MenuItem.allCases
private static let CellIdentifierHeader = "HeaderCell"
private static let CellIdentifierItem = "MenuItemCell"
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
items.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let item = items[indexPath.row]
if item == .header {
return 160
}
return 60
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = items[indexPath.row]
if item == .header {
let cell = tableView.dequeueReusableCell(withIdentifier: Self.CellIdentifierHeader, for: indexPath) as! MenuHeaderTableViewCell
cell.updateUI()
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: Self.CellIdentifierItem, for: indexPath) as! MenuItemTableViewCell
cell.item = item
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.revealViewController()?.revealToggle(animated: true)
let item = items[indexPath.row]
switch item {
case .header:
break
case .settings:
NotificationCenter.default.post(name: NSNotification.Name(rawValue: NOTIFICHE_SISMI), object: nil)
default:
// open url if available
if let url = externalUrl(for: item) {
let controller = SFSafariViewController(url: url)
present(controller, animated: true, completion: nil)
}
}
}
// MARK: - Private
private func externalUrl(for item: MenuItem) -> URL? {
let baseUrl = EQNWebsiteAddress
switch item {
case .informations: return URL(string: "\(baseUrl)")
case .faq: return URL(string: "\(baseUrl)/f-a-q/")
case .help: return URL(string: "\(baseUrl)/help/")
case .author: return URL(string: "\(baseUrl)/contact/")
case .sponsors: return URL(string: "\(baseUrl)/sponsors/")
case .disclaimer: return URL(string: "\(baseUrl)/terms-conditions/")
case .privacy: return URL(string: "\(baseUrl)/privacy/")
default: return nil
}
}
}
@@ -0,0 +1,727 @@
//
// 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, hasValidWeatherData: Bool)
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.setContentHuggingPriority(.init(800), for: .horizontal)
placeLabel.setContentHuggingPriority(.init(200), for: .horizontal)
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)
}
// we need to check agains null values, because sometimes WS returns invalid dates
if let date = seismic.date {
let formattedDate = Self.dateFormatter.string(from: 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)"
} else {
timeLabel.text = "🕗 no time available"
}
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 {
let validData = seismic?.weatherCode != nil
delegate?.seismicNetworkCellDidTapWeather(self, hasValidWeatherData: validData)
}
}
@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,355 @@
//
// 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, hasValidWeatherData: Bool) {
guard let index = tableView?.indexPath(for: cell) else { return }
if !hasValidWeatherData {
let alert = UIAlertController(title: NSLocalizedString("Attenzione", comment: ""),
message: NSLocalizedString("weather_nodata", comment: ""),
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default))
present(alert, animated: true)
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)
}
}
@@ -0,0 +1,123 @@
//
// SettingDateTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 28/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
class SettingDateTableViewCell: UITableViewCell {
@objc static let Identifier = "DateCell"
@objc var isDisabled: Bool = false {
didSet {
updateUI()
}
}
@objc var isPickerVisible: Bool = false {
didSet {
if oldValue != isPickerVisible {
updateUI()
}
}
}
@objc private(set) var date = Date()
@objc var valueChanged: ((Date) -> Void)?
// MARK: - Properties
@objc lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .body)
label.textColor = AppTheme.shared.textColor
return label
}()
@objc lazy var valuesLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .subheadline)
label.textColor = AppTheme.shared.valueColor
return label
}()
@objc lazy var datePicker: UIDatePicker = {
let picker = UIDatePicker()
picker.translatesAutoresizingMaskIntoConstraints = false
picker.datePickerMode = .time
picker.date = self.date
picker.addTarget(self, action: #selector(datePickerChanged(_:)), for: .valueChanged)
return picker
}()
@objc lazy var stackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.spacing = 8
return stackView
}()
// 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: - Public
@objc public func updateDate(_ date: Date) {
self.date = date
datePicker.setDate(date, animated: true)
}
// MARK: - Private
private func setupUI() {
translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(valuesLabel)
contentView.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor).isActive = true
}
private func updateUI() {
let theme = AppTheme.shared
titleLabel.textColor = isDisabled ? theme.textDisabledColor : theme.textColor
valuesLabel.textColor = isDisabled ? theme.textDisabledColor : theme.textColor
if isPickerVisible && !stackView.arrangedSubviews.contains(datePicker) {
stackView.addArrangedSubview(datePicker)
} else if !isPickerVisible && stackView.arrangedSubviews.contains(datePicker) {
stackView.removeArrangedSubview(datePicker)
}
}
// MARK: - Actions
@objc func datePickerChanged(_ sender: UIDatePicker) {
date = sender.date
valueChanged?(sender.date)
}
}
@@ -0,0 +1,26 @@
//
// SettingDetailTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
class SettingDetailTableViewCell: UITableViewCell {
@objc static let Identifier = "DetailCell"
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
@@ -0,0 +1,101 @@
//
// SettingEnableTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
class SettingEnableTableViewCell: UITableViewCell {
@objc static let Identifier = "EnableCell"
@objc var valueChanged: ((Bool) -> Void)?
@objc var isDisabled: Bool = false {
didSet {
updateUI()
}
}
// MARK: - Properties
@objc lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .body)
return label
}()
@objc lazy var descriptionLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .subheadline)
return label
}()
@objc lazy var toggleSwitch: UISwitch = {
let toggle = UISwitch()
toggle.setContentHuggingPriority(.required, for: .horizontal)
toggle.setContentCompressionResistancePriority(.required, for: .horizontal)
toggle.addTarget(self, action: #selector(toggleChanged(_:)), for: .valueChanged)
return toggle
}()
// 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: - Private
private func setupUI() {
selectionStyle = .none
translatesAutoresizingMaskIntoConstraints = false
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.distribution = .fill
stackView.alignment = .center
stackView.spacing = 8
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(toggleSwitch)
contentView.addSubview(stackView)
contentView.addSubview(descriptionLabel)
stackView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor).isActive = true
descriptionLabel.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 8).isActive = true
descriptionLabel.trailingAnchor.constraint(equalTo: stackView.trailingAnchor).isActive = true
descriptionLabel.leadingAnchor.constraint(equalTo: stackView.leadingAnchor).isActive = true
descriptionLabel.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor).isActive = true
}
private func updateUI() {
toggleSwitch.isEnabled = !isDisabled
titleLabel.textColor = isDisabled ? .lightGray : .black
descriptionLabel.textColor = isDisabled ? .lightGray : .black
}
// MARK: - Action
@objc private func toggleChanged(_ sender: UISwitch) {
valueChanged?(sender.isOn)
}
}
@@ -0,0 +1,81 @@
//
// SettingMultivaluesTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 26/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
class SettingMultivaluesTableViewCell: UITableViewCell {
@objc static let Identifier = "MultivaluesCell"
@objc var isDisabled: Bool = false {
didSet {
updateUI()
}
}
// MARK: - Properties
@objc lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .body)
label.textColor = AppTheme.shared.textColor
return label
}()
@objc lazy var valuesLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .subheadline)
label.textColor = AppTheme.shared.valueColor
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: - Private
private func setupUI() {
translatesAutoresizingMaskIntoConstraints = false
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.spacing = 8
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(valuesLabel)
contentView.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor).isActive = true
}
private func updateUI() {
let theme = AppTheme.shared
titleLabel.textColor = isDisabled ? theme.textDisabledColor : theme.textColor
valuesLabel.textColor = isDisabled ? theme.textDisabledColor : theme.valueColor
}
}
@@ -0,0 +1,50 @@
//
// SettingSectionHeaderView.swift
// Earthquake Network
//
// Created by Busi Andrea on 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
class SettingSectionHeaderView: UITableViewHeaderFooterView {
@objc static let Identifier = "SectionHeaderView"
@objc static let Height = 50.0
// MARK: - Properties
@objc lazy var titleLabel: UILabel = {
let titleLabel = UILabel()
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
titleLabel.textColor = AppTheme.Colors.lightBlue
return titleLabel
}()
// MARK: - Init
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupUI()
}
// MARK: - Private
private func setupUI() {
contentView.addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
}
}
@@ -0,0 +1,104 @@
//
// SettingSegmentedTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 27/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
class SettingSegmentedTableViewCell: UITableViewCell {
@objc static let Identifier = "SegmentedCell"
@objc var isDisabled: Bool = false {
didSet {
updateUI()
}
}
@objc var valueChanged: ((EQNGenericValue) -> Void)?
private var items = [EQNGenericValue]()
// MARK: - Properties
@objc lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .body)
label.textColor = AppTheme.shared.textColor
return label
}()
@objc lazy var segmentedControl: UISegmentedControl = {
let segmented = UISegmentedControl()
segmented.translatesAutoresizingMaskIntoConstraints = false
segmented.addTarget(self, action: #selector(segmentedControlChanged(_:)), for: .valueChanged)
return segmented
}()
// 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: - Private
private func setupUI() {
selectionStyle = .none
translatesAutoresizingMaskIntoConstraints = false
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.spacing = 8
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(segmentedControl)
contentView.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor).isActive = true
}
private func updateUI() {
let theme = AppTheme.shared
titleLabel.textColor = isDisabled ? theme.textDisabledColor : theme.textColor
segmentedControl.isEnabled = !isDisabled
}
// MARK: - Actions
@objc private func segmentedControlChanged(_ sender: UISegmentedControl) {
let item = items[sender.selectedSegmentIndex]
valueChanged?(item)
}
// MARK: - Public
@objc func configureControl(with items: [EQNGenericValue], current: EQNGenericValue) {
self.items = items
segmentedControl.removeAllSegments()
items.enumerated().forEach { (index, value) in
segmentedControl.insertSegment(withTitle: value.display, at: index, animated: false)
}
if let index = items.firstIndex(of: current) {
segmentedControl.selectedSegmentIndex = index
}
}
}
@@ -0,0 +1,125 @@
//
// SettingSliderTableViewCell.swift
// Earthquake Network
//
// Created by Busi Andrea on 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
class SettingSliderTableViewCell: UITableViewCell {
@objc static let Identifier = "SliderCell"
@objc var isDisabled: Bool = false {
didSet {
updateUI()
}
}
@objc var valueChanged: ((EQNGenericValue) -> Void)?
@objc var dragEnded: (() -> Void)?
private var items = [EQNGenericValue]()
// MARK: - Properties
@objc lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .body)
label.textColor = AppTheme.shared.textColor
return label
}()
@objc lazy var valueLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.preferredFont(forTextStyle: .subheadline)
label.textColor = AppTheme.shared.valueColor
return label
}()
@objc lazy var slider: UISlider = {
let slider = UISlider()
slider.isContinuous = true
slider.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
slider.addTarget(self, action: #selector(sliderEnded(_:)), for: .touchUpInside)
return slider
}()
// 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: - Private
private func setupUI() {
selectionStyle = .none
translatesAutoresizingMaskIntoConstraints = false
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.spacing = 8
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(valueLabel)
stackView.addArrangedSubview(slider)
contentView.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor).isActive = true
}
private func updateUI() {
let theme = AppTheme.shared
titleLabel.textColor = isDisabled ? theme.textDisabledColor : theme.textColor
valueLabel.textColor = isDisabled ? theme.textDisabledColor : theme.valueColor
slider.isEnabled = !isDisabled
}
// MARK: - Actions
@objc private func sliderChanged(_ sender: UISlider) {
let index = Int(sender.value)
let item = items[index]
valueLabel.text = item.display
valueChanged?(item)
}
@objc private func sliderEnded(_ sender: UISlider) {
dragEnded?()
}
// MARK: - Public
@objc func configureSlider(with items: [EQNGenericValue], current: EQNGenericValue) {
self.items = items
slider.minimumValue = 0
slider.maximumValue = Float(items.count - 1)
if let index = items.firstIndex(of: current) {
slider.value = Float(index)
valueLabel.text = current.display
} else {
slider.value = 0
valueLabel.text = ""
}
}
}
@@ -0,0 +1,19 @@
//
// SettingsBaseViewController.h
// Earthquake Network
//
// Created by Busi Andrea on 30/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SettingsBaseViewController : UITableViewController
+ (void)saveSettings;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,42 @@
//
// SettingsBaseViewController.m
// Earthquake Network
//
// Created by Busi Andrea on 30/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "SettingsBaseViewController.h"
#import "ServerRequest.h"
#import "EQNGeneratoreURLServer.h"
@interface SettingsBaseViewController ()
@end
@implementation SettingsBaseViewController
#pragma mark - View Lifecycle
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// when controller is dismissed, save settings
if (self.isMovingFromParentViewController) {
[SettingsBaseViewController saveSettings];
}
}
#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);
}];
}
@end
@@ -0,0 +1,18 @@
//
// AletaSismiTableViewController.h
// Earthquake Network
//
// Refactored by Andrea Busi 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "SettingsBaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface SettingsRealTimeAlertsViewController : SettingsBaseViewController
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,286 @@
//
// AletaSismiTableViewController.m
// Earthquake Network
//
// Refactored by Andrea Busi 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "SettingsRealTimeAlertsViewController.h"
#import "EQNAllertaSismica.h"
@interface SettingsRealTimeAlertsViewController () <UITextFieldDelegate>
@property (nonatomic, strong) NSArray<SettingItem *> *settings;
@property (strong, nonatomic) NSArray<EQNGenericValue *> *dataSourceSismi;
@property (nonatomic, strong) NSArray<EQNGenericValue *> *dataSourceRaggioSisma;
@property (nonatomic, strong) EQNGenericValue *currentSeismicToNotify;
@property (strong, nonatomic) EQNGenericValue *currentLowSeismicRadius;
@property (strong, nonatomic) EQNGenericValue *currentStrongSeismicRadius;
@property (strong, nonatomic) NSDate *currentStartTime;
@property (nonatomic) BOOL isStartTimeExpanded;
@property (strong, nonatomic) NSDate *currentEndTime;
@property (nonatomic) BOOL isEndTimeExpanded;
@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@property (nonatomic, assign) BOOL notificationEnabled;
@property (nonatomic, assign) BOOL doNotDisturbEnabled;
@end
@implementation SettingsRealTimeAlertsViewController
typedef NS_ENUM(NSInteger, RowIdentifier) {
RowIdentifierAbilitaNotifiche = 0,
RowIdentifierSismiDaNotificare,
RowIdentifierRaggioSismiLievi,
RowIndntifierRaggioSismiForti,
RowIdentifierNonDisturbare,
RowIdentifierNonDisturbareOraInizio,
RowIdentifierNonDisturbareOraFine
};
#pragma mark - Accessories
- (NSDateFormatter *)dateFormatter
{
if (!_dateFormatter) {
_dateFormatter = [[NSDateFormatter alloc] init];
[_dateFormatter setDateFormat:@"HH:mm"];
}
return _dateFormatter;
}
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];
self.settings = @[
[[SettingItem alloc] initWithType:SettingTypeEnable title:NSLocalizedString(@"Suona un allarme quando un sisma è rilevato dalla rete smartphone", @"")],
[[SettingItem alloc] initWithType:SettingTypeSegmented title:NSLocalizedString(@"Sismi da notificare", @"") subtitle:NSLocalizedString(@"", @"")],
[[SettingItem alloc] initWithType:SettingTypeSlider title:NSLocalizedString(@"Raggio sismi lievi", @"")],
[[SettingItem alloc] initWithType:SettingTypeSlider title:NSLocalizedString(@"Raggio sismi forti", @"")]
];
// these settings are disabled because on iOS app are not handled
/*
[[SettingItem alloc] initWithType:SettingTypeEnable title:NSLocalizedString(@"Intervallo allarme", @"") subtitle:NSLocalizedString(@"Non attivare allarmi o notifiche in questo lasso di tempo", @"") icon:nil segue:nil],
[[SettingItem alloc] initWithType:SettingTypeDate title:NSLocalizedString(@"Ora di inizio", @"") subtitle:nil icon:nil segue:nil],
[[SettingItem alloc] initWithType:SettingTypeDate title:NSLocalizedString(@"Ora di fine", @"") subtitle:nil icon:nil segue:nil]
*/
self.dataSourceSismi = [EQNData seismicToNotify];
self.dataSourceRaggioSisma = [EQNData raggioSismi];
[self updateUI];
}
#pragma mark - Private
- (void)setupUI
{
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
self.tableView.estimatedRowHeight = 200.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView registerClass:[SettingSectionHeaderView class] forHeaderFooterViewReuseIdentifier:SettingSectionHeaderView.Identifier];
[self.tableView registerClass:[SettingEnableTableViewCell class] forCellReuseIdentifier:SettingEnableTableViewCell.Identifier];
[self.tableView registerClass:[SettingSliderTableViewCell class] forCellReuseIdentifier:SettingSliderTableViewCell.Identifier];
[self.tableView registerClass:[SettingMultivaluesTableViewCell class] forCellReuseIdentifier:SettingMultivaluesTableViewCell.Identifier];
[self.tableView registerClass:[SettingSegmentedTableViewCell class] forCellReuseIdentifier:SettingSegmentedTableViewCell.Identifier];
[self.tableView registerClass:[SettingDateTableViewCell class] forCellReuseIdentifier:SettingDateTableViewCell.Identifier];
}
- (void)updateUI
{
self.notificationEnabled = [EQNAllertaSismica sharedInstance].isAbilitato;
self.doNotDisturbEnabled = [EQNAllertaSismica sharedInstance].isintervalloAllarme;
// sismi da notificare
EQNGenericValue *sismiDaNotificare = [EQNData seismicToNotifyFor:[EQNAllertaSismica sharedInstance].sismiDaNotificare];
self.currentSeismicToNotify = sismiDaNotificare;
// raggio sismi lievi
EQNGenericValue *raggioSismiLievi = [EQNData raggioSismaFor:[EQNAllertaSismica sharedInstance].raggioSismiLievi];
self.currentLowSeismicRadius = raggioSismiLievi;
// raggio sismi forti
EQNGenericValue *raggioSismiForti = [EQNData raggioSismaFor:[EQNAllertaSismica sharedInstance].raggioSismiForti];
self.currentStrongSeismicRadius = raggioSismiForti;
// non disturbare, orari
NSDate *startTime = [EQNData doNotDisturbEndDateFrom:[EQNAllertaSismica sharedInstance].oraioInizio];
self.currentStartTime = startTime;
NSDate *endTime = [EQNData doNotDisturbEndDateFrom:[EQNAllertaSismica sharedInstance].orarioFine];
self.currentEndTime = endTime;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.settings.count;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
SettingSectionHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:SettingSectionHeaderView.Identifier];
headerView.titleLabel.text = NSLocalizedString(@"Alerta sismica", @"titolo impostazioni notifiche");
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return SettingSectionHeaderView.Height;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
SettingItem *setting = self.settings[indexPath.row];
if (setting.type == SettingTypeEnable) {
SettingEnableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingEnableTableViewCell.Identifier forIndexPath:indexPath];
cell.titleLabel.text = setting.displayTitle;
cell.descriptionLabel.text = setting.subtitle;
if (indexPath.row == RowIdentifierAbilitaNotifiche) {
cell.toggleSwitch.on = self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.notificationEnabled = enabled;
[EQNAllertaSismica sharedInstance].isAbilitato = self.notificationEnabled;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
} else if (indexPath.row == RowIdentifierNonDisturbare) {
cell.toggleSwitch.on = self.doNotDisturbEnabled;
cell.isDisabled = !self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.doNotDisturbEnabled = enabled;
[EQNAllertaSismica sharedInstance].isintervalloAllarme = self.doNotDisturbEnabled;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
}
return cell;
} else if (setting.type == SettingTypeSegmented) {
SettingSegmentedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingSegmentedTableViewCell.Identifier forIndexPath:indexPath];
cell.titleLabel.text = setting.displayTitle;
if (indexPath.row == RowIdentifierSismiDaNotificare) {
cell.isDisabled = !self.notificationEnabled;
[cell configureControlWith:self.dataSourceSismi current:self.currentSeismicToNotify];
cell.valueChanged = ^(EQNGenericValue *item) {
[self updateSismicToNotify:item];
};
}
return cell;
} else if (setting.type == SettingTypeSlider) {
SettingSliderTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingSliderTableViewCell.Identifier forIndexPath:indexPath];
cell.titleLabel.text = setting.displayTitle;
if (indexPath.row == RowIdentifierRaggioSismiLievi) {
cell.isDisabled = !self.notificationEnabled;
[cell configureSliderWith:self.dataSourceRaggioSisma current:self.currentLowSeismicRadius];
cell.valueChanged = ^(EQNGenericValue *item) {
[self updateLowSeismicRadius:item];
};
} else if (indexPath.row == RowIndntifierRaggioSismiForti) {
cell.isDisabled = !self.notificationEnabled;
[cell configureSliderWith:self.dataSourceRaggioSisma current:self.currentStrongSeismicRadius];
cell.valueChanged = ^(EQNGenericValue *item) {
[self updateStrongSeismicRadius:item];
};
}
return cell;
} else if (setting.type == SettingTypeDate) {
SettingDateTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingDateTableViewCell.Identifier forIndexPath:indexPath];
cell.isDisabled = !self.doNotDisturbEnabled || !self.notificationEnabled;
cell.userInteractionEnabled = self.doNotDisturbEnabled && self.notificationEnabled;
cell.titleLabel.text = setting.title;
if (indexPath.row == RowIdentifierNonDisturbareOraInizio) {
cell.isPickerVisible = self.isStartTimeExpanded;
[cell updateDate:self.currentStartTime];
cell.valuesLabel.text = [self.dateFormatter stringFromDate:self.currentStartTime];
cell.valueChanged = ^(NSDate *date) {
[self updateStartTime:date];
};
} else if (indexPath.row == RowIdentifierNonDisturbareOraFine) {
cell.isPickerVisible = self.isEndTimeExpanded;
[cell updateDate:self.currentEndTime];
cell.valuesLabel.text = [self.dateFormatter stringFromDate:self.currentEndTime];
cell.valueChanged = ^(NSDate *date) {
[self updateEndTime:date];
};
}
return cell;
}
return nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == RowIdentifierNonDisturbareOraInizio) {
self.isStartTimeExpanded = !self.isStartTimeExpanded;
} else if (indexPath.row == RowIdentifierNonDisturbareOraFine) {
self.isEndTimeExpanded = !self.isEndTimeExpanded;
}
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Private
- (void)updateSismicToNotify:(EQNGenericValue *)seismic
{
[EQNAllertaSismica sharedInstance].sismiDaNotificare = seismic.value;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateLowSeismicRadius:(EQNGenericValue *)radius
{
[EQNAllertaSismica sharedInstance].raggioSismiLievi = radius.value;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateStrongSeismicRadius:(EQNGenericValue *)radius
{
[EQNAllertaSismica sharedInstance].raggioSismiForti = radius.value;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateStartTime:(NSDate *)date
{
[EQNAllertaSismica sharedInstance].oraioInizio = date;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateEndTime:(NSDate *)date
{
[EQNAllertaSismica sharedInstance].orarioFine = date;
[[EQNAllertaSismica sharedInstance] saveUserInfo];
[self updateUI];
}
@end
@@ -0,0 +1,18 @@
//
// SettingsSeismicNetworkAlertsViewController.h
// Earthquake Network
//
// Refactored by Andrea Busi 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "SettingsBaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface SettingsSeismicNetworkAlertsViewController : SettingsBaseViewController
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,258 @@
//
// SettingsSeismicNetworkAlertsViewController.m
// Earthquake Network
//
// Refactored by Andrea Busi 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "SettingsSeismicNetworkAlertsViewController.h"
#import "EQNNotificheReteSismiche.h"
@interface SettingsSeismicNetworkAlertsViewController ()
@property (nonatomic, strong) NSArray<SettingItem *> *settings;
@property (nonatomic, strong) NSArray<EQNGenericValue *> *dataSourceRaggioSisma;
@property (nonatomic, strong) NSArray<EQNGenericValue *> *dataSourceMagnitudoDeboli;
@property (nonatomic, strong) NSArray<EQNGenericValue *> *dataSourceMagnitudoForti;
@property (nonatomic, assign) BOOL notificationEnabled;
@property (nonatomic, assign) BOOL notificationNearEarthquakeEnabled;
@property (nonatomic, assign) BOOL notificationStrongEarthquakeEnabled;
@property (nonatomic, strong) EQNGenericValue *currentUserPositionRadius;
@property (nonatomic, strong) EQNGenericValue *currentSeismicEnergy;
@property (nonatomic, strong) EQNGenericValue *currentStrongEarthquakeDistance;
@end
@implementation SettingsSeismicNetworkAlertsViewController
static NSString * const SegueIdentifierListaEnti = @"ShowListaEnti";
typedef NS_ENUM(NSInteger, RowIdentifier) {
RowIdentifierAbilitaNotifiche = 0,
RowIdentifierRetiSismiche,
RowIdentifierRaggioPosizione,
RowIdentifierEnergiaSisma,
RowIdentifierTerremotiVicini,
RowIdentifierTerremotiForti,
RowIdentifierTerremotiFortiDistanza
};
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];
self.settings = @[
[[SettingItem alloc] initWithType:SettingTypeEnable title:NSLocalizedString(@"Ricevi le notifiche dei sismi rilevati dalle agenzie nazionalie internazionali", @"")],
[[SettingItem alloc] initWithType:SettingTypeMultiValues title:NSLocalizedString(@"Reti sismiche", @"") segue:SegueIdentifierListaEnti],
[[SettingItem alloc] initWithType:SettingTypeSlider title:NSLocalizedString(@"Raggio dalla tua posizione", @"")],
[[SettingItem alloc] initWithType:SettingTypeSlider title:NSLocalizedString(@"Energia sisma", @"")],
[[SettingItem alloc] initWithType:SettingTypeEnable title:NSLocalizedString(@"Terremoti vicini", @"") subtitle:NSLocalizedString(@"Notifica sismi di qualsiasi magnitudo se la distanza è inferiore a 50 km", @"")],
[[SettingItem alloc] initWithType:SettingTypeEnable title:NSLocalizedString(@"Terremoti forti", @"") subtitle:NSLocalizedString(@"Notifica sismi forti a qualsiasi distanza se la magnitudo è maggiore a", @"")],
[[SettingItem alloc] initWithType:SettingTypeSlider title:NSLocalizedString(@"Magnitudo", @"")]
];
self.dataSourceMagnitudoDeboli = [EQNData magitudoDeboli];
self.dataSourceRaggioSisma = [EQNData raggioSismi];
self.dataSourceMagnitudoForti = [EQNData magitudoForti];
[self updateUI];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self updateUI];
}
#pragma mark - Private
- (void)setupUI
{
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
self.tableView.estimatedRowHeight = 200.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView registerClass:[SettingSectionHeaderView class] forHeaderFooterViewReuseIdentifier:SettingSectionHeaderView.Identifier];
[self.tableView registerClass:[SettingEnableTableViewCell class] forCellReuseIdentifier:SettingEnableTableViewCell.Identifier];
[self.tableView registerClass:[SettingSliderTableViewCell class] forCellReuseIdentifier:SettingSliderTableViewCell.Identifier];
[self.tableView registerClass:[SettingMultivaluesTableViewCell class] forCellReuseIdentifier:SettingMultivaluesTableViewCell.Identifier];
}
- (void)updateUI
{
self.notificationEnabled = [EQNNotificheReteSismiche sharedInstance].isAbilitato;
self.notificationNearEarthquakeEnabled = [EQNNotificheReteSismiche sharedInstance].isAbilitaVicini;
self.notificationStrongEarthquakeEnabled = [EQNNotificheReteSismiche sharedInstance].isTerremortiForti;
// raggio dalla tua posizione
EQNGenericValue *raggioSisma = [EQNData raggioSismaFor:[EQNNotificheReteSismiche sharedInstance].distanzaPosizione];
self.currentUserPositionRadius = raggioSisma;
// energia sisma
EQNGenericValue *energiaSisma = [EQNData magitudoDeboleFor:[EQNNotificheReteSismiche sharedInstance].energiaSisma];
self.currentSeismicEnergy = energiaSisma;
// terremoti forti
EQNGenericValue *terremotiForti = [EQNData magitudoForteFor:[EQNNotificheReteSismiche sharedInstance].energiaTerremotiForti];
self.currentStrongEarthquakeDistance = terremotiForti;
// enti
if (![EQNNotificheReteSismiche sharedInstance].listaEnti) {
[EQNNotificheReteSismiche sharedInstance].listaEnti = [EQNData.seismicNetworkAcronyms copy];
}
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
SettingSectionHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:SettingSectionHeaderView.Identifier];
headerView.titleLabel.text = NSLocalizedString(@"Notifiche da reti sismiche", @"titolo impostazioni notifiche");
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return SettingSectionHeaderView.Height;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.settings.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
SettingItem *setting = self.settings[indexPath.row];
if (setting.type == SettingTypeEnable) {
SettingEnableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingEnableTableViewCell.Identifier forIndexPath:indexPath];
cell.titleLabel.text = setting.displayTitle;
cell.descriptionLabel.text = setting.subtitle;
if (indexPath.row == RowIdentifierAbilitaNotifiche) {
cell.toggleSwitch.on = self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.notificationEnabled = enabled;
[EQNNotificheReteSismiche sharedInstance].isAbilitato = self.notificationEnabled;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
} else if (indexPath.row == RowIdentifierTerremotiVicini) {
cell.toggleSwitch.on = self.notificationNearEarthquakeEnabled;
cell.isDisabled = !self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.notificationNearEarthquakeEnabled = enabled;
[EQNNotificheReteSismiche sharedInstance].isAbilitaVicini = self.notificationNearEarthquakeEnabled;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
} else if (indexPath.row == RowIdentifierTerremotiForti) {
cell.toggleSwitch.on = self.notificationStrongEarthquakeEnabled;
cell.isDisabled = !self.notificationEnabled;
cell.valueChanged = ^(BOOL enabled) {
self.notificationStrongEarthquakeEnabled = enabled;
[EQNNotificheReteSismiche sharedInstance].isTerremortiForti = self.notificationStrongEarthquakeEnabled;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
}
return cell;
} else if (setting.type == SettingTypeMultiValues) {
SettingMultivaluesTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingMultivaluesTableViewCell.Identifier forIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.isDisabled = !self.notificationEnabled;
cell.userInteractionEnabled = self.notificationEnabled;
cell.titleLabel.text = setting.title;
if (indexPath.row == RowIdentifierRetiSismiche) {
cell.valuesLabel.text = [self stringOfSelectedNetworks];
}
return cell;
} else if (setting.type == SettingTypeSlider) {
SettingSliderTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingSliderTableViewCell.Identifier forIndexPath:indexPath];
cell.titleLabel.text = setting.displayTitle;
if (indexPath.row == RowIdentifierRaggioPosizione) {
cell.isDisabled = !self.notificationEnabled;
[cell configureSliderWith:self.dataSourceRaggioSisma current:self.currentUserPositionRadius];
cell.valueChanged = ^(EQNGenericValue *item) {
[self updateUserPositionRadius:item];
};
} else if (indexPath.row == RowIdentifierEnergiaSisma) {
cell.isDisabled = !self.notificationEnabled;
[cell configureSliderWith:self.dataSourceMagnitudoDeboli current:self.currentSeismicEnergy];
cell.valueChanged = ^(EQNGenericValue *item) {
[self updateSeismicEnergy:item];
};
} else if (indexPath.row == RowIdentifierTerremotiFortiDistanza) {
cell.isDisabled = !self.notificationEnabled || !self.notificationStrongEarthquakeEnabled;
[cell configureSliderWith:self.dataSourceMagnitudoForti current:self.currentStrongEarthquakeDistance];
cell.valueChanged = ^(EQNGenericValue *item) {
[self updateStrongEarthquakeEnergy:item];
};
}
return cell;
}
return nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SettingItem *setting = self.settings[indexPath.row];
if (setting.segue != nil) {
[self performSegueWithIdentifier:setting.segue sender:nil];
}
}
#pragma mark - Private
- (void)updateUserPositionRadius:(EQNGenericValue *)radius
{
[EQNNotificheReteSismiche sharedInstance].distanzaPosizione = radius.value;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateSeismicEnergy:(EQNGenericValue *)energy
{
[EQNNotificheReteSismiche sharedInstance].energiaSisma = energy.value;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self updateUI];
}
- (void)updateStrongEarthquakeEnergy:(EQNGenericValue *)energy
{
[EQNNotificheReteSismiche sharedInstance].energiaTerremotiForti = energy.value;
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
[self updateUI];
}
- (NSString *)stringOfSelectedNetworks
{
NSArray *networks = [EQNNotificheReteSismiche sharedInstance].listaEnti;
networks = [networks sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
return [networks componentsJoinedByString:@", "];
}
@end
@@ -0,0 +1,71 @@
//
// SettingsSeismicNetworksViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 26/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
class SettingsSeismicNetworksViewController: UITableViewController {
var networks = [EQNSeismicNetwork]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(SettingDetailTableViewCell.self, forCellReuseIdentifier: SettingDetailTableViewCell.Identifier)
tableView.register(SettingSectionHeaderView.self, forHeaderFooterViewReuseIdentifier: SettingSectionHeaderView.Identifier)
networks = EQNData.seismicNetworks().sorted(by: { $0.acronym < $1.acronym })
}
// 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 EQNNotificheReteSismiche.shared().listaEnti.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]
var savedNetworks = EQNNotificheReteSismiche.shared().listaEnti
if let index = savedNetworks.firstIndex(where: { $0 == network.acronym }) {
savedNetworks.remove(at: index)
} else {
savedNetworks.append(network.acronym)
}
EQNNotificheReteSismiche.shared().listaEnti = savedNetworks
EQNNotificheReteSismiche.shared().saveUserInfo()
tableView.reloadData()
}
}
@@ -0,0 +1,18 @@
//
// SettingsUserReportAlertsViewController.h
// Earthquake Network
//
// Refactored by Andrea Busi 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "SettingsBaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface SettingsUserReportAlertsViewController : SettingsBaseViewController
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,120 @@
//
// SettingsUserReportAlertsViewController.m
// Earthquake Network
//
// Refactored by Andrea Busi 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "SettingsUserReportAlertsViewController.h"
#import "EQNNotificheSegnalazioniUtente.h"
#import "EQNUtility.h"
@interface SettingsUserReportAlertsViewController ()
@property (nonatomic, strong) NSArray<SettingItem *> *settings;
@property (nonatomic, assign) BOOL notificationsEnabled;
@property (nonatomic, strong) EQNGenericValue *currentRadius;
@end
@implementation SettingsUserReportAlertsViewController
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];
self.settings = @[
[[SettingItem alloc] initWithType:SettingTypeEnable title:NSLocalizedString(@"Ricevi le notifiche dei sismi segnalati manualmente dagli utenti", @"")],
[[SettingItem alloc] initWithType:SettingTypeSlider title:NSLocalizedString(@"Raggio dalla tua posizione", @"")]
];
[self updateUI];
}
#pragma mark - Private
- (void)setupUI
{
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
self.tableView.estimatedRowHeight = 100.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView registerClass:[SettingSectionHeaderView class] forHeaderFooterViewReuseIdentifier:SettingSectionHeaderView.Identifier];
[self.tableView registerClass:[SettingEnableTableViewCell class] forCellReuseIdentifier:SettingEnableTableViewCell.Identifier];
[self.tableView registerClass:[SettingSliderTableViewCell class] forCellReuseIdentifier:SettingSliderTableViewCell.Identifier];
}
- (void)updateUI
{
self.notificationsEnabled = [EQNNotificheSegnalazioniUtente sharedInstance].isAbilitato;
EQNGenericValue *distanzaPosizione = [EQNData raggioSismaFor:[EQNNotificheSegnalazioniUtente sharedInstance].distanzaPosizione];
self.currentRadius = distanzaPosizione;
[[EQNNotificheSegnalazioniUtente sharedInstance] saveUserInfo];
[self.tableView reloadData];
}
- (void)updateRadius:(EQNGenericValue *)radius
{
self.currentRadius = radius;
[EQNNotificheSegnalazioniUtente sharedInstance].distanzaPosizione = radius.value;
[[EQNNotificheSegnalazioniUtente sharedInstance] saveUserInfo];
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
SettingSectionHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:SettingSectionHeaderView.Identifier];
headerView.titleLabel.text = NSLocalizedString(@"Notifiche segnalazioni utente", @"titolo impostazioni notifiche");
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return SettingSectionHeaderView.Height;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.settings.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
SettingItem *setting = self.settings[indexPath.row];
if (setting.type == SettingTypeEnable) {
SettingEnableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingEnableTableViewCell.Identifier forIndexPath:indexPath];
cell.toggleSwitch.on = self.notificationsEnabled;
cell.titleLabel.text = setting.displayTitle;
cell.descriptionLabel.text = setting.subtitle;
cell.valueChanged = ^(BOOL enabled) {
self.notificationsEnabled = enabled;
[EQNNotificheSegnalazioniUtente sharedInstance].isAbilitato = self.notificationsEnabled;
[[EQNNotificheSegnalazioniUtente sharedInstance] saveUserInfo];
[self.tableView reloadData];
};
return cell;
} else if (setting.type == SettingTypeSlider) {
SettingSliderTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SettingSliderTableViewCell.Identifier forIndexPath:indexPath];
cell.isDisabled = !self.notificationsEnabled;
cell.titleLabel.text = setting.displayTitle;
[cell configureSliderWith:[EQNData raggioSismi] current:self.currentRadius];
cell.valueChanged = ^(EQNGenericValue *item) {
[self updateRadius:item];
};
return cell;
}
return nil;
}
@end
@@ -0,0 +1,128 @@
//
// SettingsViewController.swift
// Earthquake Network
//
// Created by Busi Andrea on 30/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import UIKit
import SafariServices
class SettingsViewController: UITableViewController {
private static let SegueIdentifierAllertaSismica = "ShowAllertaSismica"
private static let SegueIdentifierNotificheSegnalazioniUtente = "ShowNotificheSegnalazioniUtente"
private static let SegueIdentifierNotificheRetiSismiche = "ShowNotificheRetiSismiche"
private static let SegueIdentifierSafari = "ShowSafari"
private enum InfoItem: Int {
case informations
case faq
case help
case author
case sponsors
case disclaimer
case privacy
var externalUrl: URL? {
let baseUrl = EQNWebsiteAddress
switch self {
case .informations: return URL(string: "\(baseUrl)")
case .faq: return URL(string: "\(baseUrl)/f-a-q/")
case .help: return URL(string: "\(baseUrl)/help/")
case .author: return URL(string: "\(baseUrl)/contact/")
case .sponsors: return URL(string: "\(baseUrl)/sponsors/")
case .disclaimer: return URL(string: "\(baseUrl)/terms-conditions/")
case .privacy: return URL(string: "\(baseUrl)/privacy/")
}
}
}
private var settings: [[SettingItem]] = [
[
SettingItem(type: .detail, title: NSLocalizedString("Allerta in tempo reale", comment: ""), segue: SegueIdentifierAllertaSismica, emoji: "🚨"),
SettingItem(type: .detail, title: NSLocalizedString("Notifiche da reti sismiche", comment: ""), segue: SegueIdentifierNotificheRetiSismiche, emoji: "🔔"),
SettingItem(type: .detail, title: NSLocalizedString("Notifiche segnalazioni utente", comment: ""), segue: SegueIdentifierNotificheSegnalazioniUtente, emoji: "🔔")
],
[
SettingItem(type: .detail, title: NSLocalizedString("Informazioni", comment: ""), segue: SegueIdentifierSafari, icon: "menu-icon-info"),
SettingItem(type: .detail, title: NSLocalizedString("F.A.Q.", comment: ""), segue: SegueIdentifierSafari, icon: "menu-icon-faq"),
SettingItem(type: .detail, title: NSLocalizedString("Help", comment: ""), segue: SegueIdentifierSafari, icon: "menu-icon-help"),
SettingItem(type: .detail, title: NSLocalizedString("Autore", comment: ""), segue: SegueIdentifierSafari, icon: "menu-icon-author"),
SettingItem(type: .detail, title: NSLocalizedString("Patrocinatori", comment: ""), segue: SegueIdentifierSafari, icon: "menu-icon-sponsors"),
SettingItem(type: .detail, title: NSLocalizedString("Disclaimer", comment: ""), segue: SegueIdentifierSafari, icon: "menu-icon-terms"),
SettingItem(type: .detail, title: NSLocalizedString("Privacy", comment: ""), segue: SegueIdentifierSafari, icon: "menu-icon-privacy")
]
]
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
title = NSLocalizedString("Impostazioni", comment: "")
setupUI()
}
// MARK: - Private
private func setupUI() {
tableView.register(SettingDetailTableViewCell.self, forCellReuseIdentifier: SettingDetailTableViewCell.Identifier)
tableView.contentInset = UIEdgeInsets(top: 20.0, left: 0.0, bottom: 0.0, right: 0.0)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
settings.count
}
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
if section == 0 {
return nil
}
var title = ""
if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
let version = NSLocalizedString("Versione", comment: "etichetta versione app")
title = "\(version): \(appVersion)"
}
let userId = EQNUser.default().user_ID ?? "n.d."
title = "\(title) - User id: \(userId)"
return title
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let aSection = settings[section]
return aSection.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let setting = settings[indexPath.section][indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: SettingDetailTableViewCell.Identifier, for: indexPath) as! SettingDetailTableViewCell
cell.textLabel?.text = setting.displayTitle
if let icon = setting.icon {
cell.imageView?.tintColor = cell.textLabel?.textColor
cell.imageView?.image = UIImage(named: icon)
}
cell.accessoryType = .disclosureIndicator
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let setting = settings[indexPath.section][indexPath.row]
if let segue = setting.segue {
if segue == Self.SegueIdentifierSafari, let item = InfoItem(rawValue: indexPath.row), let url = item.externalUrl {
// show Safari with the given URL
let controller = SFSafariViewController(url: url)
present(controller, animated: true, completion: nil)
} else {
performSegue(withIdentifier: segue, sender: nil)
}
}
}
}
@@ -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 -105
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,45 +109,7 @@ typedef enum : NSInteger {
} EQNTipoDettagliMappa;
typedef enum : NSInteger {
reteSmartphoneController = 0,
reteSismicaController,
segnalazioneUtentiController,
tsunamiControler
} EQNController;
// 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"
@@ -182,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"
@@ -249,7 +196,6 @@ typedef enum : NSInteger {
/////////////////////////////////// impostazioni ////////////////////////////////////
#define NOTIFICHE_SISMI @"NOTIFICHE_SISMI"
#define NOTIFICHE_ORA_INIZIO @"NOTIFICHE_ORA_INIZIO"
#define NOTIFICHE_ORA_FINE @"NOTIFICHE_ORA_FINE"
#define NOTIFICHE_ATTIVA_ORARIO @"NOTIFICHE_ATTIVA_ORARIO"
@@ -272,28 +218,17 @@ typedef enum : NSInteger {
#define NOTIFICHE_ATTIVA_RETI_SISMICHE_VICINE @"NOTIFICHE_ATTIVA_RETI_SISMICHE_VICINE"
#define NOTIFICHE_ATTIVA_RETI_TERREMOTI_FORTI @"NOTIFICHE_ATTIVA_RETI_TERREMOTI_FORTI"
#define NOTIFICHE_ATTIVA_RETI_ENERGIA_SISMI @"NOTIFICHE_ATTIVA_RETI_ENERGIA_SISMI"
#define NOTIFICHE_ATTIVA_RETI_DISTANZA_VICINI @"NOTIFICHE_ATTIVA_RETI_DISTANZA_VICINI"
#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"
#define NOTIFICHE_ALLERA_SISMICA_SISMI_DA_NOTIFICARE @"NOTIFICHE_ALLERA_SISMICA_SISMI_DA_NOTIFICARE"
#define NOTIFICHE_ALLERA_SISMICA_SENZA_INTENSITA @"NOTIFICHE_ALLERA_SISMICA_SENZA_INTENSITA"
#define NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_LIEVI @"NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_LIEVI"
#define NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_FORTI @"NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_FORTI"
#define NOTIFICHE_ALLERA_SISMICA_TONO_ALLARME @"NOTIFICHE_ALLERA_SISMICA_TONO_ALLARME"
@@ -324,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"
@@ -5,5 +5,9 @@
#import "EQNUtility.h"
#import "Costanti.h"
#import "EQNUser.h"
#import "SWRevealViewController.h"
#import "EQNManager.h"
#import "EQNNotificheReteSismiche.h"
#import "EQNSisma.h"
#import "EQNBaseViewController.h"
#import "ReteSismiDettagliMappa.h"
#import "SettingsBaseViewController.h"
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>Earthquake_Network.xcdatamodel</string>
</dict>
</plist>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<elements/>
</model>
+7 -1
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>GADApplicationIdentifier</key>
@@ -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,25 @@
//
// NSDictionary+EQNExtensions.h
// Earthquake Network
//
// Created by Andrea Busi on 03/10/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSDictionary (EQNExtensions)
/// Returns a string representation of the current dictionary
/// @param prettyPrint If YES, uses white space and indentation to make the output more readable.
- (NSString *)eqn_jsonStringWithPrettyPrint:(BOOL)prettyPrint;
/// Returns the value associated with a given key if exists, nil otherwise.
/// @param aKey The key for which to return the corresponding value
- (nullable id)eqn_safeObjectForKey:(id)aKey;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,36 @@
//
// NSDictionary+EQNExtensions.h
// Earthquake Network
//
// Created by Andrea Busi on 03/10/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "NSDictionary+EQNExtensions.h"
@implementation NSDictionary (BVJSONString)
#pragma mark - Public
- (NSString *)eqn_jsonStringWithPrettyPrint:(BOOL)prettyPrint
{
NSError *error;
NSJSONWritingOptions options = prettyPrint ? NSJSONWritingPrettyPrinted : 0;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:options error:&error];
if (!jsonData) {
return @"{}";
}
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
- (id)eqn_safeObjectForKey:(id)aKey
{
NSObject *object = [self objectForKey:aKey];
if (object == [NSNull null]) {
return nil;
}
return object;
}
@end
@@ -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)
}
}
@@ -1,18 +0,0 @@
//
// NSDictionary+BVJSONString.h
// Smash
//
// Created by Luca Beretta on 24/03/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSDictionary (BVJSONString)
-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint;
@end
NS_ASSUME_NONNULL_END
@@ -1,25 +0,0 @@
//
// NSDictionary+BVJSONString.m
// Smash
//
// Created by Luca Beretta on 24/03/2019.
// Copyright © 2019 Luca Beretta. All rights reserved.
//
#import "NSDictionary+BVJSONString.h"
@implementation NSDictionary (BVJSONString)
-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint {
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
error:&error];
if (! jsonData) {
NSLog(@"%s: error: %@", __func__, error.localizedDescription);
return @"{}";
} else {
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
@end
@@ -0,0 +1,55 @@
//
// EQNAppearanceCommand.swift
// Earthquake Network
//
// Created by Busi Andrea on 14/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
public class EQNAppearanceCommand: EQNCommandProtocol {
// MARK: - Public
func execute() {
print("EQNAppearanceCommand: start execute")
applyAppearance()
}
// MARK: - Private
private func applyAppearance() {
// UINavigationBar
let proxyNavBar = UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self])
if #available(iOS 13.0, *) {
let navAppearance = UINavigationBarAppearance()
navAppearance.configureWithOpaqueBackground()
navAppearance.titleTextAttributes = [
NSAttributedString.Key.foregroundColor: AppTheme.Colors.darkGray
]
navAppearance.largeTitleTextAttributes = [
NSAttributedString.Key.foregroundColor: AppTheme.Colors.darkGray
]
navAppearance.backgroundColor = AppTheme.Colors.primary
navAppearance.shadowColor = UIColor.clear
proxyNavBar.isTranslucent = false
proxyNavBar.tintColor = AppTheme.Colors.darkGray
proxyNavBar.standardAppearance = navAppearance
proxyNavBar.scrollEdgeAppearance = navAppearance
} else {
proxyNavBar.tintColor = AppTheme.Colors.darkGray
proxyNavBar.isTranslucent = false
proxyNavBar.barTintColor = AppTheme.Colors.primary
proxyNavBar.titleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.white
]
}
let proxyTabBar = UITabBar.appearance()
proxyTabBar.tintColor = AppTheme.Colors.red
}
}
@@ -0,0 +1,15 @@
//
// EQNCommandProtocol.swift
// Earthquake Network
//
// Created by Busi Andrea on 14/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objc
protocol EQNCommandProtocol: class {
@objc func execute()
}
@@ -0,0 +1,32 @@
//
// EQNStartupCommandsBuilder.swift
// Earthquake Network
//
// Created by Busi Andrea on 14/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objc
public class EQNStartupCommandsBuilder: NSObject {
// MARK: - Public
@objc
func build() -> [EQNCommandProtocol] {
return [
EQNAppearanceCommand(),
EQNUserDefaultsCommand()
]
}
@objc
func execute(commands: [EQNCommandProtocol]) {
print("EQNStartupCommandsBuilder: start execute commands")
commands.forEach { (command) in
command.execute()
}
}
}
@@ -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)
}
}
}
@@ -0,0 +1,199 @@
//
// EQNData.swift
// Earthquake Network
//
// Created by Busi Andrea on 26/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objc class EQNData: NSObject {
@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
@objc class func raggioSismi() -> [EQNGenericValue] {
[
EQNGenericValue(value:"50", display:"50 km"),
EQNGenericValue(value:"100", display:"100 km"),
EQNGenericValue(value:"200", display:"200 km"),
EQNGenericValue(value:"300", display:"300 km"),
EQNGenericValue(value:"400", display:"400 km"),
EQNGenericValue(value:"500", display:"500 km"),
EQNGenericValue(value:"600", display:"600 km"),
EQNGenericValue(value:"800", display:"800 km"),
EQNGenericValue(value:"1000", display:"1000 km"),
EQNGenericValue(value:"2000", display:"2000 km"),
EQNGenericValue(value:"4000", display:"4000 km"),
EQNGenericValue(value:"100000", display:"Qualsiasi distanza"),
]
}
/// Returns the EQNGenericValue for the given value, or the default one
/// - Parameter value: Sisma value to search
/// - Returns: Found value or default
@objc class func raggioSisma(for value: String?) -> EQNGenericValue {
if let value = value, let genericValue = Self.raggioSismi().first(where: { $0.value == value }) {
return genericValue
}
return Self.DefaultRaggioSisma
}
@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"),
EQNGenericValue(value:"2.0", display:"Magnitudo >= 2.0"),
EQNGenericValue(value:"2.5", display:"Magnitudo >= 2.5"),
EQNGenericValue(value:"3.0", display:"Magnitudo >= 3.0"),
EQNGenericValue(value:"3.5", display:"Magnitudo >= 3.5"),
EQNGenericValue(value:"4.0", display:"Magnitudo >= 4.0"),
EQNGenericValue(value:"4.5", display:"Magnitudo >= 4.5"),
EQNGenericValue(value:"5.0", display:"Magnitudo >= 5.0"),
EQNGenericValue(value:"5.5", display:"Magnitudo >= 5.5")
]
}
/// Returns the EQNGenericValue for the given value, or the default one
/// - Parameter value: Magnitudo value to search
/// - Returns: Found value or default
@objc class func magitudoDebole(for value: String?) -> EQNGenericValue {
if let value = value, let genericValue = Self.magitudoDeboli().first(where: { $0.value == value }) {
return genericValue
}
return Self.DefaultMagitudoDebole
}
@objc class func magitudoForti() -> [EQNGenericValue] {
[
EQNGenericValue(value:"5.5", display:"Magnitudo >= 5.5"),
EQNGenericValue(value:"6.0", display:"Magnitudo >= 6.0"),
EQNGenericValue(value:"6.5", display:"Magnitudo >= 6.5"),
EQNGenericValue(value:"7.0", display:"Magnitudo >= 7.0"),
EQNGenericValue(value:"7.5", display:"Magnitudo >= 7.5")
]
}
/// Returns the EQNGenericValue for the given value, or the default one
/// - Parameter value: Magnitudo value to search
/// - Returns: Found value or default
@objc class func magitudoForte(for value: String?) -> EQNGenericValue {
if let value = value, let genericValue = Self.magitudoForti().first(where: { $0.value == value }) {
return genericValue
}
return Self.DefaultMagitudoForte
}
@objc class func seismicNetworks() -> [EQNSeismicNetwork] {
[
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: ""),
EQNSeismicNetwork(acronym: "JMA", country: NSLocalizedString("Giappone", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "Ineter", country: NSLocalizedString("Nicaragua", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "SSN", country: NSLocalizedString("Messico", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "SGC", country: NSLocalizedString("Colombia", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "RSN", country: NSLocalizedString("Costa Rica", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "CSN", country: NSLocalizedString("Cile", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "FUNVISIS", country: NSLocalizedString("Venezuela", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "GeoNet", country: NSLocalizedString("Nuova Zelanda", comment: ""), extended: ""),
EQNSeismicNetwork(acronym: "INPRES", country: NSLocalizedString("Argentina", comment: ""), extended: ""),
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: "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: "")
]
}
@objc class func seismicNetworkAcronyms() -> [String] {
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à"),
EQNGenericValue(value:"1", display:"Solo sismi forti")
]
}
@objc class func seismicToNotify(for value: String?) -> EQNGenericValue {
if let value = value, let genericValue = Self.seismicToNotify().first(where: { $0.value == value }) {
return genericValue
}
return Self.DefaultSeismicToNotify
}
@objc class func doNotDisturbStartDate(from date: Date?) -> Date {
if let date = date {
return date
}
// return default
let calendar = Calendar(identifier: .gregorian)
let units: Set<Calendar.Component> = [.year, .month, .day, .hour, .minute]
var components = calendar.dateComponents(units, from: Date())
components.hour = Self.DefaultDoNotDisturbStartTime
components.minute = 00
return calendar.date(from: components)!
}
@objc class func doNotDisturbEndDate(from date: Date?) -> Date {
if let date = date {
return date
}
// return default
let calendar = Calendar(identifier: .gregorian)
let units: Set<Calendar.Component> = [.year, .month, .day, .hour, .minute]
var components = calendar.dateComponents(units, from: Date())
components.hour = Self.DefaultDoNotDisturbEndTime
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
}
}
@@ -0,0 +1,34 @@
//
// EQNGenericValue.swift
// Earthquake Network
//
// Created by Busi Andrea on 26/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objcMembers
class EQNGenericValue: NSObject {
/// Value of the element
public let value: String
/// Display text
public let display: String
// MARK: - Init
init(value: String, display: String) {
self.value = value
self.display = NSLocalizedString(display, comment: "")
}
// MARK: - Equal
override func isEqual(_ object: Any?) -> Bool {
if let aValue = object as? EQNGenericValue {
return aValue.value == self.value
}
return false
}
}
@@ -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,172 @@
//
// 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
var networks: [String]
if let savedNetworks = UserDefaults.standard.object(forKey: IMPOSTAZIONE_ENTI_RETI_SISMICHEI) as? [String] {
networks = savedNetworks
} else {
networks = EQNData.seismicNetworkAcronyms()
}
networks = networks.map { $0.lowercased() }
// 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.lowercased()) {
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, nullable) 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, nullable) 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,119 @@
//
// EQNSisma.m
// Earthquake Network
//
// Refactored by Andrea Busi
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "EQNSisma.h"
#import "EQNUser.h"
#import "EQNUtility.h"
#import "NSDictionary+EQNExtensions.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 getDateFromString: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 eqn_safeObjectForKey:@"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
@@ -0,0 +1,45 @@
//
// EQNSeismicNetwork.swift
// Earthquake Network
//
// Created by Busi Andrea on 26/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objcMembers
class EQNSeismicNetwork: NSObject {
let acronym: String
let country: String
let extended: String
// MARK: - Init
init(acronym: String, country: String, extended: String) {
self.acronym = acronym
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,10 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong) NSArray *listaMessaggi;
@property (nonatomic, strong) NSArray *listaAreeInteresse;
+(EQNAllertaSismica *)center;
-(void)saveUserInfo;
-(void)removeUser;
+ (instancetype)sharedInstance NS_SWIFT_NAME(shared());
- (void)saveUserInfo;
+ (void)saveDefaultValues;
@end
@@ -0,0 +1,74 @@
//
// EQNAllertaSismica.m
// Earthquake Network
//
// 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)sharedInstance
{
static EQNAllertaSismica *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_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";
}
self.isintervalloAllarme = [[NSUserDefaults standardUserDefaults] boolForKey:NOTIFICHE_ALLERA_SISMICA_ABILITA_INTERVALLO];
self.oraioInizio = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_ALLERA_SISMICA_ORA_INIZIO];
self.orarioFine = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_ALLERA_SISMICA_ORA_FINE];
}
return self;
}
#pragma mark - Public
- (void)saveUserInfo
{
[[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];
[[NSUserDefaults standardUserDefaults] setObject:self.orarioFine forKey:NOTIFICHE_ALLERA_SISMICA_ORA_FINE];
[[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,29 +1,29 @@
//
// 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;
@property (nonatomic, assign) BOOL isTerremortiForti;
@property (nonatomic, strong) NSArray *listaEnti;
@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
@@ -0,0 +1,67 @@
//
// SettingItem.swift
// Earthquake Network
//
// Created by Busi Andrea on 25/08/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objc enum SettingType: Int {
case detail
case enable
case slider
case segmented
case date
case multiValues
}
@objcMembers
class SettingItem: NSObject {
let title: String
let subtitle: String?
let segue: String?
let icon: String?
let emoji: String?
let type: SettingType
var displayTitle: String {
if let emoji = emoji {
return "\(emoji) \(title)"
}
return title
}
// MARK: - Init
convenience init(type: SettingType, title: String) {
self.init(type: type, title: title, subtitle: nil, segue: nil, icon: nil, emoji: nil)
}
convenience init(type: SettingType, title: String, subtitle: String) {
self.init(type: type, title: title, subtitle: subtitle, segue: nil, icon: nil, emoji: nil)
}
convenience init(type: SettingType, title: String, segue: String) {
self.init(type: type, title: title, subtitle: nil, segue: segue, icon: nil, emoji: nil)
}
convenience init(type: SettingType, title: String, segue: String, icon: String) {
self.init(type: type, title: title, subtitle: nil, segue: segue, icon: icon, emoji: nil)
}
convenience init(type: SettingType, title: String, segue: String, emoji: String) {
self.init(type: type, title: title, subtitle: nil, segue: segue, icon: nil, emoji: emoji)
}
init(type: SettingType, title: String, subtitle: String? = nil, segue: String? = nil, icon: String? = nil, emoji: String? = nil) {
self.type = type
self.title = title
self.subtitle = subtitle
self.segue = segue
self.icon = icon
self.emoji = emoji
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -1,23 +1,23 @@
{
"images" : [
{
"filename" : "eq_icon.png",
"idiom" : "universal",
"filename" : "distquake_app_pro.png",
"scale" : "1x"
},
{
"filename" : "eq_icon@2x.png",
"idiom" : "universal",
"filename" : "distquake_app_pro-1.png",
"scale" : "2x"
},
{
"filename" : "eq_icon@3x.png",
"idiom" : "universal",
"filename" : "distquake_app_pro-2.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

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

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

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