Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 282803cf98 | |||
| 039e7b82a1 | |||
| b098caf2ef | |||
| 73caf9647c | |||
| 8700e200f9 | |||
| e99845ff1b | |||
| a0161e8f4c | |||
| 1b9944a7ca | |||
| 4c00e4ef6a | |||
| 63592e6cfb | |||
| 2877dff23c | |||
| f2386a1abb | |||
| 5e4a500f03 | |||
| 2b8f2db7c5 | |||
| 11d994696d | |||
| cd6e20c1b2 | |||
| af5371571c | |||
| 6291b22df0 | |||
| 2a7cfd3079 | |||
| cae5fee992 | |||
| 53b8c0fab4 | |||
| 8751d3c8f2 | |||
| 2d333f993b | |||
| 22d421f1cc | |||
| cec8b39fc7 | |||
| 5ceaa4a8be | |||
| 94bdb9dbe1 | |||
| ee1b762032 | |||
| 5a6c5a5cfc | |||
| d55b2ec98f | |||
| 761ebc1d17 | |||
| dd5e8862ed | |||
| ceca3ed50d |
@@ -1,5 +1,40 @@
|
||||
# Changelog
|
||||
|
||||
## Versione 5.2.1
|
||||
|
||||
- Disattivata schermata di debug
|
||||
|
||||
## Versione 5.2
|
||||
|
||||
- Nuova schermata per allerta in tempo reale
|
||||
|
||||
## Versione 5.1
|
||||
|
||||
### Build (91)
|
||||
- Corretto problema con selezioni reti EMSC
|
||||
|
||||
### Build (90)
|
||||
- Rimozione notifiche dello stesso tipo
|
||||
|
||||
## Versione 5.0.3
|
||||
|
||||
### Build (89)
|
||||
- Corretto problema con ultima posizione non salvata in app
|
||||
- Forzato aggiornamento Firebase
|
||||
- Corretti metodi deprecati in salvataggio dati
|
||||
- Corretti comportamento filtri con iOS 15
|
||||
- Slider con valori a step
|
||||
|
||||
## Versione 5.0.2
|
||||
|
||||
### Build (88)
|
||||
- Corretto errato salvataggio raggio sismi forti in allerte tempo reale
|
||||
|
||||
## Versione 5.0.1
|
||||
|
||||
### Build (87)
|
||||
- Corretto problema con slider in impostazioni
|
||||
|
||||
## Versione 5.0
|
||||
|
||||
### Build (86)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"15 χλμ από το Αίγιο"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,20 +14,21 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-15 21:34:50",
|
||||
"datetime": "2022-06-23 10:10:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "37.983810",
|
||||
"detection_longitude": "23.727539",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "37.683810",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "23.327539",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "38.19",
|
||||
"location": "15 χλμ από το Αίγιο",
|
||||
"longitude": "22.26",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"14 km from California City"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,19 +14,20 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-16 12:41:20",
|
||||
"datetime": "2022-06-23 07:55:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "37.3229978",
|
||||
"detection_longitude": "-122.0321823",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "37.9229978",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "-121.0321823",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "35.15",
|
||||
"location": "14 km from California City",
|
||||
"longitude": "-117.78",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"5 km de Las Cujas"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,19 +14,20 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-15 20:39:00",
|
||||
"datetime": "2022-06-23 10:19:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "-34.603722",
|
||||
"detection_longitude": "-58.381592",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "-34.103722",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "-58.781592",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "-32.57",
|
||||
"location": "5 km de Las Cujas",
|
||||
"longitude": "-71.46",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"15 km de Dieppe"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,19 +14,20 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-15 21:37:40",
|
||||
"datetime": "2022-06-23 10:07:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "48.856614",
|
||||
"detection_longitude": "2.8522219",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "48.456614",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "2.3522219",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "49.77",
|
||||
"location": "15 km de Dieppe",
|
||||
"longitude": "1.05",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"5 km od Novog"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,19 +14,20 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-15 21:39:50",
|
||||
"datetime": "2022-06-23 10:02:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "45.813177",
|
||||
"detection_longitude": "15.977048",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "45.413177",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "15.677048",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "45.09",
|
||||
"location": "5 km od Novog",
|
||||
"longitude": "14.87",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"35 km dari Sindanbarang"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,19 +14,20 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-15 21:42:40",
|
||||
"datetime": "2022-06-23 10:13:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "-2.548926",
|
||||
"detection_longitude": "118.0148634",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "-2.948926",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "118.6148634",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "-7.38",
|
||||
"location": "35 km dari Sindanbarang",
|
||||
"longitude": "106.83",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"2 km da Foligno"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,19 +14,20 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-15 20:32:20",
|
||||
"datetime": "2022-06-22 19:12:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "45.64664",
|
||||
"detection_longitude": "9.188540",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "45.164664",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "9.788540",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "42.958",
|
||||
"location": "2 km da Foligno",
|
||||
"longitude": "12.702",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"45 km de Puebla"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,19 +14,20 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-16 12:39:40",
|
||||
"datetime": "2022-06-23 10:16:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "19.432608",
|
||||
"detection_longitude": "-99.133209",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "19.932608",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "-98.033209",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "18.72",
|
||||
"location": "45 km de Puebla",
|
||||
"longitude": "-97.90",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"aps": {
|
||||
"alert": {
|
||||
"loc-args": [
|
||||
"150 km (Test)"
|
||||
"Bandırma'ya 25 km"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
@@ -14,20 +14,21 @@
|
||||
"sound": "alert_star_trek.wav"
|
||||
},
|
||||
"counter": 10,
|
||||
"datetime": "2021-04-15 21:44:30",
|
||||
"datetime": "2022-06-23 10:22:00",
|
||||
"delay": 4,
|
||||
"detection_latitude": "41.008238",
|
||||
"detection_longitude": "28.978359",
|
||||
"gcm.message_id": "1614708857742608",
|
||||
"google.c.a.e": 1,
|
||||
"google.c.sender.id": "899482329945",
|
||||
"intensity": 2,
|
||||
"latitude": "41.608238",
|
||||
"location": "150 km (Test)",
|
||||
"longitude": "28.678359",
|
||||
"peak": "-1",
|
||||
"randcode": 0,
|
||||
"test": 1,
|
||||
"latitude": "40.33",
|
||||
"location": "Bandırma'ya 25 km",
|
||||
"longitude": "27.66",
|
||||
"peak": "0.4",
|
||||
"randcode": 100,
|
||||
"test": 0,
|
||||
"type": "eqn",
|
||||
"wave_speed": "4.7",
|
||||
"critical": true
|
||||
}
|
||||
}
|
||||
@@ -2,3 +2,4 @@
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
#import "NotificationService.h"
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// NotificationService+Extension.swift
|
||||
// EQNNotificationService
|
||||
//
|
||||
// Created by Andrea Busi on 28/05/22.
|
||||
// Copyright © 2022 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UserNotifications
|
||||
|
||||
|
||||
extension NotificationService {
|
||||
|
||||
@objc(removeNotificationsForType:completion:)
|
||||
func removeNotifications(
|
||||
for type: String?,
|
||||
completion: @escaping() -> Void
|
||||
) {
|
||||
guard let type = type else {
|
||||
completion()
|
||||
return
|
||||
}
|
||||
|
||||
let notificationCenter = UNUserNotificationCenter.current()
|
||||
|
||||
notificationCenter.getDeliveredNotifications { notifications in
|
||||
let sameTypeNotifications = notifications.filter { notification in
|
||||
let payload = notification.request.content.userInfo
|
||||
if let notificationType = payload["type"] as? String {
|
||||
return notificationType == type
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
let identifiers = sameTypeNotifications.map { $0.request.identifier }
|
||||
notificationCenter.removeDeliveredNotifications(withIdentifiers: identifiers)
|
||||
|
||||
// !! Note: this is a known issue/bug
|
||||
// we need to add a delay before invoking the completion, otherwise the notification will not be remved
|
||||
// ref: https://stackoverflow.com/questions/53697279/why-are-notifications-not-removed-with-removedeliverednotifications
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@
|
||||
#import "NotificationService.h"
|
||||
#import "EQNAllertaSismica.h"
|
||||
#import "Costanti.h"
|
||||
#import "EQNNotificationService-Swift.h"
|
||||
|
||||
|
||||
@interface NotificationService ()
|
||||
|
||||
@@ -158,7 +160,10 @@ static NSString * const EQNSoundNotificationEQN = @"alert_sound.wav";
|
||||
}
|
||||
}
|
||||
|
||||
[self contentComplete];
|
||||
// remove same type posted notification
|
||||
[self removeNotificationsForType:notificationType completion:^{
|
||||
[self contentComplete];
|
||||
}];;
|
||||
}
|
||||
|
||||
- (void)serviceExtensionTimeWillExpire
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
651901B925F5358700CAFF20 /* EQNMapAnnotationSeismic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 651901B825F5358700CAFF20 /* EQNMapAnnotationSeismic.swift */; };
|
||||
6525A82625E13FD4008FE0D0 /* SeismicNetworkAdvertiseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6525A82525E13FD4008FE0D0 /* SeismicNetworkAdvertiseTableViewCell.swift */; };
|
||||
652C37BD26092B3C0068EC3B /* FiltersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 652C37BC26092B3C0068EC3B /* FiltersViewModel.swift */; };
|
||||
6531185928425B89006CBC29 /* NotificationService+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6531185828425B89006CBC29 /* NotificationService+Extension.swift */; };
|
||||
65355FFF25F38D3300BB57D2 /* SegnalazioniMapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65355FFE25F38D3300BB57D2 /* SegnalazioniMapViewController.swift */; };
|
||||
6535600425F398CD00BB57D2 /* Costanti+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6535600325F398CD00BB57D2 /* Costanti+Extensions.swift */; };
|
||||
653604E9262348FA00B2B651 /* EQNBaseMapFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653604E8262348FA00B2B651 /* EQNBaseMapFilter.swift */; };
|
||||
@@ -130,6 +131,8 @@
|
||||
6562C80725FFA6B100C85273 /* SeismicNetworkViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6562C80625FFA6B100C85273 /* SeismicNetworkViewModel.swift */; };
|
||||
6586971125F44C26009C0182 /* EQNBlurredCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6586971025F44C26009C0182 /* EQNBlurredCloseButton.swift */; };
|
||||
658BAB7B25FE67930015C454 /* EQNBaseMapRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658BAB7A25FE67930015C454 /* EQNBaseMapRepresentable.swift */; };
|
||||
658BC0292859A456009EECAA /* RealtimeAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658BC0282859A456009EECAA /* RealtimeAlertViewController.swift */; };
|
||||
658BC02B2859A4D3009EECAA /* RealtimeAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658BC02A2859A4D3009EECAA /* RealtimeAlertView.swift */; };
|
||||
65AD23CE261B03D400E3B57C /* SubscriptionsDescriptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65AD23CD261B03D400E3B57C /* SubscriptionsDescriptionTableViewCell.swift */; };
|
||||
65BBB22C26064BE6005D6CDF /* SegnalazioniLast24HoursCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65BBB22B26064BE6005D6CDF /* SegnalazioniLast24HoursCell.swift */; };
|
||||
65D409942619BA34008CF356 /* SegnalazioniSendReportCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D409932619BA34008CF356 /* SegnalazioniSendReportCell.swift */; };
|
||||
@@ -137,6 +140,7 @@
|
||||
65DBFB7425E2BBF20041CBA6 /* GADTMediumTemplateView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65DBFB6F25E2BBF20041CBA6 /* GADTMediumTemplateView.xib */; };
|
||||
65DBFB7525E2BBF20041CBA6 /* GADTMediumTemplateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 65DBFB7125E2BBF20041CBA6 /* GADTMediumTemplateView.m */; };
|
||||
65DBFB7625E2BBF20041CBA6 /* GADTTemplateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 65DBFB7225E2BBF20041CBA6 /* GADTTemplateView.m */; };
|
||||
65E1226C285C92AA000E294A /* EQNRealtimeAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E1226B285C92AA000E294A /* EQNRealtimeAlert.swift */; };
|
||||
65E1B19B260F980600A0ACBA /* Dictionary+EQNExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E1B19A260F980600A0ACBA /* Dictionary+EQNExtensions.swift */; };
|
||||
8C10B0B92281FE7F00125C9F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C10B0BD2281FE7F00125C9F /* Localizable.strings */; };
|
||||
8C10B0BA2281FE7F00125C9F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C10B0BD2281FE7F00125C9F /* Localizable.strings */; };
|
||||
@@ -288,6 +292,7 @@
|
||||
651901B825F5358700CAFF20 /* EQNMapAnnotationSeismic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNMapAnnotationSeismic.swift; sourceTree = "<group>"; };
|
||||
6525A82525E13FD4008FE0D0 /* SeismicNetworkAdvertiseTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworkAdvertiseTableViewCell.swift; sourceTree = "<group>"; };
|
||||
652C37BC26092B3C0068EC3B /* FiltersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiltersViewModel.swift; sourceTree = "<group>"; };
|
||||
6531185828425B89006CBC29 /* NotificationService+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationService+Extension.swift"; sourceTree = "<group>"; };
|
||||
65355FFE25F38D3300BB57D2 /* SegnalazioniMapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegnalazioniMapViewController.swift; sourceTree = "<group>"; };
|
||||
6535600325F398CD00BB57D2 /* Costanti+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Costanti+Extensions.swift"; sourceTree = "<group>"; };
|
||||
653604E8262348FA00B2B651 /* EQNBaseMapFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNBaseMapFilter.swift; sourceTree = "<group>"; };
|
||||
@@ -405,6 +410,8 @@
|
||||
6562C80625FFA6B100C85273 /* SeismicNetworkViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworkViewModel.swift; sourceTree = "<group>"; };
|
||||
6586971025F44C26009C0182 /* EQNBlurredCloseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNBlurredCloseButton.swift; sourceTree = "<group>"; };
|
||||
658BAB7A25FE67930015C454 /* EQNBaseMapRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNBaseMapRepresentable.swift; sourceTree = "<group>"; };
|
||||
658BC0282859A456009EECAA /* RealtimeAlertViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealtimeAlertViewController.swift; sourceTree = "<group>"; };
|
||||
658BC02A2859A4D3009EECAA /* RealtimeAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealtimeAlertView.swift; sourceTree = "<group>"; };
|
||||
65A4D5AA26280A24003918E0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
65A4D5AB26280A24003918E0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
65A4D5AC26280A56003918E0 /* el-GR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "el-GR"; path = "el-GR.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
@@ -424,6 +431,7 @@
|
||||
65DBFB7125E2BBF20041CBA6 /* GADTMediumTemplateView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GADTMediumTemplateView.m; sourceTree = "<group>"; };
|
||||
65DBFB7225E2BBF20041CBA6 /* GADTTemplateView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GADTTemplateView.m; sourceTree = "<group>"; };
|
||||
65DBFB7325E2BBF20041CBA6 /* GADTMediumTemplateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GADTMediumTemplateView.h; sourceTree = "<group>"; };
|
||||
65E1226B285C92AA000E294A /* EQNRealtimeAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNRealtimeAlert.swift; sourceTree = "<group>"; };
|
||||
65E1B19A260F980600A0ACBA /* Dictionary+EQNExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+EQNExtensions.swift"; sourceTree = "<group>"; };
|
||||
8C10B0BC2281FE7F00125C9F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
8C10B0BE2281FE9E00125C9F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
@@ -615,6 +623,15 @@
|
||||
path = Debug;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
658BC0272859A43C009EECAA /* Realtime Alert */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
658BC0282859A456009EECAA /* RealtimeAlertViewController.swift */,
|
||||
658BC02A2859A4D3009EECAA /* RealtimeAlertView.swift */,
|
||||
);
|
||||
path = "Realtime Alert";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
65DBFB5225E2A2580041CBA6 /* Map annotation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -660,6 +677,7 @@
|
||||
8C483CB521FDACD100259FD2 /* EQNNotificationService-Bridging-Header.h */,
|
||||
8C4B0B7C21CACE3F00AED489 /* NotificationService.h */,
|
||||
8C4B0B7D21CACE3F00AED489 /* NotificationService.m */,
|
||||
6531185828425B89006CBC29 /* NotificationService+Extension.swift */,
|
||||
DC30BC862534DBB30041B23B /* Icons */,
|
||||
8C4B0B7F21CACE3F00AED489 /* Info.plist */,
|
||||
);
|
||||
@@ -1068,6 +1086,7 @@
|
||||
8C593E89217BA2470008B260 /* EQNSegnalazione.m */,
|
||||
8CF4F4D9216D44930057110B /* EQNPastquakes.h */,
|
||||
8CF4F4DA216D44930057110B /* EQNPastquakes.m */,
|
||||
65E1226B285C92AA000E294A /* EQNRealtimeAlert.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
@@ -1087,6 +1106,7 @@
|
||||
DCEFF21024F57163009D3FE1 /* Settings */,
|
||||
DC141968250E769B0059E060 /* Seismic Networks */,
|
||||
DCB5281F256015EB005288E5 /* Simulator */,
|
||||
658BC0272859A43C009EECAA /* Realtime Alert */,
|
||||
);
|
||||
path = Controllers;
|
||||
sourceTree = "<group>";
|
||||
@@ -1526,6 +1546,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DCDAB31925188BB3001AE40D /* EQNAllertaSismica.m in Sources */,
|
||||
6531185928425B89006CBC29 /* NotificationService+Extension.swift in Sources */,
|
||||
8C4B0B7E21CACE3F00AED489 /* NotificationService.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1574,8 +1595,10 @@
|
||||
DCA5B6E7252E4BD8002AEC96 /* EQNBaseTableViewCell.swift in Sources */,
|
||||
8CF66058214C566B009F4314 /* ServerRequest.m in Sources */,
|
||||
DCF9E14D24F6D1AA002B6B1D /* EQNData.swift in Sources */,
|
||||
65E1226C285C92AA000E294A /* EQNRealtimeAlert.swift in Sources */,
|
||||
DC52B8A524FCCD6900ABEBA6 /* AppTheme.swift in Sources */,
|
||||
653C680425F3DF8A00FE52AC /* EQNBaseMapViewController.swift in Sources */,
|
||||
658BC02B2859A4D3009EECAA /* RealtimeAlertView.swift in Sources */,
|
||||
DC27EB2F24F6EBE000ACBFE0 /* SettingsSeismicNetworksViewController.swift in Sources */,
|
||||
8CF66059214C566B009F4314 /* Reachability.m in Sources */,
|
||||
DC886A5D24E92D5500F7A5D3 /* EQNBaseViewController.m in Sources */,
|
||||
@@ -1607,6 +1630,7 @@
|
||||
DC65B391250F243E00251693 /* SeismicSettingsNetworksViewController.swift in Sources */,
|
||||
65DBFB4B25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift in Sources */,
|
||||
DC08804124F5B41400186D97 /* SettingSliderTableViewCell.swift in Sources */,
|
||||
658BC0292859A456009EECAA /* RealtimeAlertViewController.swift in Sources */,
|
||||
8CBD3DD82149B9AD0070C963 /* main.m in Sources */,
|
||||
8CF05B57218C93BA0055012B /* EQNUtility.m in Sources */,
|
||||
8C4E34422152B5E8008B0D2A /* EQNRilevamento.m in Sources */,
|
||||
@@ -1738,12 +1762,12 @@
|
||||
CODE_SIGN_ENTITLEMENTS = EQNNotificationService/EQNNotificationService.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
CURRENT_PROJECT_VERSION = 98;
|
||||
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 = 5.0;
|
||||
MARKETING_VERSION = 5.2.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.notificationservice;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "EQNetwork Extension Service - Development";
|
||||
@@ -1762,12 +1786,12 @@
|
||||
CODE_SIGN_ENTITLEMENTS = EQNNotificationService/EQNNotificationService.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
CURRENT_PROJECT_VERSION = 98;
|
||||
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 = 5.0;
|
||||
MARKETING_VERSION = 5.2.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.notificationservice;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "EQNetwork Extension Service - AppStore";
|
||||
@@ -1907,14 +1931,14 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
CURRENT_PROJECT_VERSION = 98;
|
||||
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 = 5.0;
|
||||
MARKETING_VERSION = 5.2.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -2017,13 +2041,13 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
CURRENT_PROJECT_VERSION = 98;
|
||||
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 = 5.0;
|
||||
MARKETING_VERSION = 5.2.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -2122,12 +2146,12 @@
|
||||
CODE_SIGN_ENTITLEMENTS = EQNNotificationContent/EQNNotificationContent.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
CURRENT_PROJECT_VERSION = 98;
|
||||
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 = 5.0;
|
||||
MARKETING_VERSION = 5.2.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.notificationcontent;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "EQNetwork Extension Content - Development";
|
||||
@@ -2146,12 +2170,12 @@
|
||||
CODE_SIGN_ENTITLEMENTS = EQNNotificationContent/EQNNotificationContent.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
CURRENT_PROJECT_VERSION = 98;
|
||||
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 = 5.0;
|
||||
MARKETING_VERSION = 5.2.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.notificationcontent;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "EQNetwork Extension Content - AppStore";
|
||||
|
||||
@@ -124,7 +124,10 @@
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
NSString *token = [self stringWithDeviceToken:deviceToken];
|
||||
NSLog(@"[DEBUG] push token: %@", token);
|
||||
[[NSUserDefaults standardUserDefaults] setObject:token forKey:EQNUserDefaultPushToken];
|
||||
|
||||
FIRMessaging.messaging.APNSToken = deviceToken;
|
||||
}
|
||||
|
||||
- (NSString *)stringWithDeviceToken:(NSData *)deviceToken
|
||||
@@ -180,9 +183,9 @@
|
||||
EQNTabBarSection section = EQNTabBarSectionAllerte;
|
||||
if ([userInfo[@"type"] isEqualToString:@"eqn"]) {
|
||||
NSDate *dataRicezione = [NSDate date];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:dataRicezione forKey:NOTIFICHE_RETE_SMARTPHONE_DATA_NOTIFICA];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:dataRicezione forKey:EQNUserDefaultRealTimeAlertDate];
|
||||
|
||||
[EQNUtility storeDictionary:userInfo toUserDefaultForKey:NOTIFICHE_RETE_SMARTPHONE_DIZIONARIO_NOTIFICA];
|
||||
[EQNUtility storeDictionary:userInfo toUserDefaultForKey:EQNUserDefaultRealTimeAlertPayload];
|
||||
section = EQNTabBarSectionAllerte;
|
||||
} else if([userInfo[@"type"] isEqualToString:@"manual"]) {
|
||||
section = EQNTabBarSectionSegnalazioni;
|
||||
|
||||
@@ -104,7 +104,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
- (void)setupUI
|
||||
{
|
||||
self.title = [NSLocalizedString(@"tab_network", nil) capitalizedString];
|
||||
self.tableView.estimatedRowHeight = 200.0;
|
||||
self.tableView.estimatedRowHeight = 600.0;
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
}
|
||||
|
||||
@@ -116,15 +116,23 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
BOOL showAllCards = [[NSUserDefaults standardUserDefaults] boolForKey:EQNUserDefaultKeyAlertsShowAllCards];
|
||||
self.expandeCollapseButton.image = showAllCards ? [UIImage imageNamed:@"navbar-icon-arrow-collapse"] : [UIImage imageNamed:@"navbar-icon-arrow-expand"];
|
||||
|
||||
NSDate *date = [[NSUserDefaults standardUserDefaults] objectForKey:NOTIFICHE_RETE_SMARTPHONE_DATA_NOTIFICA];
|
||||
if (date) {
|
||||
if ([EQNUtility getDifferenceMinute:date] < TEMPO_VISUALIZZAZIONE_NOTIFICA)
|
||||
self.isNotificaAttiva = YES;
|
||||
else{
|
||||
self.isNotificaAttiva = NO;
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:NOTIFICHE_RETE_SMARTPHONE_DATA_NOTIFICA];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
// controlliamo se c'è una notifica in tempo reale da mostrare
|
||||
NSDate *date = [[NSUserDefaults standardUserDefaults] objectForKey:EQNUserDefaultRealTimeAlertDate];
|
||||
NSDictionary *info = [EQNUtility loadDictionaryFromUserDefaultsForKey:EQNUserDefaultRealTimeAlertPayload];
|
||||
if (date && info && [EQNUtility getDifferenceMinute:date] < EQNRealtimeAlertExpiration) {
|
||||
self.isNotificaAttiva = YES;
|
||||
|
||||
// mostriamo la schermata solo se il countdown non è a zero
|
||||
EQNRealtimeAlert *alert = [[EQNRealtimeAlert alloc] initWithNotification:info];
|
||||
if (alert != nil && ![alert isCountdownExpired]) {
|
||||
RealtimeAlertViewController *controller = [[RealtimeAlertViewController alloc] initWithAlert:alert];
|
||||
if (@available(iOS 13.0, *)) {
|
||||
controller.modalInPresentation = YES;
|
||||
}
|
||||
[self presentViewController:controller animated:YES completion:nil];
|
||||
}
|
||||
} else {
|
||||
[self resetRealtimeAlert];
|
||||
}
|
||||
|
||||
[self.tableItems removeAllObjects];
|
||||
@@ -152,6 +160,13 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
- (void)resetRealtimeAlert
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:EQNUserDefaultRealTimeAlertDate];
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:EQNUserDefaultRealTimeAlertPayload];
|
||||
self.isNotificaAttiva = NO;
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)refreshDataTapped:(id)sender
|
||||
@@ -171,11 +186,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
|
||||
- (void)actionCloseNotification
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:NOTIFICHE_RETE_SMARTPHONE_DATA_NOTIFICA];
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:NOTIFICHE_RETE_SMARTPHONE_DIZIONARIO_NOTIFICA];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
self.isNotificaAttiva = NO;
|
||||
|
||||
[self resetRealtimeAlert];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
@@ -258,7 +269,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
} else if (tableRow == AllerteTableRowSismiRilevati) {
|
||||
if (self.isNotificaAttiva) {
|
||||
AlertsSeismicNotificationExpandedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SeismicNotificationExpandedCell" forIndexPath:indexPath];
|
||||
NSDictionary *info = [EQNUtility loadDictionaryFromUserDefaultsForKey:NOTIFICHE_RETE_SMARTPHONE_DIZIONARIO_NOTIFICA];
|
||||
NSDictionary *info = [EQNUtility loadDictionaryFromUserDefaultsForKey:EQNUserDefaultRealTimeAlertPayload];
|
||||
cell.notification = info;
|
||||
|
||||
__weak AllerteViewController *weakSelf = self;
|
||||
|
||||
-26
@@ -15,7 +15,6 @@ class AlertsSeismicNotificationExpandedTableViewCell: EQNBaseTableViewCell, MKMa
|
||||
|
||||
@objc var notification: [String: Any]? {
|
||||
didSet {
|
||||
startCountdown()
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
@@ -64,17 +63,6 @@ class AlertsSeismicNotificationExpandedTableViewCell: EQNBaseTableViewCell, MKMa
|
||||
descriptionLabel.text = NSLocalizedString("map_smartphone_magnitude", comment: "")
|
||||
}
|
||||
|
||||
private func startCountdown() {
|
||||
guard let notification = notification else { return }
|
||||
|
||||
// calculate the impact timestamp and start a timer for the countdown label
|
||||
if let impactTimestamp = EQNUtility.calculateUserSeismicTimestamp(fromUserInfo: notification) {
|
||||
self.impactTimestamp = impactTimestamp
|
||||
countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(countdownTimerFired(_:)), userInfo: nil, repeats: true)
|
||||
countdownTimer?.fire()
|
||||
}
|
||||
}
|
||||
|
||||
private func updateUI() {
|
||||
// clearn any other previous notifications
|
||||
notificationTitleLabel.text = ""
|
||||
@@ -149,20 +137,6 @@ class AlertsSeismicNotificationExpandedTableViewCell: EQNBaseTableViewCell, MKMa
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc private func countdownTimerFired(_ sender: Timer) {
|
||||
guard let impactTimestamp = impactTimestamp else { return }
|
||||
|
||||
let now = Date()
|
||||
let difference = lround(max(impactTimestamp.timeIntervalSince(now), 0))
|
||||
waveTimeLabel.text = String(format: NSLocalizedString("alert_wave", comment: ""), difference)
|
||||
|
||||
if difference <= 0 {
|
||||
// stop the countdown
|
||||
countdownTimer?.invalidate()
|
||||
countdownTimer = nil
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction private func shareAppTapped(_ sender: UIButton) {
|
||||
onTapShareApp?()
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ static NSString * const SegueIdentifierLogs = @"ShowLogs";
|
||||
}
|
||||
|
||||
// tap 5 times on "Settings" to open debug view
|
||||
if ([controller isKindOfClass:[SettingsViewController class]]) {
|
||||
if ([controller isKindOfClass:[SettingsViewController class]] && EQNEnableDebugView) {
|
||||
self.debugTapCounter += 1;
|
||||
if (self.debugTapCounter == 5) {
|
||||
self.debugTapCounter = 0;
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// RealtimeAlertView.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 15/06/22.
|
||||
// Copyright © 2022 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
|
||||
|
||||
class RealtimeAlertView: UIView {
|
||||
|
||||
let titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.font = .preferredFont(forTextStyle: .title2)
|
||||
label.text = NSLocalizedString("app_name", comment: "")
|
||||
return label
|
||||
}()
|
||||
|
||||
let descriptionLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.font = .preferredFont(forTextStyle: .body)
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
}()
|
||||
|
||||
let waveTimeLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.font = .preferredFont(forTextStyle: .title3)
|
||||
label.textColor = AppTheme.Colors.red
|
||||
label.text = String(format: NSLocalizedString("alert_wave", comment: ""), 0)
|
||||
label.textAlignment = .center
|
||||
label.isHidden = true
|
||||
return label
|
||||
}()
|
||||
|
||||
lazy var mapView: MKMapView = {
|
||||
let map = MKMapView()
|
||||
map.translatesAutoresizingMaskIntoConstraints = false
|
||||
map.delegate = self
|
||||
map.register(EQNCustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNCustomAnnotationView.SingleLineIdentifier)
|
||||
map.showsUserLocation = true
|
||||
return map
|
||||
}()
|
||||
|
||||
let closeButton: EQNBlurredCloseButton = {
|
||||
let button = EQNBlurredCloseButton()
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
button.setTitleColor(.darkGray, for: .normal)
|
||||
return button
|
||||
}()
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
convenience init() {
|
||||
self.init(frame: .zero)
|
||||
configureUI()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func configureUI() {
|
||||
backgroundColor = AppTheme.Colors.lightGray
|
||||
|
||||
addSubview(closeButton)
|
||||
addSubview(titleLabel)
|
||||
addSubview(descriptionLabel)
|
||||
addSubview(waveTimeLabel)
|
||||
addSubview(mapView)
|
||||
|
||||
closeButton.addDefaultConstraint(to: self)
|
||||
|
||||
titleLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true
|
||||
titleLabel.trailingAnchor.constraint(equalTo: closeButton.leadingAnchor, constant: -10.0).isActive = true
|
||||
titleLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor, constant: 10.0).isActive = true
|
||||
|
||||
descriptionLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true
|
||||
descriptionLabel.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor).isActive = true
|
||||
descriptionLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 20.0).isActive = true
|
||||
|
||||
waveTimeLabel.leadingAnchor.constraint(equalTo: descriptionLabel.leadingAnchor).isActive = true
|
||||
waveTimeLabel.trailingAnchor.constraint(equalTo: descriptionLabel.trailingAnchor).isActive = true
|
||||
waveTimeLabel.topAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, constant: 20.0).isActive = true
|
||||
|
||||
mapView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
|
||||
mapView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
|
||||
mapView.topAnchor.constraint(equalTo: waveTimeLabel.bottomAnchor, constant: 20.0).isActive = true
|
||||
mapView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func addMapCircle(
|
||||
center: CLLocationCoordinate2D,
|
||||
radius: CLLocationDistance,
|
||||
overlayId: String
|
||||
) {
|
||||
// remove any other existing overlays
|
||||
let overlays = mapView.overlays.filter { $0.title == overlayId }
|
||||
mapView.removeOverlays(overlays)
|
||||
|
||||
// add new overlay
|
||||
let circle = MKCircle(center: center, radius: radius)
|
||||
circle.title = overlayId
|
||||
mapView.addOverlay(circle)
|
||||
}
|
||||
|
||||
func addMapLine(
|
||||
coordinates: [CLLocationCoordinate2D]
|
||||
) {
|
||||
let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
|
||||
mapView.addOverlay(polyline)
|
||||
}
|
||||
|
||||
func addMapAnnotation(
|
||||
title: String = "",
|
||||
center: CLLocationCoordinate2D,
|
||||
intensity: Int
|
||||
) {
|
||||
let annotation = EQNMapAnnotationPastquake(title: title, coordinate: center, intensity: intensity)
|
||||
mapView.addAnnotation(annotation)
|
||||
}
|
||||
}
|
||||
|
||||
extension RealtimeAlertView: MKMapViewDelegate {
|
||||
|
||||
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
||||
switch overlay {
|
||||
case let circle as MKCircle:
|
||||
let circleRenderer = MKCircleRenderer(overlay: circle)
|
||||
circleRenderer.strokeColor = AppTheme.Colors.red
|
||||
circleRenderer.fillColor = AppTheme.Colors.red.withAlphaComponent(0.2)
|
||||
circleRenderer.lineWidth = 3.0
|
||||
return circleRenderer
|
||||
case let polyline as MKPolyline:
|
||||
let polylineRenderer = MKPolylineRenderer(polyline: polyline)
|
||||
polylineRenderer.strokeColor = .blue
|
||||
polylineRenderer.lineWidth = 2.0
|
||||
return polylineRenderer
|
||||
default:
|
||||
return MKOverlayRenderer(overlay: overlay)
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
|
||||
guard let annotation = annotation as? EQNMapAnnotationPastquake else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: EQNCustomAnnotationView.SingleLineIdentifier, for: annotation) as! EQNCustomAnnotationView
|
||||
annotationView.image = annotation.image
|
||||
annotationView.title = annotation.title
|
||||
return annotationView
|
||||
}
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
//
|
||||
// RealtimeAlertViewController.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 15/06/22.
|
||||
// Copyright © 2022 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
|
||||
|
||||
class RealtimeAlertViewController: UIViewController, MKMapViewDelegate {
|
||||
|
||||
@objc var onClose: () -> Void = {}
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
private let notificationView = RealtimeAlertView()
|
||||
/// Alert to display
|
||||
private let realtimeAlert: EQNRealtimeAlert
|
||||
/// Timer to constantly update countdown label
|
||||
private var countdownTimer: Timer?
|
||||
/// Refresh time for wave animation
|
||||
private let waveAnimationRefreshRate = 0.1
|
||||
/// Current radius of the wave animation on the map
|
||||
private var waveAnimationCurrentRadius: CLLocationDistance = 0
|
||||
private var waveAnimationVelocity: Double = 1_000
|
||||
/// Timer to simulate animation for the wave
|
||||
private var waveAnimationTimer: Timer?
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
@objc
|
||||
init(alert: EQNRealtimeAlert) {
|
||||
self.realtimeAlert = alert
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
self.waveAnimationCurrentRadius = currentWavePosition()
|
||||
self.waveAnimationVelocity = evaluateWaveAnimationVelocity()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
// importante togliere il delegato, altrimenti causa crash
|
||||
notificationView.mapView.delegate = nil
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func loadView() {
|
||||
view = notificationView
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
configureUI()
|
||||
updateUI()
|
||||
|
||||
startCountdown()
|
||||
startWaveAnimation()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func configureUI() {
|
||||
notificationView.closeButton.addTarget(self, action: #selector(onTapClose(_:)), for: .touchUpInside)
|
||||
}
|
||||
|
||||
private func updateUI() {
|
||||
notificationView.descriptionLabel.text = realtimeAlert.title
|
||||
|
||||
// update title with distance from earthquake
|
||||
let distanceRound = Int(round(realtimeAlert.distanceFromUser() / 1_000))
|
||||
notificationView.descriptionLabel.text = (notificationView.descriptionLabel.text ?? "")
|
||||
+ ".\n"
|
||||
+ String(format: NSLocalizedString("timer_message2_other", comment: ""), distanceRound)
|
||||
|
||||
// center map on the earthquake coordinate
|
||||
let span = MKCoordinateSpan(latitudeDelta: 10.5, longitudeDelta: 10.5)
|
||||
let region = MKCoordinateRegion(center: realtimeAlert.coordinate.coordinate, span: span)
|
||||
notificationView.mapView.setCenter(realtimeAlert.coordinate.coordinate, animated: false)
|
||||
notificationView.mapView.setRegion(region, animated: true)
|
||||
|
||||
// aggiungiamo annotation con epicentro sisma
|
||||
notificationView.addMapAnnotation(center: realtimeAlert.coordinate.coordinate, intensity: realtimeAlert.intensity)
|
||||
|
||||
// simuliamo animazione dell'onda sismica
|
||||
notificationView.addMapCircle(center: realtimeAlert.coordinate.coordinate, radius: waveAnimationCurrentRadius, overlayId: "wave_animation")
|
||||
|
||||
// aggiungiamo un segmento tra la posizione del sisma e quella dell'utente
|
||||
if let lastPosition = EQNUser.default().lastPosition {
|
||||
notificationView.addMapLine(coordinates: [realtimeAlert.coordinate.coordinate, lastPosition.coordinate])
|
||||
}
|
||||
}
|
||||
|
||||
private func startCountdown() {
|
||||
// show countdown only if time is less than 300 seconds
|
||||
if realtimeAlert.currentCountdown() < 300 {
|
||||
// start a timer for the countdown label
|
||||
notificationView.waveTimeLabel.isHidden = false
|
||||
countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(countdownTimerFired(_:)), userInfo: nil, repeats: true)
|
||||
countdownTimer?.fire()
|
||||
}
|
||||
}
|
||||
|
||||
private func startWaveAnimation() {
|
||||
waveAnimationTimer = Timer.scheduledTimer(timeInterval: waveAnimationRefreshRate, target: self, selector: #selector(mapWaveAnimationFired(_:)), userInfo: nil, repeats: true)
|
||||
waveAnimationTimer?.fire()
|
||||
}
|
||||
|
||||
// MARK: - Action
|
||||
|
||||
@objc private func onTapClose(_ sender: UIButton) {
|
||||
// invalidiamo i timer, altri
|
||||
countdownTimer?.invalidate()
|
||||
countdownTimer = nil
|
||||
waveAnimationTimer?.invalidate()
|
||||
waveAnimationTimer = nil
|
||||
|
||||
onClose()
|
||||
dismiss(animated: true)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Timer
|
||||
|
||||
@objc private func countdownTimerFired(_ sender: Timer) {
|
||||
let countdown = realtimeAlert.currentCountdown()
|
||||
notificationView.waveTimeLabel.text = String(format: NSLocalizedString("alert_wave", comment: ""), countdown)
|
||||
|
||||
if countdown <= 0 {
|
||||
// stop the countdown
|
||||
countdownTimer?.invalidate()
|
||||
countdownTimer = nil
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func mapWaveAnimationFired(_ sender: Timer) {
|
||||
waveAnimationCurrentRadius += waveAnimationVelocity
|
||||
notificationView.addMapCircle(center: realtimeAlert.coordinate.coordinate, radius: waveAnimationCurrentRadius, overlayId: "wave_animation")
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
/// Evaluate current position for the wave
|
||||
/// Used to define initial position for the wave circle
|
||||
/// - Returns: Distance of the wave from the original earthquake point
|
||||
private func currentWavePosition() -> Double {
|
||||
// distanza tra utente e terremoto
|
||||
let distance = realtimeAlert.distanceFromUser()
|
||||
|
||||
// calcoliamo la distanza rimanente da mostrare, perchè la schermata potrebbe anche essere aperta in ritardo
|
||||
let remainingDistance = realtimeAlert.waveSpeed * Double(realtimeAlert.currentCountdown())
|
||||
return distance - remainingDistance
|
||||
}
|
||||
|
||||
/// Evaluate wave velocity based on push notification data
|
||||
/// - Returns: Wave velocity, used for animation
|
||||
private func evaluateWaveAnimationVelocity() -> Double {
|
||||
let velocity = realtimeAlert.waveSpeed
|
||||
return velocity * waveAnimationRefreshRate
|
||||
}
|
||||
}
|
||||
+8
-12
@@ -66,7 +66,8 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
super.viewDidLoad()
|
||||
|
||||
setupUI()
|
||||
updateUI()
|
||||
loadDataSource()
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
private func setupUI() {
|
||||
@@ -83,7 +84,7 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
closeButton.setLocalizedTitle(key: "official_close", uppercased: false)
|
||||
}
|
||||
|
||||
private func updateUI() {
|
||||
private func loadDataSource() {
|
||||
currentMagnitudoMinima = EQNData.magitudoDebole(for: EQNSeismic.shared.magnitudoMinima)
|
||||
if initialMagnitudoMinima == nil {
|
||||
initialMagnitudoMinima = currentMagnitudoMinima
|
||||
@@ -97,7 +98,6 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
initialQualsiasiMagnitudo = currentSismiQualsiasiMagnitudo
|
||||
}
|
||||
currentModificaImpostazioni = EQNSeismic.shared.modificaImpostazioniAbilitato
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
// MARK: - Table view delegate and data source
|
||||
@@ -111,7 +111,7 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
|
||||
switch setting.type {
|
||||
case .slider:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: SettingSliderTableViewCell.Identifier, for: indexPath) as! SettingSliderTableViewCell
|
||||
let cell = SettingSliderTableViewCell(style: .default, reuseIdentifier: nil)
|
||||
cell.titleLabel.text = setting.displayTitle
|
||||
|
||||
if indexPath.row == RowIdentifier.magnitudoMinima.rawValue {
|
||||
@@ -120,7 +120,6 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
currentMagnitudoMinima = value
|
||||
EQNSeismic.shared.magnitudoMinima = value.value
|
||||
EQNSeismic.shared.saveFilters()
|
||||
updateUI()
|
||||
}
|
||||
cell.dragEnded = { [unowned self] in
|
||||
showWarningAlertIfNeeded(for: currentMagnitudoMinima)
|
||||
@@ -131,7 +130,6 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
currentDistanzaMassima = value
|
||||
EQNSeismic.shared.distanzaMassima = value.value
|
||||
EQNSeismic.shared.saveFilters()
|
||||
updateUI()
|
||||
}
|
||||
} else if indexPath.row == RowIdentifier.periodoTemporale.rawValue {
|
||||
cell.configureSlider(with: dataSourcePeriodoTemporale, current: currentPeriodoTemporale)
|
||||
@@ -139,7 +137,6 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
currentPeriodoTemporale = value
|
||||
EQNSeismic.shared.periodoTemporale = value.value
|
||||
EQNSeismic.shared.saveFilters()
|
||||
updateUI()
|
||||
}
|
||||
} else if indexPath.row == RowIdentifier.sismiFortiDistanza.rawValue {
|
||||
cell.isDisabled = !currentSismiFortiAbilitati
|
||||
@@ -148,13 +145,12 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
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
|
||||
let cell = SettingEnableTableViewCell(style: .default, reuseIdentifier: nil)
|
||||
cell.titleLabel.text = setting.displayTitle
|
||||
cell.detailTextLabel?.text = setting.subtitle
|
||||
|
||||
@@ -164,7 +160,9 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
currentSismiFortiAbilitati = value
|
||||
EQNSeismic.shared.sismiFortiAbilitati = value
|
||||
EQNSeismic.shared.saveFilters()
|
||||
updateUI()
|
||||
|
||||
loadDataSource()
|
||||
tableView.reloadData()
|
||||
}
|
||||
} else if indexPath.row == RowIdentifier.sismiQualsiasiMagnitudo.rawValue {
|
||||
cell.toggleSwitch.isOn = currentSismiQualsiasiMagnitudo
|
||||
@@ -172,7 +170,6 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
currentSismiQualsiasiMagnitudo = value
|
||||
EQNSeismic.shared.sismiQualsiasiAbilitati = value
|
||||
EQNSeismic.shared.saveFilters()
|
||||
updateUI()
|
||||
}
|
||||
} else if indexPath.row == RowIdentifier.modificaImpostazioni.rawValue {
|
||||
cell.toggleSwitch.isOn = currentModificaImpostazioni
|
||||
@@ -180,7 +177,6 @@ class SeismicFiltersViewController: UIViewController, UITableViewDelegate, UITab
|
||||
currentModificaImpostazioni = value
|
||||
EQNSeismic.shared.modificaImpostazioniAbilitato = value
|
||||
EQNSeismic.shared.saveFilters()
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -86,7 +86,12 @@ class SeismicSettingsNetworksViewController: UITableViewController {
|
||||
savedNetworks.append(network.acronym)
|
||||
}
|
||||
|
||||
tableView.reloadRows(at: [indexPath], with: .automatic)
|
||||
// reload all rows with the given acronym
|
||||
let indexes = networks
|
||||
.enumerated()
|
||||
.filter { $0.element.acronym == network.acronym }
|
||||
.map { IndexPath(row: $0.offset, section: 0) }
|
||||
tableView.reloadRows(at: indexes, with: .automatic)
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@@ -89,8 +89,6 @@ class SettingDateTableViewCell: UITableViewCell {
|
||||
// MARK: - Private
|
||||
|
||||
private func setupUI() {
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
stackView.addArrangedSubview(titleLabel)
|
||||
stackView.addArrangedSubview(valuesLabel)
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ class SettingEnableTableViewCell: UITableViewCell {
|
||||
|
||||
private func setupUI() {
|
||||
selectionStyle = .none
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let stackView = UIStackView()
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
-2
@@ -54,8 +54,6 @@ class SettingMultivaluesTableViewCell: UITableViewCell {
|
||||
// MARK: - Private
|
||||
|
||||
private func setupUI() {
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let stackView = UIStackView()
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.axis = .vertical
|
||||
|
||||
-1
@@ -55,7 +55,6 @@ class SettingSegmentedTableViewCell: UITableViewCell {
|
||||
|
||||
private func setupUI() {
|
||||
selectionStyle = .none
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let stackView = UIStackView()
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
+6
-1
@@ -66,7 +66,6 @@ class SettingSliderTableViewCell: UITableViewCell {
|
||||
|
||||
private func setupUI() {
|
||||
selectionStyle = .none
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let stackView = UIStackView()
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
@@ -99,6 +98,12 @@ class SettingSliderTableViewCell: UITableViewCell {
|
||||
let index = Int(sender.value)
|
||||
let item = items[index]
|
||||
|
||||
// make slider with step values
|
||||
let step: Float = 1
|
||||
let roundedValue = round(sender.value / step) * step
|
||||
sender.value = roundedValue
|
||||
|
||||
// update value
|
||||
valueLabel.text = item.display
|
||||
valueChanged?(item)
|
||||
}
|
||||
|
||||
+13
-9
@@ -75,7 +75,8 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
self.dataSourceSismi = [EQNData seismicToNotify];
|
||||
self.dataSourceRaggioSisma = [EQNData raggioSismi];
|
||||
|
||||
[self updateUI];
|
||||
[self loadDataSource];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
@@ -94,7 +95,7 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
[self.tableView registerClass:[SettingDateTableViewCell class] forCellReuseIdentifier:SettingDateTableViewCell.Identifier];
|
||||
}
|
||||
|
||||
- (void)updateUI
|
||||
- (void)loadDataSource
|
||||
{
|
||||
self.notificationEnabled = [EQNAllertaSismica sharedInstance].isAbilitato;
|
||||
self.criticalAlertsEnabled = [EQNAllertaSismica sharedInstance].isCriticalAlertsEnabled;
|
||||
@@ -120,8 +121,6 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
self.currentEndTime = endTime;
|
||||
|
||||
[[EQNAllertaSismica sharedInstance] saveUserInfo];
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
|
||||
@@ -262,35 +261,40 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
{
|
||||
[EQNAllertaSismica sharedInstance].sismiDaNotificare = seismic.value;
|
||||
[[EQNAllertaSismica sharedInstance] saveUserInfo];
|
||||
[self updateUI];
|
||||
|
||||
[self loadDataSource];
|
||||
}
|
||||
|
||||
- (void)updateLowSeismicRadius:(EQNGenericValue *)radius
|
||||
{
|
||||
[EQNAllertaSismica sharedInstance].raggioSismiLievi = radius.value;
|
||||
[[EQNAllertaSismica sharedInstance] saveUserInfo];
|
||||
[self updateUI];
|
||||
|
||||
[self loadDataSource];
|
||||
}
|
||||
|
||||
- (void)updateStrongSeismicRadius:(EQNGenericValue *)radius
|
||||
{
|
||||
[EQNAllertaSismica sharedInstance].raggioSismiForti = radius.value;
|
||||
[[EQNAllertaSismica sharedInstance] saveUserInfo];
|
||||
[self updateUI];
|
||||
|
||||
[self loadDataSource];
|
||||
}
|
||||
|
||||
- (void)updateStartTime:(NSDate *)date
|
||||
{
|
||||
[EQNAllertaSismica sharedInstance].oraioInizio = date;
|
||||
[[EQNAllertaSismica sharedInstance] saveUserInfo];
|
||||
[self updateUI];
|
||||
|
||||
[self loadDataSource];
|
||||
}
|
||||
|
||||
- (void)updateEndTime:(NSDate *)date
|
||||
{
|
||||
[EQNAllertaSismica sharedInstance].orarioFine = date;
|
||||
[[EQNAllertaSismica sharedInstance] saveUserInfo];
|
||||
[self updateUI];
|
||||
|
||||
[self loadDataSource];
|
||||
}
|
||||
|
||||
- (void)askForCriticalAlertsPermission
|
||||
|
||||
+8
-8
@@ -62,14 +62,16 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
self.dataSourceRaggioSisma = [EQNData raggioSismi];
|
||||
self.dataSourceMagnitudoForti = [EQNData magitudoForti];
|
||||
|
||||
[self updateUI];
|
||||
[self loadDataSource];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
[self updateUI];
|
||||
[self loadDataSource];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
@@ -86,7 +88,7 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
[self.tableView registerClass:[SettingMultivaluesTableViewCell class] forCellReuseIdentifier:SettingMultivaluesTableViewCell.Identifier];
|
||||
}
|
||||
|
||||
- (void)updateUI
|
||||
- (void)loadDataSource
|
||||
{
|
||||
self.notificationEnabled = [EQNNotificheReteSismiche sharedInstance].isAbilitato;
|
||||
self.notificationNearEarthquakeEnabled = [EQNNotificheReteSismiche sharedInstance].isAbilitaVicini;
|
||||
@@ -110,8 +112,6 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
}
|
||||
|
||||
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
[EQNNotificheReteSismiche sharedInstance].distanzaPosizione = radius.value;
|
||||
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
|
||||
|
||||
[self updateUI];
|
||||
[self loadDataSource];
|
||||
}
|
||||
|
||||
- (void)updateSeismicEnergy:(EQNGenericValue *)energy
|
||||
@@ -237,7 +237,7 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
[EQNNotificheReteSismiche sharedInstance].energiaSisma = energy.value;
|
||||
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
|
||||
|
||||
[self updateUI];
|
||||
[self loadDataSource];
|
||||
}
|
||||
|
||||
- (void)updateStrongEarthquakeEnergy:(EQNGenericValue *)energy
|
||||
@@ -245,7 +245,7 @@ typedef NS_ENUM(NSInteger, RowIdentifier) {
|
||||
[EQNNotificheReteSismiche sharedInstance].energiaTerremotiForti = energy.value;
|
||||
[[EQNNotificheReteSismiche sharedInstance] saveUserInfo];
|
||||
|
||||
[self updateUI];
|
||||
[self loadDataSource];
|
||||
}
|
||||
|
||||
- (NSString *)stringOfSelectedNetworks
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
/// Stampa le risposte delle chiamate al server
|
||||
static BOOL const EQNDebugPrintResponse = NO;
|
||||
/// Visualizza schermata con info di debug (ex. push token)
|
||||
static BOOL const EQNEnableDebugView = NO;
|
||||
|
||||
#pragma mark - Urls
|
||||
|
||||
@@ -71,6 +73,9 @@ static NSString * const EQNUserDefaultKeySesmicInformations = @"EQNetwork.Seismi
|
||||
static NSString * const EQNUserDefaultKeyOneShotShowCountry = @"EQNetwork.OneShot.CountrySelection";
|
||||
static NSString * const EQNUserDefaultLastLocation = @"EQNLast_Location";
|
||||
static NSString * const EQNUserDefaultSeismicNetworkCards = @"EQNData.RetiSismiche";
|
||||
static NSString * const EQNUserDefaultRealTimeAlertPayload = @"EQNData.RealtimeAlertPayload";
|
||||
static NSString * const EQNUserDefaultRealTimeAlertDate = @"EQNData.RealtimeAlertDate";
|
||||
|
||||
/// Numero di aperture dell'app per sbloccare la versione Pro scontata
|
||||
static NSString * const EQNUserDefaultProDiscountOpenCounter = @"CONTEGGIO_APERTURE_PER_SCONTO";
|
||||
/// Prezzo scontato per la versione pro scaduto
|
||||
@@ -106,6 +111,8 @@ static NSTimeInterval const EQNSeismicDataRefreshInterval = 120.0;
|
||||
static NSTimeInterval const EQNSendReportDelayBetweenMessages = 5.0;
|
||||
/// Tempo di attesa (minuti) per l'invio di due commenti
|
||||
static NSTimeInterval const EQNSendReportDelayBetweenComments = 30.0;
|
||||
/// Tempo (in minuti) entro cui vengono mostrate allerte in tempo reale ricevute
|
||||
static NSTimeInterval const EQNRealtimeAlertExpiration = 480;
|
||||
|
||||
#ifdef DEBUG
|
||||
static NSString * const EQNAdMobAppIdAdaptiveBanner = @"ca-app-pub-3940256099942544/2934735716"; // test
|
||||
@@ -216,11 +223,6 @@ typedef enum : NSInteger {
|
||||
#define NOTIFICHE_ALLERA_SISMICA_ORA_INIZIO @"NOTIFICHE_ALLERA_SISMICA_ORA_INIZIO"
|
||||
#define NOTIFICHE_ALLERA_SISMICA_ORA_FINE @"NOTIFICHE_ALLERA_SISMICA_ORA_INIZIO"
|
||||
|
||||
// NOTIFICHE RETE SMARTPHONE
|
||||
#define NOTIFICHE_RETE_SMARTPHONE_DATA_NOTIFICA @"NOTIFICHE_RETE_SMARTPHONE_DATA_NOTIFICA"
|
||||
#define NOTIFICHE_RETE_SMARTPHONE_DIZIONARIO_NOTIFICA @"NOTIFICHE_RETE_SMARTPHONE_DIZIONARIO_NOTIFICA"
|
||||
#define TEMPO_VISUALIZZAZIONE_NOTIFICA 10800
|
||||
|
||||
|
||||
// FILTRO ENTI
|
||||
#define EQN_MAGNITUDO_MINIMA @"EQN_MAGNITUDO_MINIMA"
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// EQNRealtimeAlert.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 17/06/22.
|
||||
// Copyright © 2022 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreLocation
|
||||
|
||||
|
||||
@objc
|
||||
class EQNRealtimeAlert: NSObject {
|
||||
|
||||
typealias NotificationPayload = [String: Any]
|
||||
|
||||
/// Title to display
|
||||
var title: String = ""
|
||||
/// Earthquake coordinate
|
||||
let coordinate: CLLocation
|
||||
/// Earthquake intensity
|
||||
let intensity: Int
|
||||
/// Earthquake wave speed
|
||||
let waveSpeed: Double
|
||||
/// Calculated timestamp for earthquake on user position
|
||||
let impactTimestamp: Date
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
@objc
|
||||
init?(notification: [String: Any]) {
|
||||
guard let alert = Self.getPushAlertPayload(from: notification),
|
||||
let coordinate = Self.getCoordinate(from: notification),
|
||||
let impactTimestamp = EQNUtility.calculateUserSeismicTimestamp(fromUserInfo: notification) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.coordinate = coordinate
|
||||
self.impactTimestamp = impactTimestamp
|
||||
if let title = alert["loc-key"] as? String, let args = alert["loc-args"] as? [String], let arg = args.first {
|
||||
self.title = String(format: NSLocalizedString(title, comment: ""), arg)
|
||||
}
|
||||
self.intensity = notification.eqn_intValue(for: "intensity") ?? 0
|
||||
self.waveSpeed = (notification.eqn_doubleValue(for: "wave_speed") ?? 0) * 1000 // m/s
|
||||
}
|
||||
|
||||
func distanceFromUser() -> CLLocationDistance {
|
||||
EQNUser.default().lastPosition?.distance(from: coordinate) ?? 0.0
|
||||
}
|
||||
|
||||
/// Remaining time before earthquake gets user position
|
||||
func currentCountdown() -> Int {
|
||||
let now = Date()
|
||||
let difference = lround(max(impactTimestamp.timeIntervalSince(now), 0))
|
||||
return difference
|
||||
}
|
||||
|
||||
@objc
|
||||
func isCountdownExpired() -> Bool {
|
||||
currentCountdown() <= 0
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
/// Get `aps.alert` object inside a given notification payload
|
||||
/// - Parameter notification: Notification payload
|
||||
/// - Returns: `aps.alert` object if found, nil otherwise
|
||||
static func getPushAlertPayload(
|
||||
from notification: NotificationPayload
|
||||
) -> NotificationPayload? {
|
||||
guard let aps = notification["aps"] as? [String: Any],
|
||||
let alert = aps["alert"] as? [String: Any] else {
|
||||
return nil
|
||||
}
|
||||
return alert
|
||||
}
|
||||
|
||||
/// Retrieve coordinate of earthquake from the notification payload
|
||||
/// - Parameter notification: Notification payload
|
||||
/// - Returns: Coordinate if found, nil otherwise
|
||||
static func getCoordinate(
|
||||
from notification: NotificationPayload
|
||||
) -> CLLocation? {
|
||||
guard let latitude = notification.eqn_doubleValue(for: "latitude"),
|
||||
let longitude = notification.eqn_doubleValue(for: "longitude") else {
|
||||
return nil
|
||||
}
|
||||
return CLLocation(latitude: latitude, longitude: longitude)
|
||||
}
|
||||
}
|
||||
@@ -130,14 +130,11 @@
|
||||
|
||||
- (void)inviaPosizioneServer
|
||||
{
|
||||
NSLog(@"URLPosizione %@", [EQNGeneratoreURLServer urlPosizione]);
|
||||
|
||||
[[ServerRequest defaultServerConnectionSingleton] inviaInformazioniAlServerWithURL:[EQNGeneratoreURLServer urlPosizione] richiesta:EQNTipoChiamataPosizione success:^(id result) {
|
||||
|
||||
NSLog(@"inviato");
|
||||
|
||||
} failure:^(NSError *errore) {
|
||||
|
||||
NSLog(@"[EQNUtility] Position saved on server");
|
||||
[self saveUserInfo];
|
||||
} failure:^(NSError *error) {
|
||||
NSLog(@"[EQNUtility] Unable to save position. Error: %@", error.localizedDescription);
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,10 @@
|
||||
{
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSData *data = [defaults objectForKey:keyName];
|
||||
if (!data) {
|
||||
NSLog(@"[EQNUtility] No array saved for key '%@'", keyName);
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&error];
|
||||
@@ -119,6 +123,10 @@
|
||||
{
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSData *data = [defaults objectForKey:keyName];
|
||||
if (!data) {
|
||||
NSLog(@"[EQNUtility] No dictionary saved for key '%@'", keyName);
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&error];
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
[userDefaults setBool:self.isAbilitato forKey:NOTIFICHE_ALLERA_SISMICA_ABILITATO];
|
||||
[userDefaults setObject:self.sismiDaNotificare forKey:NOTIFICHE_ALLERA_SISMICA_SISMI_DA_NOTIFICARE];
|
||||
[userDefaults setObject:self.raggioSismiLievi forKey:NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_LIEVI];
|
||||
[userDefaults setObject:self.raggioSismiLievi forKey:NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_FORTI];
|
||||
[userDefaults setObject:self.raggioSismiForti forKey:NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_FORTI];
|
||||
[userDefaults setBool:self.isintervalloAllarme forKey:NOTIFICHE_ALLERA_SISMICA_ABILITA_INTERVALLO];
|
||||
[userDefaults setObject:self.oraioInizio forKey:NOTIFICHE_ALLERA_SISMICA_ORA_INIZIO];
|
||||
[userDefaults setObject:self.orarioFine forKey:NOTIFICHE_ALLERA_SISMICA_ORA_FINE];
|
||||
|
||||
@@ -137,6 +137,7 @@
|
||||
case EQNTipoChiamataRilevamento:
|
||||
onSuccess([EQNUtility clearStringMessaggi:newStr]);
|
||||
break;
|
||||
case EQNTipoChiamataPosizione:
|
||||
case EQNTipoChiamataCalibrazione:
|
||||
case EQNTipoChiamataImpostazioniNotifiche:
|
||||
case EQNTipoChiamataAlertSimulator:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -61,9 +61,9 @@ class EQNBlurredCloseButton: UIButton {
|
||||
|
||||
/// Add constaints to show the button on the upper right corner
|
||||
func addDefaultConstraint(to view: UIView) {
|
||||
leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10.0).isActive = true
|
||||
trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10.0).isActive = true
|
||||
topAnchor.constraint(equalTo: view.topAnchor, constant: 10.0).isActive = true
|
||||
widthAnchor.constraint(equalTo: heightAnchor).isActive = true
|
||||
heightAnchor.constraint(equalToConstant: 40.0).isActive = true
|
||||
heightAnchor.constraint(equalToConstant: 34.0).isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
+51
-51
@@ -1,90 +1,90 @@
|
||||
PODS:
|
||||
- DZNEmptyDataSet (1.8.1)
|
||||
- Firebase/Core (9.0.0):
|
||||
- Firebase/Core (9.1.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (~> 9.0.0)
|
||||
- Firebase/CoreOnly (9.0.0):
|
||||
- FirebaseCore (= 9.0.0)
|
||||
- Firebase/Crashlytics (9.0.0):
|
||||
- FirebaseAnalytics (~> 9.1.0)
|
||||
- Firebase/CoreOnly (9.1.0):
|
||||
- FirebaseCore (= 9.1.0)
|
||||
- Firebase/Crashlytics (9.1.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseCrashlytics (~> 9.0.0)
|
||||
- Firebase/Messaging (9.0.0):
|
||||
- FirebaseCrashlytics (~> 9.1.0)
|
||||
- Firebase/Messaging (9.1.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 9.0.0)
|
||||
- FirebaseAnalytics (9.0.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 9.0.0)
|
||||
- FirebaseMessaging (~> 9.1.0)
|
||||
- FirebaseAnalytics (9.1.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 9.1.0)
|
||||
- FirebaseCore (~> 9.0)
|
||||
- FirebaseInstallations (~> 9.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseAnalytics/AdIdSupport (9.0.0):
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseAnalytics/AdIdSupport (9.1.0):
|
||||
- FirebaseCore (~> 9.0)
|
||||
- FirebaseInstallations (~> 9.0)
|
||||
- GoogleAppMeasurement (= 9.0.0)
|
||||
- GoogleAppMeasurement (= 9.1.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseCore (9.0.0):
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseCore (9.1.0):
|
||||
- FirebaseCoreDiagnostics (~> 9.0)
|
||||
- FirebaseCoreInternal (~> 9.0)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/Logger (~> 7.7)
|
||||
- FirebaseCoreDiagnostics (9.0.0):
|
||||
- GoogleDataTransport (~> 9.1)
|
||||
- FirebaseCoreDiagnostics (9.1.0):
|
||||
- GoogleDataTransport (< 10.0.0, >= 9.1.4)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/Logger (~> 7.7)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseCoreInternal (9.0.0):
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseCoreInternal (9.1.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- FirebaseCrashlytics (9.0.0):
|
||||
- FirebaseCrashlytics (9.1.0):
|
||||
- FirebaseCore (~> 9.0)
|
||||
- FirebaseInstallations (~> 9.0)
|
||||
- GoogleDataTransport (~> 9.1)
|
||||
- GoogleDataTransport (< 10.0.0, >= 9.1.4)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- PromisesObjC (~> 2.1)
|
||||
- FirebaseInstallations (9.0.0):
|
||||
- FirebaseInstallations (9.1.0):
|
||||
- FirebaseCore (~> 9.0)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/UserDefaults (~> 7.7)
|
||||
- PromisesObjC (~> 2.1)
|
||||
- FirebaseMessaging (9.0.0):
|
||||
- FirebaseMessaging (9.1.0):
|
||||
- FirebaseCore (~> 9.0)
|
||||
- FirebaseInstallations (~> 9.0)
|
||||
- GoogleDataTransport (~> 9.1)
|
||||
- GoogleDataTransport (< 10.0.0, >= 9.1.4)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/Reachability (~> 7.7)
|
||||
- GoogleUtilities/UserDefaults (~> 7.7)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- Google-Mobile-Ads-SDK (9.4.0):
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- Google-Mobile-Ads-SDK (9.6.0):
|
||||
- GoogleAppMeasurement (< 10.0, >= 7.0)
|
||||
- GoogleUserMessagingPlatform (>= 1.1)
|
||||
- GoogleAppMeasurement (9.0.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 9.0.0)
|
||||
- GoogleAppMeasurement (9.1.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 9.1.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleAppMeasurement/AdIdSupport (9.0.0):
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 9.0.0)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- GoogleAppMeasurement/AdIdSupport (9.1.0):
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 9.1.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (9.0.0):
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (9.1.0):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- GoogleDataTransport (9.1.4):
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
@@ -109,11 +109,11 @@ PODS:
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/UserDefaults (7.7.0):
|
||||
- GoogleUtilities/Logger
|
||||
- nanopb (2.30908.0):
|
||||
- nanopb/decode (= 2.30908.0)
|
||||
- nanopb/encode (= 2.30908.0)
|
||||
- nanopb/decode (2.30908.0)
|
||||
- nanopb/encode (2.30908.0)
|
||||
- nanopb (2.30909.0):
|
||||
- nanopb/decode (= 2.30909.0)
|
||||
- nanopb/encode (= 2.30909.0)
|
||||
- nanopb/decode (2.30909.0)
|
||||
- nanopb/encode (2.30909.0)
|
||||
- PromisesObjC (2.1.0)
|
||||
- Solar (2.1.0)
|
||||
|
||||
@@ -147,20 +147,20 @@ SPEC REPOS:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
DZNEmptyDataSet: 9525833b9e68ac21c30253e1d3d7076cc828eaa7
|
||||
Firebase: a876fadc5ea653a377693376fd4f885c62704512
|
||||
FirebaseAnalytics: ea4f6f4b604a20b4de4d3c7f7a2cb51d9a989040
|
||||
FirebaseCore: e4c0b5d9727eaee0b43f9ed00baff7500c188d7b
|
||||
FirebaseCoreDiagnostics: 54410e5d156bf406a764c2722d9f77d682723b4c
|
||||
FirebaseCoreInternal: 5b8f4f2e2970a4cb9bd1cf7ada16c8ba69a29530
|
||||
FirebaseCrashlytics: 08561398868790fc9694b85efb4c080940926fcc
|
||||
FirebaseInstallations: e693c0dfe404af44afbd553de42498b2ca1ca189
|
||||
FirebaseMessaging: 411a61cde991cbd00b5b11c7a25e0c8f28c44990
|
||||
Google-Mobile-Ads-SDK: 5a1d44987c82e441811ecaa5ae824e100ea819d7
|
||||
GoogleAppMeasurement: 2c2792d43ebdea0524adbc90cba9139721f3039b
|
||||
Firebase: 91c243d75573ac6e7c9735ec859b72bffb61347d
|
||||
FirebaseAnalytics: bf11064790ac96804df1df9ddc0ae45af950d9fc
|
||||
FirebaseCore: b7bfc258e996eada23b3666bd6b9a22ca092acb8
|
||||
FirebaseCoreDiagnostics: 2dabba3412b23b524823325739f45e520f67d1e7
|
||||
FirebaseCoreInternal: f3c838ae0b41cd840bbf34f90debfede78d352e5
|
||||
FirebaseCrashlytics: 8e21736dcf15d814b79229eb7e79ba3a5eec5f30
|
||||
FirebaseInstallations: a91c74276b544524ce144c8315d8cdbce2dbe30b
|
||||
FirebaseMessaging: 0bf5caa621182ccc66ba3be3b15e68d800d98e9f
|
||||
Google-Mobile-Ads-SDK: bdf13d37aa77e368510687b5305d4972b4f9e9c7
|
||||
GoogleAppMeasurement: 8ecc717f2abe3f9ee95a5d38db08827852894acc
|
||||
GoogleDataTransport: 5fffe35792f8b96ec8d6775f5eccd83c998d5a3b
|
||||
GoogleUserMessagingPlatform: ab890ce5f6620f293a21b6bdd82e416a2c73aeca
|
||||
GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1
|
||||
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
|
||||
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
|
||||
PromisesObjC: 99b6f43f9e1044bd87a95a60beff28c2c44ddb72
|
||||
Solar: 2dc6e7cc39186cb0c8228fa08df76fb50c7d8f24
|
||||
|
||||
|
||||
Reference in New Issue
Block a user