Compare commits

...

27 Commits

Author SHA1 Message Date
Andrea Busi ff2f6e1e5a release: Increase version for release 2021-02-25 19:47:20 +01:00
Andrea Busi c10000df53 fix: Retry server registration if fails
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/30
2021-02-24 21:05:50 +01:00
Andrea Busi 6e6f1bed17 feat: Use native ads in seismics section
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/22
2021-02-21 20:56:12 +01:00
Andrea Busi c77a31e322 refactor: Remove no longer used EQNAdsUtility class 2021-02-21 20:56:12 +01:00
Andrea Busi 47db205135 refactor: Use adaptive banners in maps
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/22
2021-02-21 20:56:05 +01:00
Andrea Busi 5ab30c139f refactor: Rename ReteSismicaAnnotation in EQNMapAnnotationSeismicNetwork 2021-02-21 20:56:05 +01:00
Andrea Busi 852e950428 refactor: Rename PastquakesAnnotation in EQNMapAnnotationPastquakes 2021-02-21 20:56:05 +01:00
Andrea Busi e882a83694 refactor: Rewrite seismic map in Swift and rename its annotation model 2021-02-21 20:56:05 +01:00
Andrea Busi 0d26e641d7 refactor: Improve NSNotification definition to be Swift friendly 2021-02-21 20:56:05 +01:00
Andrea Busi 4c6a07c9d0 refactor: Use adaptive banners in main controllers
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/22
2021-02-21 20:55:51 +01:00
Andrea Busi fe38921f23 fix: Use test ads during debug 2021-02-21 20:54:12 +01:00
Andrea Busi 118991feea dependency: Add missing SKAdNetworkItems in info.plist for GoogleMobileAds 2021-02-21 20:52:07 +01:00
Andrea Busi a87750f380 dependency: Add -ObjC flag to let GoogleMobileAds works 2021-02-21 20:52:07 +01:00
Andrea Busi cb8ee2cb67 dependency: Update Pods 2021-02-21 20:52:07 +01:00
Andrea Busi 787cd8b4e7 refactor: Rename some constants 2021-02-21 20:51:28 +01:00
Andrea Busi 64ec53e6f8 refactor: Remove unused method to validate app receipt 2021-02-21 20:50:55 +01:00
Andrea Busi 2df5342da2 chore: Remove old xcuserdata from versioning 2020-12-18 22:00:26 +01:00
Andrea Busi d8fdba5e4f release: Increase version for release 2020-12-08 16:20:10 +01:00
Andrea Busi a05e186275 refactor: Rewrite EQNReteSmartphone model in Swift and use proper types for properties 2020-12-08 16:20:10 +01:00
Andrea Busi 7730da5faa dependency: Update Pods 2020-12-07 09:57:27 +01:00
Andrea Busi 9844dc9ac2 fix: Add missing return 2020-12-07 09:57:27 +01:00
Andrea Busi a9f16bca4a refactor: Reorganise code related to background monitoring
- Move to Models folder
- Improve code and nullability notation
- Rename class with typo in name
2020-12-07 09:46:43 +01:00
Andrea Busi 5612768d7f refactor: Remove useless imports 2020-12-07 09:46:43 +01:00
Andrea Busi ad1487afdf feat: Add server request to register in-app purchase
Resolves: https://gitlab.steamware.net/eqn/eqn.ios/-/issues/29
2020-12-07 09:46:24 +01:00
Andrea Busi f707186dea refactor: Show restored product in alert 2020-12-02 21:16:10 +01:00
Andrea Busi 24f63c7d4b feat: Add message if no subscriptions are available to restore 2020-12-02 21:16:10 +01:00
Andrea Busi 9678040d51 refactor: Improve log in in-app purchase manager 2020-12-02 21:16:10 +01:00
79 changed files with 1967 additions and 1219 deletions
+20
View File
@@ -1,5 +1,25 @@
# Changelog
## Versione 3.3
### Build (52)
- Aggiunta gestione in caso di fallita registrazione iniziale al server
### Build (51)
- Utilizzati adaptive e native banner
- Aggiornate dipendenze
- Rimosso codice non utilizzato
## Versione 3.2.1
### Build (50)
- Aggiunta chiamata per registrazione acquisto
- Rivisto modell EQNReteSmartphone
### Build (49)
- Aggiunta indicazione prodotto ripristinato
- Aggiunto messaggio se nessun prodotto da ripristinare
## Versione 3.2.0
### Build (48)
@@ -7,8 +7,8 @@
//
#import "NotificationViewController.h"
#import "PastquakesAnnotation.h"
#import "ReteSismicaAnnotation.h"
#import "EQNMapAnnotationPastquakes.h"
#import "EQNMapAnnotationSeismicNetwork.h"
#import "EQNUtility.h"
@import UserNotifications;
@@ -61,13 +61,13 @@
[self.mapView setRegion:region animated:YES];
if ([userInfo[@"type"] isEqualToString:@"eqn"]) {
PastquakesAnnotation *annotation = [[PastquakesAnnotation alloc] initWithTitle:content.body
EQNMapAnnotationPastquakes *annotation = [[EQNMapAnnotationPastquakes alloc] initWithTitle:content.body
location:coordinate.coordinate
intensita:[userInfo[@"intensity"] intValue]];
[self.mapView addAnnotation:annotation];
} else if ([userInfo[@"type"] isEqualToString:@"manual"]){
ReteSismicaAnnotation *annotation = [[ReteSismicaAnnotation alloc] initWithTitle:content.body
EQNMapAnnotationSeismicNetwork *annotation = [[EQNMapAnnotationSeismicNetwork alloc] initWithTitle:content.body
location:coordinate.coordinate
magnitudo:[userInfo[@"magnitudo"] intValue]];
[self.mapView addAnnotation:annotation];
@@ -139,9 +139,9 @@
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[PastquakesAnnotation class]]) {
PastquakesAnnotation *anLocation = (PastquakesAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_PASTQUAKES];
if ([annotation isKindOfClass:[EQNMapAnnotationPastquakes class]]) {
EQNMapAnnotationPastquakes *anLocation = (EQNMapAnnotationPastquakes *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:EQNMapAnnotationPastquakesIdentifier];
if (annotationView == nil) {
annotationView = anLocation.annotationView;
} else {
@@ -149,9 +149,9 @@
}
return annotationView;
} else if ([annotation isKindOfClass:[ReteSismicaAnnotation class]]) {
ReteSismicaAnnotation *anLocation = (ReteSismicaAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_RETESMARTPHONE];
} else if ([annotation isKindOfClass:[EQNMapAnnotationSeismicNetwork class]]) {
EQNMapAnnotationSeismicNetwork *anLocation = (EQNMapAnnotationSeismicNetwork *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:EQNMapAnnotationSeismicNetworkIdentifier];
if (annotationView == nil) {
annotationView = anLocation.annotationView;
} else {
@@ -7,18 +7,20 @@
objects = {
/* Begin PBXBuildFile section */
6525A82625E13FD4008FE0D0 /* SeismicNetworkAdvertiseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6525A82525E13FD4008FE0D0 /* SeismicNetworkAdvertiseTableViewCell.swift */; };
65DBFB4B25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DBFB4A25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift */; };
65DBFB5F25E2A5010041CBA6 /* EQNMapAnnotationPastquakes.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C602249218EDBE200C799C2 /* EQNMapAnnotationPastquakes.m */; };
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 */; };
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 */; };
8C14113121ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113021ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m */; };
8C14113721EE502800A59729 /* EQNAllertaSismica.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C14113621EE502800A59729 /* EQNAllertaSismica.m */; };
8C2B251121938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2B251021938BFD00E0E25E /* SegnalazioniUtenteDettagliMappa.m */; };
8C2B25142193927E00E0E25E /* ReteSismiDettagliMappa.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2B25132193927E00E0E25E /* ReteSismiDettagliMappa.m */; };
8C465D9A21F653AB00F04673 /* Assets.xcassets in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CBD3DD12149B9AD0070C963 /* Assets.xcassets */; };
8C465D9B21F653CA00F04673 /* Assets.xcassets in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CBD3DD12149B9AD0070C963 /* Assets.xcassets */; };
8C465D9C21F7BBE700F04673 /* PastquakesAnnotation.m in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C602249218EDBE200C799C2 /* PastquakesAnnotation.m */; };
8C465D9D21F7BBE700F04673 /* PastquakesAnnotation.h in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C602248218EDBE200C799C2 /* PastquakesAnnotation.h */; };
8C465D9E21F7BD8700F04673 /* PastquakesAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C602249218EDBE200C799C2 /* PastquakesAnnotation.m */; };
8C465D9F21F7BE0600F04673 /* Assets.xcassets in Sources */ = {isa = PBXBuildFile; fileRef = 8CBD3DD12149B9AD0070C963 /* Assets.xcassets */; };
8C483CAE21FDA53B00259FD2 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C483CAD21FDA53B00259FD2 /* StoreKit.framework */; };
8C483CB821FDACD300259FD2 /* IAPHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C483CB721FDACD300259FD2 /* IAPHelper.swift */; };
@@ -28,20 +30,20 @@
8C4DD4F9228237E000AE77ED /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C4DD4FB228237E000AE77ED /* InfoPlist.strings */; };
8C4E343F215012FA008B0D2A /* EQNManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C4E343E215012FA008B0D2A /* EQNManager.m */; };
8C4E34422152B5E8008B0D2A /* EQNRilevamento.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C4E34412152B5E8008B0D2A /* EQNRilevamento.m */; };
8C4E34452152B707008B0D2A /* EQMAccelerometroManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C4E34442152B707008B0D2A /* EQMAccelerometroManager.m */; };
8C4E34452152B707008B0D2A /* EQNAccelerometroManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C4E34442152B707008B0D2A /* EQNAccelerometroManager.m */; };
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 */; };
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 */; };
8C60224A218EDBE200C799C2 /* EQNMapAnnotationPastquakes.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C602249218EDBE200C799C2 /* EQNMapAnnotationPastquakes.m */; };
8C6CBAE521597E79005C426A /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8C6CBAE421597E79005C426A /* GoogleService-Info.plist */; };
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 */; };
8C7CD64821F7D0F800835812 /* EQNMapAnnotationSeismicNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD08637218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.m */; };
8C7CD64921F7D11700835812 /* EQNMapAnnotationSeismicNetwork.m in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CD08637218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.m */; };
8C7CD64A21F7D11700835812 /* EQNMapAnnotationSeismicNetwork.h in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CD08636218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.h */; };
8C8EBBA721540039002784BA /* EQNUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C8EBBA621540039002784BA /* EQNUser.m */; };
8CA46BA12194532E00C63C16 /* SismaAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CA46BA02194532E00C63C16 /* SismaAnnotation.m */; };
8CA46BA12194532E00C63C16 /* EQNMapAnnotationSeismic.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CA46BA02194532E00C63C16 /* EQNMapAnnotationSeismic.m */; };
8CADAA9421B2627D0044E256 /* LogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CADAA9321B2627D0044E256 /* LogViewController.m */; };
8CAFD7C521825E4A00F8BD29 /* EQNSisma.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CAFD7C421825E4A00F8BD29 /* EQNSisma.m */; };
8CBD3DC72149B9AD0070C963 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CBD3DC62149B9AD0070C963 /* AppDelegate.m */; };
@@ -56,7 +58,7 @@
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 */; };
8CD08638218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD08637218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.m */; };
8CF05B51218C41FB0055012B /* PickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF05B4B218C41F90055012B /* PickerViewController.m */; };
8CF05B53218C41FB0055012B /* PickerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8CF05B4F218C41FA0055012B /* PickerViewController.xib */; };
8CF05B57218C93BA0055012B /* EQNUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF05B56218C93BA0055012B /* EQNUtility.m */; };
@@ -65,7 +67,6 @@
8CF12CD921DE49B600613AC5 /* NotificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF12CD821DE49B600613AC5 /* NotificationViewController.m */; };
8CF12CDC21DE49B600613AC5 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8CF12CDA21DE49B600613AC5 /* MainInterface.storyboard */; };
8CF12CE021DE49B600613AC5 /* EQNNotificationContent.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 8CF12CD121DE49B600613AC5 /* EQNNotificationContent.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
8CF4F4D2216D2C780057110B /* EQNReteSmartphone.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF4F4D1216D2C780057110B /* EQNReteSmartphone.m */; };
8CF4F4D8216D3A110057110B /* EQNAreaCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF4F4D7216D3A110057110B /* EQNAreaCheck.m */; };
8CF4F4DB216D44930057110B /* EQNPastquakes.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF4F4DA216D44930057110B /* EQNPastquakes.m */; };
8CF6604F214C0E58009F4314 /* EQNCalibrazione.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF6604E214C0E58009F4314 /* EQNCalibrazione.m */; };
@@ -76,7 +77,6 @@
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 */; };
DC0AE1A325381D4100111307 /* EQNAdsUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0AE1A225381D4100111307 /* EQNAdsUtility.m */; };
DC0AE1B52538202300111307 /* EQNUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF05B56218C93BA0055012B /* EQNUtility.m */; };
DC0AE1B92538204100111307 /* EQNSegnalazione.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C593E89217BA2470008B260 /* EQNSegnalazione.m */; };
DC0AE1BA2538204100111307 /* EQNPastquakes.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF4F4DA216D44930057110B /* EQNPastquakes.m */; };
@@ -86,6 +86,7 @@
DC2814302519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC28142F2519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift */; };
DC2814382519C56100C1AFF7 /* SeismicNetworksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2814372519C56100C1AFF7 /* SeismicNetworksViewController.swift */; };
DC30BC882534DBBD0041B23B /* star_white1.png in Resources */ = {isa = PBXBuildFile; fileRef = DC30BC872534DBBD0041B23B /* star_white1.png */; };
DC3B5429257FCBCA00C0B6A5 /* EQNReteSmartphone.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3B5428257FCBCA00C0B6A5 /* EQNReteSmartphone.swift */; };
DC3BA11124D1A9C90062EE7F /* SubscriptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3BA11024D1A9C90062EE7F /* SubscriptionsViewController.swift */; };
DC3CE50A250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3CE509250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift */; };
DC47D1BC252A0C2B004119F6 /* AlertsPastEartquakesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC47D1BB252A0C2B004119F6 /* AlertsPastEartquakesTableViewCell.swift */; };
@@ -272,6 +273,13 @@
/* Begin PBXFileReference section */
25A8BFFE29D46740E8A8A7A3 /* Pods_Earthquake_Network.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Earthquake_Network.framework; sourceTree = BUILT_PRODUCTS_DIR; };
40CD2E5581CF2FA3D52F392D /* Pods-Earthquake Network.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Earthquake Network.release.xcconfig"; path = "Pods/Target Support Files/Pods-Earthquake Network/Pods-Earthquake Network.release.xcconfig"; sourceTree = "<group>"; };
6525A82525E13FD4008FE0D0 /* SeismicNetworkAdvertiseTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworkAdvertiseTableViewCell.swift; sourceTree = "<group>"; };
65DBFB4A25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworksMapDetailViewController.swift; sourceTree = "<group>"; };
65DBFB6F25E2BBF20041CBA6 /* GADTMediumTemplateView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GADTMediumTemplateView.xib; sourceTree = "<group>"; };
65DBFB7025E2BBF20041CBA6 /* GADTTemplateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GADTTemplateView.h; sourceTree = "<group>"; };
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>"; };
8C10B0AF2281FBE800125C9F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Main.strings; sourceTree = "<group>"; };
8C10B0B02281FBE800125C9F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
8C10B0B12281FBE800125C9F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/MainInterface.strings; sourceTree = "<group>"; };
@@ -288,8 +296,6 @@
8C14113621EE502800A59729 /* EQNAllertaSismica.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNAllertaSismica.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>"; };
8C2B25132193927E00E0E25E /* ReteSismiDettagliMappa.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReteSismiDettagliMappa.m; sourceTree = "<group>"; };
8C465D9721F6539700F04673 /* Earthquake Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = "Earthquake Network.xcodeproj"; sourceTree = "<group>"; };
8C483CAD21FDA53B00259FD2 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
8C483CB021FDA8C700259FD2 /* Earthquake Network-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Earthquake Network-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -308,8 +314,8 @@
8C4E343E215012FA008B0D2A /* EQNManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNManager.m; sourceTree = "<group>"; };
8C4E34402152B5E8008B0D2A /* EQNRilevamento.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNRilevamento.h; sourceTree = "<group>"; };
8C4E34412152B5E8008B0D2A /* EQNRilevamento.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNRilevamento.m; sourceTree = "<group>"; };
8C4E34432152B707008B0D2A /* EQMAccelerometroManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQMAccelerometroManager.h; sourceTree = "<group>"; };
8C4E34442152B707008B0D2A /* EQMAccelerometroManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQMAccelerometroManager.m; sourceTree = "<group>"; };
8C4E34432152B707008B0D2A /* EQNAccelerometroManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNAccelerometroManager.h; sourceTree = "<group>"; };
8C4E34442152B707008B0D2A /* EQNAccelerometroManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNAccelerometroManager.m; sourceTree = "<group>"; };
8C4E34492152EE5B008B0D2A /* EQNGeneratoreURLServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNGeneratoreURLServer.h; sourceTree = "<group>"; };
8C4E344A2152EE5B008B0D2A /* EQNGeneratoreURLServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNGeneratoreURLServer.m; sourceTree = "<group>"; };
8C593E88217BA2470008B260 /* EQNSegnalazione.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNSegnalazione.h; sourceTree = "<group>"; };
@@ -319,15 +325,15 @@
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>"; };
8C602245218D9DB200C799C2 /* PastquakesDettagliMappa.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PastquakesDettagliMappa.m; sourceTree = "<group>"; };
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>"; };
8C602248218EDBE200C799C2 /* EQNMapAnnotationPastquakes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNMapAnnotationPastquakes.h; sourceTree = "<group>"; };
8C602249218EDBE200C799C2 /* EQNMapAnnotationPastquakes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNMapAnnotationPastquakes.m; sourceTree = "<group>"; };
8C6CBAE421597E79005C426A /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; 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>"; };
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>"; };
8CA46B9F2194532E00C63C16 /* EQNMapAnnotationSeismic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNMapAnnotationSeismic.h; sourceTree = "<group>"; };
8CA46BA02194532E00C63C16 /* EQNMapAnnotationSeismic.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNMapAnnotationSeismic.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>"; };
@@ -353,8 +359,8 @@
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>"; };
8CD08636218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNMapAnnotationSeismicNetwork.h; sourceTree = "<group>"; };
8CD08637218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNMapAnnotationSeismicNetwork.m; sourceTree = "<group>"; };
8CF05B4B218C41F90055012B /* PickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PickerViewController.m; sourceTree = "<group>"; };
8CF05B4D218C41FA0055012B /* PickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PickerViewController.h; sourceTree = "<group>"; };
8CF05B4F218C41FA0055012B /* PickerViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PickerViewController.xib; sourceTree = "<group>"; };
@@ -367,8 +373,6 @@
8CF12CD821DE49B600613AC5 /* NotificationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationViewController.m; sourceTree = "<group>"; };
8CF12CDB21DE49B600613AC5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
8CF12CDD21DE49B600613AC5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8CF4F4D0216D2C780057110B /* EQNReteSmartphone.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNReteSmartphone.h; sourceTree = "<group>"; };
8CF4F4D1216D2C780057110B /* EQNReteSmartphone.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNReteSmartphone.m; sourceTree = "<group>"; };
8CF4F4D6216D3A110057110B /* EQNAreaCheck.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNAreaCheck.h; sourceTree = "<group>"; };
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>"; };
@@ -386,14 +390,13 @@
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>"; };
DC0AE1A125381D4100111307 /* EQNAdsUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQNAdsUtility.h; sourceTree = "<group>"; };
DC0AE1A225381D4100111307 /* EQNAdsUtility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQNAdsUtility.m; 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>"; };
DC30BC872534DBBD0041B23B /* star_white1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = star_white1.png; sourceTree = "<group>"; };
DC3B5428257FCBCA00C0B6A5 /* EQNReteSmartphone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNReteSmartphone.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>"; };
@@ -572,10 +575,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8C7CD64921F7D11700835812 /* ReteSismicaAnnotation.m in Frameworks */,
8C7CD64A21F7D11700835812 /* ReteSismicaAnnotation.h in Frameworks */,
8C465D9C21F7BBE700F04673 /* PastquakesAnnotation.m in Frameworks */,
8C465D9D21F7BBE700F04673 /* PastquakesAnnotation.h in Frameworks */,
8C7CD64921F7D11700835812 /* EQNMapAnnotationSeismicNetwork.m in Frameworks */,
8C7CD64A21F7D11700835812 /* EQNMapAnnotationSeismicNetwork.h in Frameworks */,
8C465D9A21F653AB00F04673 /* Assets.xcassets in Frameworks */,
8CF12CD521DE49B600613AC5 /* UserNotificationsUI.framework in Frameworks */,
8CF12CD321DE49B600613AC5 /* UserNotifications.framework in Frameworks */,
@@ -585,6 +586,31 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
65DBFB5225E2A2580041CBA6 /* Map annotation */ = {
isa = PBXGroup;
children = (
8CA46B9F2194532E00C63C16 /* EQNMapAnnotationSeismic.h */,
8CA46BA02194532E00C63C16 /* EQNMapAnnotationSeismic.m */,
8C602248218EDBE200C799C2 /* EQNMapAnnotationPastquakes.h */,
8C602249218EDBE200C799C2 /* EQNMapAnnotationPastquakes.m */,
8CD08636218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.h */,
8CD08637218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.m */,
);
path = "Map annotation";
sourceTree = "<group>";
};
65DBFB7D25E2CB020041CBA6 /* Ad templates */ = {
isa = PBXGroup;
children = (
65DBFB7025E2BBF20041CBA6 /* GADTTemplateView.h */,
65DBFB7225E2BBF20041CBA6 /* GADTTemplateView.m */,
65DBFB7325E2BBF20041CBA6 /* GADTMediumTemplateView.h */,
65DBFB7125E2BBF20041CBA6 /* GADTMediumTemplateView.m */,
65DBFB6F25E2BBF20041CBA6 /* GADTMediumTemplateView.xib */,
);
path = "Ad templates";
sourceTree = "<group>";
};
8C465D9821F6539700F04673 /* Products */ = {
isa = PBXGroup;
children = (
@@ -628,19 +654,6 @@
path = "Dettagli mappa";
sourceTree = "<group>";
};
8C60224B218EDBF700C799C2 /* annotation */ = {
isa = PBXGroup;
children = (
8CD08636218B3BEE0000CB5E /* ReteSismicaAnnotation.h */,
8CD08637218B3BEE0000CB5E /* ReteSismicaAnnotation.m */,
8C602248218EDBE200C799C2 /* PastquakesAnnotation.h */,
8C602249218EDBE200C799C2 /* PastquakesAnnotation.m */,
8CA46B9F2194532E00C63C16 /* SismaAnnotation.h */,
8CA46BA02194532E00C63C16 /* SismaAnnotation.m */,
);
path = annotation;
sourceTree = "<group>";
};
8CBD3DB92149B9AD0070C963 = {
isa = PBXGroup;
children = (
@@ -723,17 +736,8 @@
8CF66049214C09E0009F4314 /* model */ = {
isa = PBXGroup;
children = (
8C60224B218EDBF700C799C2 /* annotation */,
8C4E343D215012FA008B0D2A /* EQNManager.h */,
8C4E343E215012FA008B0D2A /* EQNManager.m */,
8CF66051214C12DC009F4314 /* EQNMath.h */,
8CF66052214C12DC009F4314 /* EQNMath.m */,
8C4E34432152B707008B0D2A /* EQMAccelerometroManager.h */,
8C4E34442152B707008B0D2A /* EQMAccelerometroManager.m */,
8CF6604D214C0E58009F4314 /* EQNCalibrazione.h */,
8CF6604E214C0E58009F4314 /* EQNCalibrazione.m */,
8C4E34402152B5E8008B0D2A /* EQNRilevamento.h */,
8C4E34412152B5E8008B0D2A /* EQNRilevamento.m */,
8CF4F4D9216D44930057110B /* EQNPastquakes.h */,
8CF4F4DA216D44930057110B /* EQNPastquakes.m */,
8C593E88217BA2470008B260 /* EQNSegnalazione.h */,
@@ -770,8 +774,7 @@
DC65B390250F243E00251693 /* SeismicSettingsNetworksViewController.swift */,
DC2814372519C56100C1AFF7 /* SeismicNetworksViewController.swift */,
DCC76BD7251F56050005C4DC /* SeismicCardSettingsViewController.swift */,
8C2B25122193927E00E0E25E /* ReteSismiDettagliMappa.h */,
8C2B25132193927E00E0E25E /* ReteSismiDettagliMappa.m */,
65DBFB4A25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift */,
);
path = "Seismic Networks";
sourceTree = "<group>";
@@ -779,7 +782,9 @@
DC28142E2519C21400C1AFF7 /* Cells */ = {
isa = PBXGroup;
children = (
65DBFB7D25E2CB020041CBA6 /* Ad templates */,
DC28142F2519C24400C1AFF7 /* SeismicNetworkTableViewCell.swift */,
6525A82525E13FD4008FE0D0 /* SeismicNetworkAdvertiseTableViewCell.swift */,
);
path = Cells;
sourceTree = "<group>";
@@ -893,6 +898,21 @@
path = Icons;
sourceTree = "<group>";
};
DC3640DF257E19A00037A4B7 /* Monitoring */ = {
isa = PBXGroup;
children = (
8CF66051214C12DC009F4314 /* EQNMath.h */,
8CF66052214C12DC009F4314 /* EQNMath.m */,
8C4E34432152B707008B0D2A /* EQNAccelerometroManager.h */,
8C4E34442152B707008B0D2A /* EQNAccelerometroManager.m */,
8CF6604D214C0E58009F4314 /* EQNCalibrazione.h */,
8CF6604E214C0E58009F4314 /* EQNCalibrazione.m */,
8C4E34402152B5E8008B0D2A /* EQNRilevamento.h */,
8C4E34412152B5E8008B0D2A /* EQNRilevamento.m */,
);
path = Monitoring;
sourceTree = "<group>";
};
DC3ADD2A24CB1E6600737919 /* Supporting Files */ = {
isa = PBXGroup;
children = (
@@ -1020,9 +1040,11 @@
DCB6FBE924D0B0DF00ED23B8 /* Models */ = {
isa = PBXGroup;
children = (
DC3640DF257E19A00037A4B7 /* Monitoring */,
DCF9E15024F6EA0B002B6B1D /* Networks */,
DC99A50124E66DFB0071BC9F /* Commands */,
DCEFF21824F587CC009D3FE1 /* Settings */,
65DBFB5225E2A2580041CBA6 /* Map annotation */,
8C483CBB21FDACE500259FD2 /* VersioneProProducts.swift */,
8C483CB721FDACD300259FD2 /* IAPHelper.swift */,
DCF10DC524D2B8C7009F34C3 /* EQNPurchaseUtility.swift */,
@@ -1032,15 +1054,12 @@
DC4B67602517833F00634277 /* EQNSeismic.swift */,
8CAFD7C321825E4A00F8BD29 /* EQNSisma.h */,
8CAFD7C421825E4A00F8BD29 /* EQNSisma.m */,
DC0AE1A125381D4100111307 /* EQNAdsUtility.h */,
DC0AE1A225381D4100111307 /* EQNAdsUtility.m */,
8CF05B55218C93BA0055012B /* EQNUtility.h */,
8CF05B56218C93BA0055012B /* EQNUtility.m */,
DCF0188E252F09C500C783F0 /* EQNUtility+Extensions.swift */,
8C8EBBA521540039002784BA /* EQNUser.h */,
8C8EBBA621540039002784BA /* EQNUser.m */,
8CF4F4D0216D2C780057110B /* EQNReteSmartphone.h */,
8CF4F4D1216D2C780057110B /* EQNReteSmartphone.m */,
DC3B5428257FCBCA00C0B6A5 /* EQNReteSmartphone.swift */,
8CF4F4D6216D3A110057110B /* EQNAreaCheck.h */,
8CF4F4D7216D3A110057110B /* EQNAreaCheck.m */,
);
@@ -1392,6 +1411,7 @@
DC958D672535788E00D73D4A /* alert_sound.wav in Resources */,
8CBD3DD22149B9AD0070C963 /* Assets.xcassets in Resources */,
8CF05B53218C41FB0055012B /* PickerViewController.xib in Resources */,
65DBFB7425E2BBF20041CBA6 /* GADTMediumTemplateView.xib in Resources */,
DCB6FBEC24D0B40600ED23B8 /* Colors.xcassets in Resources */,
8CBD3DCD2149B9AD0070C963 /* Main.storyboard in Resources */,
);
@@ -1503,6 +1523,7 @@
buildActionMask = 2147483647;
files = (
DCEFF21324F5821E009D3FE1 /* SettingDetailTableViewCell.swift in Sources */,
DC3B5429257FCBCA00C0B6A5 /* EQNReteSmartphone.swift in Sources */,
DCC23DEF24D28F58003A2404 /* EQNEdgeInsetLabel.swift in Sources */,
DCF0188F252F09C500C783F0 /* EQNUtility+Extensions.swift in Sources */,
8CCE165121E7BAEC00173CD9 /* EQNNotificheReteSismiche.m in Sources */,
@@ -1516,7 +1537,9 @@
DC4B67612517833F00634277 /* EQNSeismic.swift in Sources */,
DCF0188A252F055800C783F0 /* AlertsPositionDataTableViewCell.swift in Sources */,
DCBB267E24D1EA2000F04559 /* SubscriptionProductTableViewCell.swift in Sources */,
6525A82625E13FD4008FE0D0 /* SeismicNetworkAdvertiseTableViewCell.swift in Sources */,
DC99A50524E66E430071BC9F /* EQNAppearanceCommand.swift in Sources */,
65DBFB7525E2BBF20041CBA6 /* GADTMediumTemplateView.m in Sources */,
DC03BEAB250BC0A60084769B /* EQNRoundedButton.swift in Sources */,
8CCE164E21E7BACE00173CD9 /* EQNNotificheSegnalazioniUtente.m in Sources */,
DCD4571C24F6CF0D00B58304 /* EQNGenericValue.swift in Sources */,
@@ -1532,7 +1555,7 @@
DC99A50724E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift in Sources */,
DCA5B6E7252E4BD8002AEC96 /* EQNBaseTableViewCell.swift in Sources */,
8CF66058214C566B009F4314 /* ServerRequest.m in Sources */,
8CD08638218B3BEE0000CB5E /* ReteSismicaAnnotation.m in Sources */,
8CD08638218B3BEE0000CB5E /* EQNMapAnnotationSeismicNetwork.m in Sources */,
DCF9E14D24F6D1AA002B6B1D /* EQNData.swift in Sources */,
DC52B8A524FCCD6900ABEBA6 /* AppTheme.swift in Sources */,
DC27EB2F24F6EBE000ACBFE0 /* SettingsSeismicNetworksViewController.swift in Sources */,
@@ -1549,7 +1572,6 @@
8CF6604F214C0E58009F4314 /* EQNCalibrazione.m in Sources */,
DCBB84F0252CFC4600F12633 /* AlertsNoLocationTableViewCell.swift in Sources */,
DCD3E3C024D15576007C78D4 /* PurchaseProVersionViewController.swift in Sources */,
8C2B25142193927E00E0E25E /* ReteSismiDettagliMappa.m in Sources */,
8CF05B51218C41FB0055012B /* PickerViewController.m in Sources */,
DC99A50324E66E270071BC9F /* EQNCommandProtocol.swift in Sources */,
DCB45BC8250E86E100DB2D0C /* SeismicSettingsViewController.swift in Sources */,
@@ -1561,26 +1583,26 @@
8C14113121ED3E5B00A59729 /* SettingsRealTimeAlertsViewController.m in Sources */,
DCBB267A24D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift in Sources */,
DC65B391250F243E00251693 /* SeismicSettingsNetworksViewController.swift in Sources */,
8CF4F4D2216D2C780057110B /* EQNReteSmartphone.m in Sources */,
65DBFB4B25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift in Sources */,
DC08804124F5B41400186D97 /* SettingSliderTableViewCell.swift in Sources */,
8CBD3DD82149B9AD0070C963 /* main.m in Sources */,
8CF05B57218C93BA0055012B /* EQNUtility.m in Sources */,
8C4E34422152B5E8008B0D2A /* EQNRilevamento.m in Sources */,
8C7A3B66225A5EA40045B266 /* NSDictionary+EQNExtensions.m in Sources */,
8CF66053214C12DC009F4314 /* EQNMath.m in Sources */,
DC0AE1A325381D4100111307 /* EQNAdsUtility.m in Sources */,
DCF4A54524F8DB8300B17326 /* SettingDateTableViewCell.swift in Sources */,
DC7EEE4A252A11C9004B4A2A /* AlertsSmartphoneNetworkTableViewCell.swift in Sources */,
DC7EEE4F252A1634004B4A2A /* AlertsPriorityServiceTableViewCell.swift in Sources */,
8C60224A218EDBE200C799C2 /* PastquakesAnnotation.m in Sources */,
8C60224A218EDBE200C799C2 /* EQNMapAnnotationPastquakes.m in Sources */,
65DBFB7625E2BBF20041CBA6 /* GADTTemplateView.m in Sources */,
8CC1B15A217CB09100F22178 /* DettagliMappaViewController.m in Sources */,
8C5EA23D2177B51C002DC156 /* SegnalazioniViewController.m in Sources */,
8CF4F4D8216D3A110057110B /* EQNAreaCheck.m in Sources */,
8C4E34452152B707008B0D2A /* EQMAccelerometroManager.m in Sources */,
8C4E34452152B707008B0D2A /* EQNAccelerometroManager.m in Sources */,
8CBD3DC72149B9AD0070C963 /* AppDelegate.m in Sources */,
DC974AFF251748B300A139EC /* SeismicFiltersViewController.swift in Sources */,
DC105641251E7ECE002579BB /* UIFont+Extensions.swift in Sources */,
8CA46BA12194532E00C63C16 /* SismaAnnotation.m in Sources */,
8CA46BA12194532E00C63C16 /* EQNMapAnnotationSeismic.m in Sources */,
DCB28CEE24FB8400001F557E /* SettingsViewController.swift in Sources */,
DCB528212560161C005288E5 /* AlertSimulatorViewController.swift in Sources */,
DCC76BD8251F56050005C4DC /* SeismicCardSettingsViewController.swift in Sources */,
@@ -1599,12 +1621,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8C7CD64821F7D0F800835812 /* ReteSismicaAnnotation.m in Sources */,
8C7CD64821F7D0F800835812 /* EQNMapAnnotationSeismicNetwork.m in Sources */,
8C465D9F21F7BE0600F04673 /* Assets.xcassets in Sources */,
DC0AE1B92538204100111307 /* EQNSegnalazione.m in Sources */,
65DBFB5F25E2A5010041CBA6 /* EQNMapAnnotationPastquakes.m in Sources */,
DC0AE1B52538202300111307 /* EQNUtility.m in Sources */,
DC0AE1BA2538204100111307 /* EQNPastquakes.m in Sources */,
8C465D9E21F7BD8700F04673 /* PastquakesAnnotation.m in Sources */,
8CF12CD921DE49B600613AC5 /* NotificationViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1683,12 +1705,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 48;
CURRENT_PROJECT_VERSION = 52;
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 = 3.2.0;
MARKETING_VERSION = 3.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1705,12 +1727,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 48;
CURRENT_PROJECT_VERSION = 52;
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 = 3.2.0;
MARKETING_VERSION = 3.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1843,14 +1865,97 @@
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 48;
CURRENT_PROJECT_VERSION = 52;
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 = 3.2.0;
MARKETING_VERSION = 3.3;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-l\"c++\"",
"-l\"sqlite3\"",
"-l\"z\"",
"-framework",
"\"AVFoundation\"",
"-framework",
"\"AudioToolbox\"",
"-framework",
"\"CFNetwork\"",
"-framework",
"\"CoreGraphics\"",
"-framework",
"\"CoreMedia\"",
"-framework",
"\"CoreTelephony\"",
"-framework",
"\"CoreVideo\"",
"-framework",
"\"DZNEmptyDataSet\"",
"-framework",
"\"FBLPromises\"",
"-framework",
"\"FirebaseAnalytics\"",
"-framework",
"\"FirebaseCore\"",
"-framework",
"\"FirebaseCoreDiagnostics\"",
"-framework",
"\"FirebaseCrashlytics\"",
"-framework",
"\"FirebaseInstallations\"",
"-framework",
"\"FirebaseInstanceID\"",
"-framework",
"\"FirebaseMessaging\"",
"-framework",
"\"Foundation\"",
"-framework",
"\"GoogleAppMeasurement\"",
"-framework",
"\"GoogleDataTransport\"",
"-framework",
"\"GoogleMobileAds\"",
"-framework",
"\"GoogleUtilities\"",
"-framework",
"\"MediaPlayer\"",
"-framework",
"\"MessageUI\"",
"-framework",
"\"MobileCoreServices\"",
"-framework",
"\"QuartzCore\"",
"-framework",
"\"Security\"",
"-framework",
"\"Solar\"",
"-framework",
"\"StoreKit\"",
"-framework",
"\"SystemConfiguration\"",
"-framework",
"\"UIKit\"",
"-framework",
"\"UserMessagingPlatform\"",
"-framework",
"\"WebKit\"",
"-framework",
"\"nanopb\"",
"-weak_framework",
"\"AdSupport\"",
"-weak_framework",
"\"JavaScriptCore\"",
"-weak_framework",
"\"SafariServices\"",
"-weak_framework",
"\"UserNotifications\"",
"-weak_framework",
"\"WebKit\"",
);
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@@ -1871,13 +1976,96 @@
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 48;
CURRENT_PROJECT_VERSION = 52;
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 = 3.2.0;
MARKETING_VERSION = 3.3;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-l\"c++\"",
"-l\"sqlite3\"",
"-l\"z\"",
"-framework",
"\"AVFoundation\"",
"-framework",
"\"AudioToolbox\"",
"-framework",
"\"CFNetwork\"",
"-framework",
"\"CoreGraphics\"",
"-framework",
"\"CoreMedia\"",
"-framework",
"\"CoreTelephony\"",
"-framework",
"\"CoreVideo\"",
"-framework",
"\"DZNEmptyDataSet\"",
"-framework",
"\"FBLPromises\"",
"-framework",
"\"FirebaseAnalytics\"",
"-framework",
"\"FirebaseCore\"",
"-framework",
"\"FirebaseCoreDiagnostics\"",
"-framework",
"\"FirebaseCrashlytics\"",
"-framework",
"\"FirebaseInstallations\"",
"-framework",
"\"FirebaseInstanceID\"",
"-framework",
"\"FirebaseMessaging\"",
"-framework",
"\"Foundation\"",
"-framework",
"\"GoogleAppMeasurement\"",
"-framework",
"\"GoogleDataTransport\"",
"-framework",
"\"GoogleMobileAds\"",
"-framework",
"\"GoogleUtilities\"",
"-framework",
"\"MediaPlayer\"",
"-framework",
"\"MessageUI\"",
"-framework",
"\"MobileCoreServices\"",
"-framework",
"\"QuartzCore\"",
"-framework",
"\"Security\"",
"-framework",
"\"Solar\"",
"-framework",
"\"StoreKit\"",
"-framework",
"\"SystemConfiguration\"",
"-framework",
"\"UIKit\"",
"-framework",
"\"UserMessagingPlatform\"",
"-framework",
"\"WebKit\"",
"-framework",
"\"nanopb\"",
"-weak_framework",
"\"AdSupport\"",
"-weak_framework",
"\"JavaScriptCore\"",
"-weak_framework",
"\"SafariServices\"",
"-weak_framework",
"\"UserNotifications\"",
"-weak_framework",
"\"WebKit\"",
);
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@@ -1893,12 +2081,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 48;
CURRENT_PROJECT_VERSION = 52;
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 = 3.2.0;
MARKETING_VERSION = 3.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationContent;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -1915,12 +2103,12 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 48;
CURRENT_PROJECT_VERSION = 52;
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 = 3.2.0;
MARKETING_VERSION = 3.3;
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.EQNNotificationContent;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Earthquake Network Extensions - Development";
@@ -50,6 +50,13 @@
ReferencedContainer = "container:Earthquake Network.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
<AdditionalOption
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "2.0">
</Bucket>
@@ -1,92 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8CBD3DC12149B9AD0070C963"
BuildableName = "Earthquake Network.app"
BlueprintName = "Earthquake Network"
ReferencedContainer = "container:Earthquake Network.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8CBD3DC12149B9AD0070C963"
BuildableName = "Earthquake Network.app"
BlueprintName = "Earthquake Network"
ReferencedContainer = "container:Earthquake Network.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = "it"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8CBD3DC12149B9AD0070C963"
BuildableName = "Earthquake Network.app"
BlueprintName = "Earthquake Network"
ReferencedContainer = "container:Earthquake Network.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8CBD3DC12149B9AD0070C963"
BuildableName = "Earthquake Network.app"
BlueprintName = "Earthquake Network"
ReferencedContainer = "container:Earthquake Network.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,47 +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>SchemeUserState</key>
<dict>
<key>EQNNotificationContent.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>6</integer>
</dict>
<key>EQNNotificationContent.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>6</integer>
</dict>
<key>EQNNotificationService.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
</dict>
<key>EQNNotificationService.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
</dict>
<key>Earthquake Network.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>NotificationService.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>8CBD3DC12149B9AD0070C963</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
@@ -1,18 +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>BuildLocationStyle</key>
<string>UseAppPreferences</string>
<key>CustomBuildLocationType</key>
<string>RelativeToDerivedData</string>
<key>DerivedDataLocationStyle</key>
<string>Default</string>
<key>EnabledFullIndexStoreVisibility</key>
<false/>
<key>IssueFilterStyle</key>
<string>ShowActiveSchemeOnly</string>
<key>LiveSourceIssuesEnabled</key>
<true/>
</dict>
</plist>
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "0"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "NotificationService/NotificationService.m"
timestampString = "566939074.092063"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "22"
endingLineNumber = "22"
landmarkName = "-didReceiveNotificationRequest:withContentHandler:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Earthquake Network/ViewController/impostazioniNotifiche/ManuTableViewController.m"
timestampString = "578957991.487044"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "178"
endingLineNumber = "178"
landmarkName = "-tableView:didSelectRowAtIndexPath:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Earthquake Network/model/EQNManager.m"
timestampString = "580927134.578099"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "215"
endingLineNumber = "215"
landmarkName = "-scaricaTempoDisponibile"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Earthquake Network/model/EQNGeneratoreURLServer.m"
timestampString = "581369763.523838"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "269"
endingLineNumber = "269"
landmarkName = "+urlInvioImpostazioniNotifiche"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Earthquake Network/ViewController/Dettagli mappa/DettagliMappaViewController.m"
timestampString = "586112158.88384"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "69"
endingLineNumber = "69"
landmarkName = "-setUpSegnalazioniUtente"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
+9 -5
View File
@@ -11,7 +11,7 @@
#import "ServerRequest.h"
#import "EQNGeneratoreURLServer.h"
#import "EQNUser.h"
#import "EQMAccelerometroManager.h"
#import "EQNAccelerometroManager.h"
#import "EQNManager.h"
#import "EQNUtility.h"
#import "EQNAllertaSismica.h"
@@ -31,6 +31,10 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef DEBUG
// Test ads on specific devices
GADMobileAds.sharedInstance.requestConfiguration.testDeviceIdentifiers = @[ @"81392581e1790d4fbc6eff919815088d" ];
#endif
// start 3rd party SDKs and custom managers
[GADMobileAds.sharedInstance startWithCompletionHandler:^(GADInitializationStatus *status) {
NSLog(@"[AppDelegate] GADMobileAds started with status: %@", status);
@@ -76,18 +80,18 @@
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
[[EQNManager defaultManager] avviaManager];
[[EQMAccelerometroManager sharedInstance] startUpdatingLocationBackground];
[[EQNAccelerometroManager sharedInstance] startUpdatingLocationBackground];
NSUInteger counter = [[NSUserDefaults standardUserDefaults] integerForKey:CONTEGGIO_APERTURE_PER_SCONTO];
NSUInteger counter = [[NSUserDefaults standardUserDefaults] integerForKey:EQNUserDefaultProDiscountOpenCounter];
counter += 1;
[[NSUserDefaults standardUserDefaults] setInteger:counter forKey:CONTEGGIO_APERTURE_PER_SCONTO];
[[NSUserDefaults standardUserDefaults] setInteger:counter forKey:EQNUserDefaultProDiscountOpenCounter];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
[[EQNManager defaultManager] stopManager];
[[EQMAccelerometroManager sharedInstance] stopUpdatingLocation];
[[EQNAccelerometroManager sharedInstance] stopUpdatingLocation];
}
@@ -12,9 +12,7 @@
#import "EQNGeneratoreURLServer.h"
#import "EQNManager.h"
#import "PastquakesDettagliMappa.h"
#import "PastquakesAnnotation.h"
#import "EQNUser.h"
#import "AppDelegate.h"
#import "EQNAreaCheck.h"
@import StoreKit;
@import SafariServices;
@@ -70,7 +68,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didChangeAuthorizationStatusNotification:)
name:EQNNotificationDidChangeAuthorizationStatus
name:EQNAuthorizationStatusDidChangeNotification
object:nil];
}
@@ -29,8 +29,8 @@ class AlertsPastEartquakesTableViewCell: EQNBaseTableViewCell {
private func updateUI() {
guard let smartphoneNetwork = smartphoneNetwork else { return }
last24hLabel.text = smartphoneNetwork.eq;
from2013Label.text = smartphoneNetwork.eq_p;
last24hLabel.text = "\(smartphoneNetwork.counterLastDayAlerts)"
from2013Label.text = "\(smartphoneNetwork.counterTotalAlerts)"
}
// MARK: - Actions
@@ -23,9 +23,9 @@ class AlertsPriorityServiceTableViewCell: EQNBaseTableViewCell {
// MARK: - Private
private func updateUI() {
guard let smartphoneNetwork = smartphoneNetwork, let minutes = Int(smartphoneNetwork.diff) else { return }
guard let smartphoneNetwork = smartphoneNetwork else { return }
let formattedTime = EQNUtility.formattedString(forTimeDifference: minutes)
let formattedTime = EQNUtility.formattedString(forTimeDifference: smartphoneNetwork.lastSubscriptionDiff)
lastSubscriptionLabel.text = String(format: NSLocalizedString("inapp_adv", comment: ""), formattedTime)
}
}
@@ -80,17 +80,17 @@ class AlertsSeismicNotificationExpandedTableViewCell: EQNBaseTableViewCell, MKMa
mapView.setCenter(coordinate.coordinate, animated: false)
mapView.setRegion(region, animated: true)
let annotation = PastquakesAnnotation(title: "", location: coordinate.coordinate, intensita: intensity)
let annotation = EQNMapAnnotationPastquakes(title: "", location: coordinate.coordinate, intensita: intensity)
mapView.addAnnotation(annotation)
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard let annotation = annotation as? PastquakesAnnotation else {
guard let annotation = annotation as? EQNMapAnnotationPastquakes else {
return nil
}
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: IDENTIFIER_ANNOTATION_PASTQUAKES)
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: EQNMapAnnotationPastquakesIdentifier)
if annotationView == nil {
annotationView = annotation.annotationView()
} else {
@@ -28,7 +28,7 @@ class AlertsSmartphoneNetworkTableViewCell: EQNBaseTableViewCell {
private func updateUI() {
guard let smartphoneNetwork = smartphoneNetwork else { return }
smartphoneCounterLabel.text = smartphoneNetwork.green.stringValue
smartphoneCounterLabel.text = "\(smartphoneNetwork.counterSmartphones)"
}
// MARK: - Actions
@@ -14,11 +14,11 @@ NS_ASSUME_NONNULL_BEGIN
- (void)refreshUI;
/// Handle `IAPHelperPurchaseNotification` notification
/// Handle `EQNInAppPurchaseDidCompleteNotification` notification
/// @param notification Notification fired
- (void)didReceiveInAppNotification:(NSNotification *)notification;
/// Handle `EQNNotificationDidDownloadData` notification
/// Handle `EQNDownloadDataDidCompleteNotification` notification
/// @param notification Notification fired
- (void)didReceiveDownloadCompleteNotification:(NSNotification *)notification;
@@ -7,7 +7,7 @@
//
#import "EQNBaseViewController.h"
#import "EQNUtility.h"
#import "Costanti.h"
@import GoogleMobileAds;
@interface EQNBaseViewController ()
@@ -23,19 +23,24 @@
- (void)viewDidLoad
{
[super viewDidLoad];
[self addBannerView];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didReceiveInAppNotification:)
name:IAPHelperPurchaseNotification object:nil];
name:EQNInAppPurchaseDidCompleteNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didReceiveDownloadCompleteNotification:)
name:EQNNotificationDidDownloadData object:nil];
name:EQNDownloadDataDidCompleteNotification object:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self handleAdBanner];
}
#pragma mark - Public
- (void)refreshUI
@@ -43,13 +48,79 @@
// nope
}
#pragma mark - Private
- (void)handleAdBanner
{
// ad banner mut be displayed only for non pro users
if ([EQNPurchaseUtility isProVersionEnabled]) {
[self hideAdBanner];
return;
}
[self showAdBanner];
}
- (void)hideAdBanner
{
if (self.bannerView == nil) {
return;
}
// remove the banner (if available)
[self.bannerView removeFromSuperview];
self.bannerView = nil;
self.bannerContainerHeightConstraint.constant = 0;
}
- (void)showAdBanner
{
if (self.bannerView == nil) {
[self createBanner];
}
// Determine the view width to use for the ad width.
CGRect frame = self.view.frame;
// Here safe area is taken into account, hence the view frame is used after
// the view has been laid out.
if (@available(iOS 11.0, *)) {
frame = UIEdgeInsetsInsetRect(self.view.frame, self.view.safeAreaInsets);
}
CGFloat viewWidth = frame.size.width;
// Step 3 - Get Adaptive GADAdSize and set the ad view.
// Here the current interface orientation is used. If the ad is being
// preloaded for a future orientation change or different orientation, the
// function for the relevant orientation should be used.
GADAdSize adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth);
self.bannerView.adSize = adSize;
self.bannerContainerHeightConstraint.constant = adSize.size.height;
// Step 4 - Create an ad request and load the adaptive banner ad.
GADRequest *request = [GADRequest request];
[self.bannerView loadRequest:request];
}
- (void)createBanner
{
self.bannerView = [[GADBannerView alloc] init];
self.bannerView.adUnitID = EQNAdMobAppIdAdaptiveBanner;
self.bannerView.rootViewController = self;
self.bannerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.bannerContainerView addSubview:self.bannerView];
[self.bannerView.topAnchor constraintEqualToAnchor:self.bannerContainerView.topAnchor].active = YES;
[self.bannerView.bottomAnchor constraintEqualToAnchor:self.bannerContainerView.bottomAnchor].active = YES;
[self.bannerView.leadingAnchor constraintEqualToAnchor:self.bannerContainerView.leadingAnchor].active = YES;
[self.bannerView.trailingAnchor constraintEqualToAnchor:self.bannerContainerView.trailingAnchor].active = YES;
}
#pragma mark - Notification
- (void)didReceiveInAppNotification:(NSNotification *)notification
{
[self.bannerView removeFromSuperview];
self.bannerView = nil;
self.bannerContainerHeightConstraint.constant = 0;
[self hideAdBanner];
dispatch_async(dispatch_get_main_queue(), ^{
[self refreshUI];
@@ -63,35 +134,4 @@
});
}
#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
@@ -10,10 +10,7 @@
#import "AppDelegate.h"
#import "EQNBaseViewController.h"
#import "SettingsBaseViewController.h"
#import "EQNUtility.h"
#import "EQNManager.h"
#import "EQNGeneratoreURLServer.h"
#import "ServerRequest.h"
@interface EQNMainTabBarController () <UITabBarControllerDelegate>
@@ -35,19 +32,30 @@ static NSString * const SegueIdentifierLogs = @"ShowLogs";
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
}];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(serverRegistrationFailedNotification:)
name:EQNServerRegistrationDidFailNotification
object:nil];
[self sincronizza];
}
#pragma mark - Notification
- (void)serverRegistrationFailedNotification:(NSNotification *)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Attenzione", nil)
message:NSLocalizedString(@"error_server_registration", nil)
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"retry", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// retry server registration
[[EQNUser defaultUser] verificaRegistrazione];
}]];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Annulla", nil) style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
});
}
#pragma mark - Public
@@ -35,7 +35,7 @@ class PurchaseProVersionViewController: UIViewController {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handlePurchaseNotification(_:)),
name: .IAPHelperPurchaseNotification,
name: .EQNInAppPurchaseDidComplete,
object: nil)
configureUI()
@@ -36,7 +36,7 @@ class SubscriptionDetailViewController: UIViewController {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handlePurchaseNotification(_:)),
name: .IAPHelperPurchaseNotification,
name: .EQNInAppPurchaseDidComplete,
object: nil)
updateUI()
@@ -73,11 +73,15 @@ class SubscriptionsViewController: UITableViewController {
private func addObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(handlePurchaseNotification(_:)),
name: .IAPHelperPurchaseNotification,
name: .EQNInAppPurchaseDidComplete,
object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(fail(_:)),
name: .IAPHelperPurchaseNotificationFail,
name: .EQNInAppPurchaseDidFail,
object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleNoTransactionsNotification(_:)),
name: .EQNInAppPurchaseNoTransactions,
object: nil)
}
@@ -173,8 +177,14 @@ class SubscriptionsViewController: UITableViewController {
if isRestorePurchase {
isRestorePurchase = false
var product: String = "unknown"
if let productIdentifier = notification.object as? String, let productName = resourceNameForProductIdentifier(productIdentifier) {
product = productName
}
let message = "\(NSLocalizedString("purchase_pro_restore_alert_message", comment: ""))\n\n(\(product))"
let alert = UIAlertController(title: NSLocalizedString("purchase_pro_restore_alert_title", comment: ""),
message: NSLocalizedString("purchase_pro_restore_alert_message", comment: ""), preferredStyle: .alert)
message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
@@ -182,6 +192,13 @@ class SubscriptionsViewController: UITableViewController {
VersioneProProducts.store.loadPurchase()
loadData()
}
@objc func handleNoTransactionsNotification(_ notification: Notification) {
let alert = UIAlertController(title: NSLocalizedString("Attenzione", comment: ""),
message: NSLocalizedString("purchase_pro_no_subscriptions_alert_message", comment: ""), preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
// MARK: - Table view data source
@@ -87,13 +87,13 @@ static NSString * const SegueIdentifierMap = @"ShowMap";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Last24HCell" forIndexPath:indexPath];
UILabel *verdeLabel = (UILabel *)[cell viewWithTag:1];
verdeLabel.text = [NSString stringWithFormat:@"%@", reteSmartPhone.g_man];
verdeLabel.text = [NSString stringWithFormat:@"%ld", (long)reteSmartPhone.manualGreen];
UILabel *giallaLabel = (UILabel *)[cell viewWithTag:2];
giallaLabel.text = [NSString stringWithFormat:@"%@", reteSmartPhone.y_man];
giallaLabel.text = [NSString stringWithFormat:@"%ld", (long)reteSmartPhone.manualYellow];
UILabel *rossaLabel = (UILabel *)[cell viewWithTag:3];
rossaLabel.text = [NSString stringWithFormat:@"%@", reteSmartPhone.r_man];
rossaLabel.text = [NSString stringWithFormat:@"%ld", (long)reteSmartPhone.manualRed];
return cell;
}
@@ -0,0 +1,23 @@
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "GADTTemplateView.h"
/// A template for medium sized views. Renders a roughly square view with a call to action on the
/// bottom and a horizontal image in the middle.
@interface GADTMediumTemplateView : GADTTemplateView
@end
@@ -0,0 +1,30 @@
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import "GADTMediumTemplateView.h"
@implementation GADTMediumTemplateView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.translatesAutoresizingMaskIntoConstraints = NO;
}
return self;
}
- (NSString *)getTemplateTypeName {
return @"medium_template";
}
@end
@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina5_5" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="GADTMediumTemplateView">
<connections>
<outlet property="adBadge" destination="PfZ-cd-zxs" id="Szh-GS-1OE"/>
<outlet property="callToActionView" destination="Ekc-Zs-FHH" id="2Er-Iz-r30"/>
<outlet property="iconView" destination="tcZ-gP-ynt" id="uYX-bV-cXT"/>
<outlet property="mediaView" destination="1ne-Xk-CBH" id="3Lh-1Y-oAC"/>
<outlet property="primaryTextView" destination="NKU-cb-NgA" id="WcC-uD-uFb"/>
<outlet property="secondaryTextView" destination="41W-IZ-S0S" id="pUs-sn-Mws"/>
<outlet property="tertiaryTextView" destination="ic2-4I-EtF" id="KnY-7K-UnN"/>
</connections>
</placeholder>
<view opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="h2X-7h-r2O">
<rect key="frame" x="0.0" y="0.0" width="355" height="402"/>
<subviews>
<view opaque="NO" clearsContextBeforeDrawing="NO" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qZf-ej-Zxg">
<rect key="frame" x="10" y="199.66666666666663" width="335" height="202.33333333333337"/>
<subviews>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ekc-Zs-FHH">
<rect key="frame" x="0.0" y="153.33333333333334" width="335" height="39"/>
<color key="backgroundColor" red="0.25882352939999997" green="0.52156862749999999" blue="0.95686274510000002" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="39" id="y8W-B6-JKk"/>
</constraints>
<state key="normal" title="Button">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JRU-6T-XIW">
<rect key="frame" x="0.0" y="0.0" width="335" height="51"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dtV-H5-CUV">
<rect key="frame" x="0.0" y="0.0" width="335" height="51"/>
<subviews>
<view contentMode="scaleToFill" horizontalCompressionResistancePriority="1" verticalCompressionResistancePriority="1" translatesAutoresizingMaskIntoConstraints="NO" id="IDQ-dK-aNl">
<rect key="frame" x="0.0" y="0.0" width="51" height="51"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="1" verticalCompressionResistancePriority="1" translatesAutoresizingMaskIntoConstraints="NO" id="tcZ-gP-ynt">
<rect key="frame" x="0.0" y="0.0" width="51" height="51"/>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="tcZ-gP-ynt" firstAttribute="leading" secondItem="IDQ-dK-aNl" secondAttribute="leading" id="080-xf-xNS"/>
<constraint firstItem="tcZ-gP-ynt" firstAttribute="top" secondItem="IDQ-dK-aNl" secondAttribute="top" id="7ay-A1-lkK"/>
<constraint firstAttribute="trailing" secondItem="tcZ-gP-ynt" secondAttribute="trailing" id="D58-gg-wEz"/>
<constraint firstAttribute="width" secondItem="IDQ-dK-aNl" secondAttribute="height" multiplier="1:1" id="fy0-5g-4fT"/>
<constraint firstAttribute="bottom" secondItem="tcZ-gP-ynt" secondAttribute="bottom" id="mcB-Kl-8SB"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZMg-Gj-lfR">
<rect key="frame" x="51" y="0.0" width="284" height="51"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Ad" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PfZ-cd-zxs">
<rect key="frame" x="10" y="30" width="28" height="21"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="5e5-3M-FF3"/>
<constraint firstAttribute="width" constant="28" id="L2a-Ko-fWP"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.2274509804" green="0.4039215686" blue="0.15686274510000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NKU-cb-NgA">
<rect key="frame" x="10" y="0.0" width="266" height="25"/>
<constraints>
<constraint firstAttribute="height" constant="25" id="iVB-Nr-QJm"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ic2-4I-EtF">
<rect key="frame" x="43" y="30" width="241" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="PfZ-cd-zxs" firstAttribute="top" secondItem="NKU-cb-NgA" secondAttribute="bottom" constant="5" id="8CL-eR-AJN"/>
<constraint firstAttribute="trailing" secondItem="ic2-4I-EtF" secondAttribute="trailing" id="9Ig-ff-Xy9"/>
<constraint firstItem="ic2-4I-EtF" firstAttribute="leading" secondItem="PfZ-cd-zxs" secondAttribute="trailing" constant="5" id="BvN-q8-2tx"/>
<constraint firstItem="NKU-cb-NgA" firstAttribute="leading" secondItem="ZMg-Gj-lfR" secondAttribute="leading" constant="10" id="R0a-Yh-5hA"/>
<constraint firstAttribute="bottom" secondItem="ic2-4I-EtF" secondAttribute="bottom" id="RsF-hZ-dlg"/>
<constraint firstAttribute="trailing" secondItem="NKU-cb-NgA" secondAttribute="trailing" constant="8" id="Rur-KX-Eao"/>
<constraint firstItem="PfZ-cd-zxs" firstAttribute="leading" secondItem="ZMg-Gj-lfR" secondAttribute="leading" constant="10" id="XOm-ic-qzo"/>
<constraint firstItem="NKU-cb-NgA" firstAttribute="top" secondItem="ZMg-Gj-lfR" secondAttribute="top" id="XXu-i3-Bb8"/>
<constraint firstItem="ic2-4I-EtF" firstAttribute="leading" secondItem="PfZ-cd-zxs" secondAttribute="trailing" constant="5" id="hI7-l2-cCQ"/>
<constraint firstAttribute="bottom" secondItem="PfZ-cd-zxs" secondAttribute="bottom" id="s9K-uZ-2fK"/>
<constraint firstItem="ic2-4I-EtF" firstAttribute="top" secondItem="NKU-cb-NgA" secondAttribute="bottom" constant="5" id="zDa-Y8-eNv"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="IDQ-dK-aNl" secondAttribute="bottom" id="Pz3-Ne-UvS"/>
<constraint firstItem="IDQ-dK-aNl" firstAttribute="top" secondItem="dtV-H5-CUV" secondAttribute="top" id="Um4-Pc-PRn"/>
<constraint firstItem="IDQ-dK-aNl" firstAttribute="leading" secondItem="dtV-H5-CUV" secondAttribute="leading" id="ygw-iI-8p3"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="dtV-H5-CUV" secondAttribute="bottom" id="JTS-sy-ZIx"/>
<constraint firstItem="dtV-H5-CUV" firstAttribute="leading" secondItem="JRU-6T-XIW" secondAttribute="leading" id="KnB-yd-LES"/>
<constraint firstAttribute="trailing" secondItem="dtV-H5-CUV" secondAttribute="trailing" id="c6Z-Wa-u8v"/>
<constraint firstItem="dtV-H5-CUV" firstAttribute="top" secondItem="JRU-6T-XIW" secondAttribute="top" id="hLc-rA-agZ"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="41W-IZ-S0S">
<rect key="frame" x="0.0" y="61.000000000000021" width="335" height="82.333333333333314"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="20.329999999999998" id="NUh-RX-SnN"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" notEnabled="YES"/>
</accessibility>
<constraints>
<constraint firstItem="JRU-6T-XIW" firstAttribute="top" secondItem="qZf-ej-Zxg" secondAttribute="top" id="7V3-bf-fEw"/>
<constraint firstItem="JRU-6T-XIW" firstAttribute="leading" secondItem="qZf-ej-Zxg" secondAttribute="leading" id="7q0-md-byq"/>
<constraint firstItem="Ekc-Zs-FHH" firstAttribute="top" secondItem="41W-IZ-S0S" secondAttribute="bottom" constant="10" id="Haj-5X-7Jq"/>
<constraint firstItem="41W-IZ-S0S" firstAttribute="top" secondItem="JRU-6T-XIW" secondAttribute="bottom" constant="10" id="LUq-TO-4Ri"/>
<constraint firstItem="Ekc-Zs-FHH" firstAttribute="leading" secondItem="qZf-ej-Zxg" secondAttribute="leading" id="N0d-Ud-bcH"/>
<constraint firstAttribute="trailing" secondItem="Ekc-Zs-FHH" secondAttribute="trailing" id="QEk-Nl-LP0"/>
<constraint firstAttribute="bottom" secondItem="Ekc-Zs-FHH" secondAttribute="bottom" constant="10" id="fQb-8m-kWu"/>
<constraint firstAttribute="trailing" secondItem="JRU-6T-XIW" secondAttribute="trailing" id="fpH-cd-zrf"/>
<constraint firstAttribute="trailing" secondItem="41W-IZ-S0S" secondAttribute="trailing" id="rZu-Yd-6qa"/>
<constraint firstItem="41W-IZ-S0S" firstAttribute="leading" secondItem="qZf-ej-Zxg" secondAttribute="leading" id="w16-DI-Ydj"/>
</constraints>
</view>
<view clipsSubviews="YES" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="1ne-Xk-CBH" customClass="GADMediaView">
<rect key="frame" x="0.0" y="0.0" width="355" height="199.66666666666666"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" secondItem="1ne-Xk-CBH" secondAttribute="height" multiplier="16:9" id="kTC-ip-nfX"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" notEnabled="YES"/>
</accessibility>
<constraints>
<constraint firstAttribute="trailing" secondItem="qZf-ej-Zxg" secondAttribute="trailing" constant="10" id="1Rv-ij-HDB"/>
<constraint firstItem="qZf-ej-Zxg" firstAttribute="leading" secondItem="h2X-7h-r2O" secondAttribute="leading" constant="10" id="OCX-hu-Rvd"/>
<constraint firstItem="qZf-ej-Zxg" firstAttribute="top" secondItem="1ne-Xk-CBH" secondAttribute="bottom" id="aHY-Ht-nDt"/>
<constraint firstItem="1ne-Xk-CBH" firstAttribute="leading" secondItem="h2X-7h-r2O" secondAttribute="leading" id="cj9-Mw-8MR"/>
<constraint firstAttribute="trailing" secondItem="1ne-Xk-CBH" secondAttribute="trailing" id="gLW-Sf-wcR"/>
<constraint firstItem="1ne-Xk-CBH" firstAttribute="top" secondItem="h2X-7h-r2O" secondAttribute="top" id="ipR-Fl-Mie"/>
<constraint firstAttribute="bottom" secondItem="qZf-ej-Zxg" secondAttribute="bottom" id="sWi-Jm-MXA"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-68.840579710144937" y="794.83695652173924"/>
</view>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
</objects>
</document>
@@ -0,0 +1,109 @@
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright © 2018 Google. All rights reserved.
#import <GoogleMobileAds/GoogleMobileAds.h>
/// Constants used to style your template.
typedef NSString* GADTNativeTemplateStyleKey NS_STRING_ENUM;
/// The font, font color and background color for your call to action view.
/// All templates have a call to action view.
#pragma mark - Call To Action
/// Call to action font. Expects a UIFont.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyCallToActionFont;
/// Call to action font color. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyCallToActionFontColor;
/// Call to action background color. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyCallToActionBackgroundColor;
/// The font, font color and background color for the first row of text in the template.
/// All templates have a primary text area which is populated by the native ad's headline.
#pragma mark - Primary Text
/// Primary text font. Expects a UIFont.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyPrimaryFont;
/// Primary text font color. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyPrimaryFontColor;
/// Primary text background color. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyPrimaryBackgroundColor;
/// The font, font color and background color for the second row of text in the template.
/// All templates have a secondary text area which is populated either by the body of the ad,
/// or by the rating of the app.
#pragma mark - Secondary Text
/// Secondary text font. Expects a UIFont.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeySecondaryFont;
/// Secondary text font color. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeySecondaryFontColor;
/// Secondary text background color. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeySecondaryBackgroundColor;
/// The font, font color and background color for the third row of text in the template.
/// The third row is used to display store name or the default tertiary text.
#pragma mark - Tertiary Text
/// Tertiary text font. Expects a UIFont.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyTertiaryFont;
/// Tertiary text font color. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyTertiaryFontColor;
/// Tertiary text background color. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyTertiaryBackgroundColor;
#pragma mark - Additional Style Options
/// The background color for the bulk of the ad. Expects a UIColor.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyMainBackgroundColor;
/// The corner rounding radius for the icon view and call to action. Expects an NSNumber.
extern GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyCornerRadius;
/// The super class for every template object.
/// This class has the majority of all layout and styling logic.
@interface GADTTemplateView : GADNativeAdView
@property(nonatomic, copy) NSDictionary<GADTNativeTemplateStyleKey, NSObject*>* styles;
@property(weak) IBOutlet UILabel* primaryTextView;
@property(weak) IBOutlet UILabel* secondaryTextView;
@property(weak) IBOutlet UILabel* tertiaryTextView;
@property(weak) IBOutlet UILabel* adBadge;
@property(weak) IBOutlet UIImageView* brandImage;
@property(weak) IBOutlet UIView* backgroundView;
@property(weak) UIView* rootView;
/// Adds a constraint to the superview so that the template spans the width of its parent.
/// Does nothing if there is no superview.
- (void)addHorizontalConstraintsToSuperviewWidth;
/// Adds a constraint to the superview so that the template is centered vertically in its parent.
/// Does nothing if there is no superview.
- (void)addVerticalCenterConstraintToSuperview;
/// Utility method to get a color from a hex string.
+ (UIColor*)colorFromHexString:(NSString*)hexString;
- (NSString *)getTemplateTypeName;
@end
@@ -0,0 +1,306 @@
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Copyright © 2018 Google. All rights reserved.
#import "GADTTemplateView.h"
#import <QuartzCore/QuartzCore.h>
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyCallToActionFont =
@"call_to_action_font";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyCallToActionFontColor =
@"call_to_action_font_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyCallToActionBackgroundColor =
@"call_to_action_background_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeySecondaryFont = @"secondary_font";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeySecondaryFontColor =
@"secondary_font_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeySecondaryBackgroundColor =
@"secondary_background_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyPrimaryFont = @"primary_font";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyPrimaryFontColor = @"primary_font_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyPrimaryBackgroundColor =
@"primary_background_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyTertiaryFont = @"tertiary_font";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyTertiaryFontColor =
@"tertiary_font_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyTertiaryBackgroundColor =
@"tertiary_background_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyMainBackgroundColor =
@"main_background_color";
GADTNativeTemplateStyleKey const GADTNativeTemplateStyleKeyCornerRadius = @"corner_radius";
static NSString* const GADTBlue = @"#5C84F0";
@implementation GADTTemplateView {
NSDictionary<GADTNativeTemplateStyleKey, NSObject*>* _defaultStyles;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_rootView = [NSBundle.mainBundle loadNibNamed:NSStringFromClass([self class])
owner:self
options:nil]
.firstObject;
[self addSubview:_rootView];
[self
addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|[_rootView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_rootView)]];
[self
addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|[_rootView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_rootView)]];
[self applyStyles];
[self styleAdBadge];
}
return self;
}
- (NSString *)getTemplateTypeName {
return @"root";
}
/// Returns the style value for the provided key or the default style if no styles dictionary
/// was set.
- (id)styleForKey:(GADTNativeTemplateStyleKey)key {
return _styles[key] ?: nil;
}
// Goes through all recognized style keys and updates the views accordingly, overwriting the
// defaults.
- (void)applyStyles {
self.layer.borderColor = [GADTTemplateView colorFromHexString:@"E0E0E0"].CGColor;
self.layer.borderWidth = 1.0f;
[self.mediaView sizeToFit];
if ([self styleForKey:GADTNativeTemplateStyleKeyCornerRadius]) {
float roundedCornerRadius =
((NSNumber*)[self styleForKey:GADTNativeTemplateStyleKeyCornerRadius]).floatValue;
// Rounded corners
self.iconView.layer.cornerRadius = roundedCornerRadius;
self.iconView.clipsToBounds = YES;
((UIButton*)self.callToActionView).layer.cornerRadius = roundedCornerRadius;
((UIButton*)self.callToActionView).clipsToBounds = YES;
}
// Fonts
if ([self styleForKey:GADTNativeTemplateStyleKeyPrimaryFont]) {
((UILabel*)_primaryTextView).font =
(UIFont*)[self styleForKey:GADTNativeTemplateStyleKeyPrimaryFont];
}
if ([self styleForKey:GADTNativeTemplateStyleKeySecondaryFont]) {
((UILabel*)_secondaryTextView).font =
(UIFont*)[self styleForKey:GADTNativeTemplateStyleKeySecondaryFont];
}
if ([self styleForKey:GADTNativeTemplateStyleKeyTertiaryFont]) {
((UILabel*)_tertiaryTextView).font =
(UIFont*)[self styleForKey:GADTNativeTemplateStyleKeyTertiaryFont];
}
if ([self styleForKey:GADTNativeTemplateStyleKeyCallToActionFont]) {
((UIButton*)self.callToActionView).titleLabel.font =
(UIFont*)[self styleForKey:GADTNativeTemplateStyleKeyCallToActionFont];
}
// Font colors
if ([self styleForKey:GADTNativeTemplateStyleKeyPrimaryFontColor])
((UILabel*)_primaryTextView).textColor =
(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeyPrimaryFontColor];
if ([self styleForKey:GADTNativeTemplateStyleKeySecondaryFontColor]) {
((UILabel*)_secondaryTextView).textColor =
(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeySecondaryFontColor];
}
if ([self styleForKey:GADTNativeTemplateStyleKeyTertiaryFontColor]) {
((UILabel*)_tertiaryTextView).textColor =
(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeyTertiaryFontColor];
}
if ([self styleForKey:GADTNativeTemplateStyleKeyCallToActionFontColor]) {
[((UIButton*)self.callToActionView)
setTitleColor:(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeyCallToActionFontColor]
forState:UIControlStateNormal];
}
// Background colors
if ([self styleForKey:GADTNativeTemplateStyleKeyPrimaryBackgroundColor]) {
((UILabel*)_primaryTextView).backgroundColor =
(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeyPrimaryBackgroundColor];
}
if ([self styleForKey:GADTNativeTemplateStyleKeySecondaryBackgroundColor]) {
((UILabel*)_secondaryTextView).backgroundColor =
(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeySecondaryBackgroundColor];
}
if ([self styleForKey:GADTNativeTemplateStyleKeyTertiaryBackgroundColor]) {
((UILabel*)_tertiaryTextView).backgroundColor =
(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeyTertiaryBackgroundColor];
}
if ([self styleForKey:GADTNativeTemplateStyleKeyCallToActionBackgroundColor]) {
((UIButton*)self.callToActionView).backgroundColor =
(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeyCallToActionBackgroundColor];
}
if ([self styleForKey:GADTNativeTemplateStyleKeyMainBackgroundColor]) {
self.backgroundColor = (UIColor*)[self styleForKey:GADTNativeTemplateStyleKeyMainBackgroundColor];
}
if (_backgroundView && [self styleForKey:GADTNativeTemplateStyleKeyPrimaryBackgroundColor]) {
_backgroundView.backgroundColor =
(UIColor*)[self styleForKey:GADTNativeTemplateStyleKeyPrimaryBackgroundColor];
}
}
/// Styles the Ad Badge according to best practices.
- (void)styleAdBadge {
_adBadge.layer.borderColor = _adBadge.textColor.CGColor;
_adBadge.layer.borderWidth = 1.0;
_adBadge.layer.cornerRadius = 3.0;
}
- (void)setStyles:(NSDictionary<GADTNativeTemplateStyleKey, NSObject*>*)styles {
_styles = [styles copy];
[self applyStyles];
}
- (void)setNativeAd:(GADNativeAd*)nativeAd {
[super setNativeAd:nativeAd];
self.headlineView = _primaryTextView;
NSString* adBody = nativeAd.body;
NSString* cta = nativeAd.callToAction;
NSString* headline = nativeAd.headline;
NSString* tertiaryText;
if (nativeAd.store.length && !nativeAd.advertiser.length) {
// Ad has store but not advertiser
self.storeView = _tertiaryTextView;
tertiaryText = nativeAd.store;
} else if (!nativeAd.store.length && nativeAd.advertiser.length) {
// Ad has advertiser but not store
self.advertiserView = _tertiaryTextView;
tertiaryText = nativeAd.advertiser;
} else if (!nativeAd.store.length && !nativeAd.advertiser.length) {
// Ad has both store and advertiser, default to showing advertiser.
self.advertiserView = _tertiaryTextView;
tertiaryText = nativeAd.advertiser;
}
((UILabel*)_primaryTextView).text = headline;
((UILabel*)_tertiaryTextView).text = tertiaryText;
[((UIButton*)self.callToActionView) setTitle:cta forState:UIControlStateNormal];
// Body text
// We either show the number of stars an app has, or show the body of the ad.
// Use the unicode characters for filled in or empty stars.
if (nativeAd.starRating.floatValue > 0) {
NSMutableString* stars = [[NSMutableString alloc] initWithString:@""];
int count = 0;
for (; count < nativeAd.starRating.intValue; count++) {
NSString* filledStar = [NSString stringWithUTF8String:"\u2605"];
[stars appendString:filledStar];
}
for (; count < 5; count++) {
NSString* emptyStar = [NSString stringWithUTF8String:"\u2606"];
[stars appendString:emptyStar];
}
adBody = stars;
self.starRatingView = _secondaryTextView;
} else {
self.bodyView = _secondaryTextView;
}
((UILabel*)_secondaryTextView).text = adBody;
if (nativeAd.icon) {
((UIImageView*)self.iconView).image = nativeAd.icon.image;
}
[self.mediaView setMediaContent:nativeAd.mediaContent];
}
- (void)addHorizontalConstraintsToSuperviewWidth {
// Add an autolayout constraint to make sure our template view stretches to fill the
// width of its parent.
if (self.superview) {
UIView* child = self;
[self.superview
addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|[child]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(child)]];
}
}
- (void)addVerticalCenterConstraintToSuperview {
if (self.superview) {
UIView* child = self;
[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self.superview
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:child
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0]];
}
}
/// Creates an opaque UIColor object from a byte-value color definition.
+ (UIColor*)colorFromHexString:(NSString*)hexString {
if (hexString == nil) {
return nil;
}
NSRange range = [hexString rangeOfString:@"^#[0-9a-fA-F]{6}$" options:NSRegularExpressionSearch];
if (range.location == NSNotFound) {
return nil;
}
unsigned rgbValue = 0;
NSScanner* scanner = [NSScanner scannerWithString:hexString];
[scanner setScanLocation:1]; // Bypass '#' character.
[scanner scanHexInt:&rgbValue];
return [UIColor colorWithRed:((rgbValue & 0xff0000) >> 16) / 255.0f
green:((rgbValue & 0xff00) >> 8) / 255.0f
blue:(rgbValue & 0xff) / 255.0f
alpha:1];
}
@end
@@ -0,0 +1,77 @@
//
// SeismicNetworkAdvertiseTableViewCell.swift
// Earthquake Network
//
// Created by Andrea Busi on 20/02/21.
// Copyright © 2021 Earthquake Network. All rights reserved.
//
import UIKit
import GoogleMobileAds
class SeismicNetworkAdvertiseTableViewCell: UITableViewCell {
static let Identifier = "SeismicNetworkAdvertiseTableViewCell"
private lazy var containerView: UIView = {
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.cornerRadius = AppTheme.shared.borderCornerRadius
view.layer.masksToBounds = false
// add shadow
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOpacity = 0.5
view.layer.shadowOffset = CGSize(width: 0, height: 2)
view.layer.shadowRadius = 2
return view
}()
private lazy var bannerView: GADNativeAdView = {
let view = GADTMediumTemplateView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// 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 = .default
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .clear
// container view
contentView.addSubview(containerView)
containerView.backgroundColor = .red
containerView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8.0).isActive = true
containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8.0).isActive = true
containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0).isActive = true
containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8.0).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 350.0).isActive = true
containerView.addSubview(bannerView)
bannerView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
bannerView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
bannerView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
bannerView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
}
// MARK: - Public
func loadNativeAd(_ nativeAd: GADNativeAd) {
bannerView.nativeAd = nativeAd
}
}
@@ -1,15 +0,0 @@
//
// ReteSismiDettagliMappa.h
// Earthquake Network
//
// Refactored by Andrea Busi on 26/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "DettagliMappaViewController.h"
#import "EQNSisma.h"
@interface ReteSismiDettagliMappa : DettagliMappaViewController
@property (nonatomic, strong, nullable) EQNSisma *sisma;
@end
@@ -1,77 +0,0 @@
//
// 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"
#import "EQNAdsUtility.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 = [EQNAdsUtility 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,72 @@
//
// SeismicNetworksMapDetailViewController.swift
// Earthquake Network
//
// Created by Andrea Busi on 21/02/21.
// Copyright © 2021 Earthquake Network. All rights reserved.
//
import UIKit
import MapKit
class SeismicNetworksMapDetailViewController: EQNBaseViewController, MKMapViewDelegate {
// MARK: - UI
@IBOutlet private weak var mapView: MKMapView!
// MARK: - State
var seismic: EQNSisma?
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
if let seismic = seismic {
addMarker(for: seismic)
}
}
// MARK: - Private
private func setupUI() {
let closeButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(closeTapped(_:)))
navigationItem.rightBarButtonItem = closeButton
}
private func addMarker(for seismic: EQNSisma) {
let annotation = EQNMapAnnotationSeismic(title: seismic.place, location: seismic.coordinate.coordinate, intensita: seismic.magnitude.doubleValue)
mapView.addAnnotation(annotation)
let span = MKCoordinateSpan(latitudeDelta: 10.5, longitudeDelta: 10.5)
let region = MKCoordinateRegion(center: seismic.coordinate.coordinate, span: span)
mapView.setCenter(seismic.coordinate.coordinate, animated: false)
mapView.setRegion(region, animated: true)
}
// MARK: - Actions
@objc private func closeTapped(_ sender: Any) {
dismiss(animated: true)
}
// MARK: - MKMapViewDelegate
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let sismaAnnotation = annotation as? EQNMapAnnotationSeismic {
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: EQNMapAnnotationSeismicIdentifier)
if annotationView == nil {
annotationView = sismaAnnotation.annotationView()
} else {
annotationView?.annotation = sismaAnnotation
}
return annotationView
}
return nil
}
}
@@ -10,8 +10,13 @@ import UIKit
import EventKitUI
import DZNEmptyDataSet
class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate, UITableViewDataSource {
class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private enum CellType {
case seismic(EQNSisma)
case advertise(GADNativeAd)
}
private static let SegueIdentifierMap = "ShowMapDetail"
private static let SegueIdentifierFilters = "ShowFilters"
private static let SegueIdentifierSettings = "ShowSettings"
@@ -23,8 +28,17 @@ class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate,
@IBOutlet private weak var tableView: UITableView?
@IBOutlet private weak var expandeCollapseButton: UIBarButtonItem!
/// Seismisc to display
private var seismics = [EQNSisma]()
/// The ad loader
private lazy var adLoader: GADAdLoader = {
let adLoader = GADAdLoader(
adUnitID: EQNAdMobAppIdNativeBanner, rootViewController: self,
adTypes: [.native], options: nil)
adLoader.delegate = self
return adLoader
}()
/// Cells to display (must be seismics or ad banners)
private var rows = [CellType]()
/// Informations to display on a single cell
private var informations = [SeismicNetworkTableViewCell.InformationType]()
/// Index path of row with map expanded
@@ -46,6 +60,8 @@ class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate,
performSegue(withIdentifier: Self.SegueIdentifierSettings, sender: nil)
UserDefaults.standard.setValue(true, forKey: EQNUserDefaultKeyOneShotShowCountry)
}
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveDownloadCompleteNotification(_:)), name: .EQNDownloadDataDidComplete, object: nil)
}
override func viewWillAppear(_ animated: Bool) {
@@ -60,14 +76,15 @@ class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate,
tableView?.estimatedRowHeight = 300.0;
tableView?.rowHeight = UITableView.automaticDimension
tableView?.register(SeismicNetworkTableViewCell.self, forCellReuseIdentifier: SeismicNetworkTableViewCell.Identifier)
tableView?.register(SeismicNetworkAdvertiseTableViewCell.self, forCellReuseIdentifier: SeismicNetworkAdvertiseTableViewCell.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
if let seismic = sender as? EQNSisma, let navController = segue.destination as? UINavigationController, let controller = navController.viewControllers.first as? SeismicNetworksMapDetailViewController {
controller.seismic = seismic
}
case Self.SegueIdentifierFilters:
if let controller = segue.destination as? SeismicFiltersViewController {
@@ -90,13 +107,21 @@ class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate,
}
}
// MARK: - Notifications
@objc func didReceiveDownloadCompleteNotification(_ sender: Notification) {
self.openMapIndexPath = nil
self.openWeatherIndexPath = nil
DispatchQueue.main.async {
self.refreshUI()
}
}
// MARK: - Private
override func refreshUI() {
super.refreshUI()
let allSeismics = EQNManager.manager().retiSismiche
seismics = EQNSeismic.shared.filterSeismicList(allSeismics ?? [])
private func refreshUI() {
elaborateData()
if let saved = UserDefaults.standard.array(forKey: EQNUserDefaultKeySesmicInformations) as? [Int] {
informations = saved.compactMap { SeismicNetworkTableViewCell.InformationType(rawValue: $0) }
@@ -111,15 +136,24 @@ class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate,
tableView?.reloadData()
}
private func loadAd() {
adLoader.load(GADRequest())
}
private func loadData(forced: Bool) {
EQNManager.manager().refreshSeismicData(forced: forced)
}
@objc override func didReceiveDownloadComplete(_ notification: Notification) {
self.openMapIndexPath = nil
self.openWeatherIndexPath = nil
private func elaborateData() {
// show filtered seismic based on user settings
let allSeismics = EQNManager.manager().retiSismiche
let filteredSeismics = EQNSeismic.shared.filterSeismicList(allSeismics ?? [])
rows = filteredSeismics.map { .seismic($0) }
super.didReceiveDownloadComplete(notification)
// if is not a pro user, show an advertise
if !EQNPurchaseUtility.isProVersionEnabled() {
loadAd()
}
}
// MARK: - Actions
@@ -150,30 +184,39 @@ class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate,
// MARK: - Table view delegate and data source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
seismics.count
rows.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
let row = rows[indexPath.row]
switch row {
case .seismic(let seismic):
let cell = tableView.dequeueReusableCell(withIdentifier: SeismicNetworkTableViewCell.Identifier, for: indexPath) as! SeismicNetworkTableViewCell
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
case .advertise(let nativeAd):
let cell = tableView.dequeueReusableCell(withIdentifier: SeismicNetworkAdvertiseTableViewCell.Identifier, for: indexPath) as! SeismicNetworkAdvertiseTableViewCell
cell.loadNativeAd(nativeAd)
return cell
}
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 row = rows[indexPath.row]
let seismic = seismics[indexPath.row]
performSegue(withIdentifier: Self.SegueIdentifierMap, sender: seismic)
if case .seismic(let seismic) = row {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: Self.SegueIdentifierMap, sender: seismic)
}
}
// MARK: - Private
@@ -231,16 +274,30 @@ class SeismicNetworksViewController: EQNBaseViewController, UITableViewDelegate,
}
}
extension SeismicNetworksViewController: GADNativeAdLoaderDelegate {
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {
print("[GADAdLoader] didReceive")
let adPosition = min(3, rows.count)
rows.insert(.advertise(nativeAd), at: adPosition)
tableView?.reloadData()
}
func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: Error) {
// nope
print("[GADAdLoader] didFailToReceiveAdWithError: \(error.localizedDescription)")
}
}
extension SeismicNetworksViewController: SeismicNetworkTableViewCellDelegate {
func seismicNetworkCellDidTapShare(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
guard let index = tableView?.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] 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
@@ -281,15 +338,14 @@ extension SeismicNetworksViewController: SeismicNetworkTableViewCellDelegate {
}
func seismicNetworkCellDidTapMapDetail(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
let seismic = seismics[index.row]
guard let index = tableView?.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
performSegue(withIdentifier: Self.SegueIdentifierMap, sender: seismic)
}
func seismicNetworkCellDidTapCalendar(_ cell: SeismicNetworkTableViewCell) {
guard let index = tableView?.indexPath(for: cell) else { return }
guard let index = tableView?.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
let seismic = seismics[index.row]
openCalendar(for: seismic)
}
@@ -8,7 +8,6 @@
#import "SettingsUserReportAlertsViewController.h"
#import "EQNNotificheSegnalazioniUtente.h"
#import "EQNUtility.h"
@interface SettingsUserReportAlertsViewController ()
+29 -25
View File
@@ -35,6 +35,8 @@ static NSString * const EQNServerUrlDownloadRetiSismiche = @"https://srv.earthqu
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";
/// Registra l'abbonamento acquistato dall'utente
static NSString * const EQNServerUrlRegisterSubscription = @"https://srv.earthquakenetwork.it/distquake_upload_subscription.php";
/// Carica le impostazioni delle notifiche definite dall'utente
static NSString * const EQNServerUrlUploadSettings = @"https://srv.earthquakenetwork.it/distquake_upload_settings_ios.php";
// URL EQNTipoChiamataRegistrazione server
@@ -65,13 +67,25 @@ 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";
/// 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
static NSString * const EQNUserDefaultProDiscountExpired = @"PREZZO_SCONTATO_SCADUTO";
#pragma mark - NSNotification
/// Notifica di fallimento registrazione al server (user_id non ricavato)
static NSNotificationName const EQNServerRegistrationDidFailNotification = @"EQNServerRegistrationDidFailNotification";
/// Notifica di cambio stato permesso di localizzazione
static NSString * const EQNNotificationDidChangeAuthorizationStatus = @"EQNNotificationDidChangeAuthorizationStatus";
static NSNotificationName const EQNAuthorizationStatusDidChangeNotification = @"EQNAuthorizationStatusDidChangeNotification";
/// Notifica di completamento download dei dati
static NSString * const EQNNotificationDidDownloadData = @"EQNNotificationDidDownloadData";
static NSNotificationName const EQNDownloadDataDidCompleteNotification = @"EQNDownloadDataDidCompleteNotification";
/// Notifica di acquisto in-app effettuato
static NSNotificationName const EQNInAppPurchaseDidCompleteNotification = @"EQNInAppPurchaseDidCompleteNotification";
/// Notifica di acquisto in-app fallito
static NSNotificationName const EQNInAppPurchaseDidFailNotification = @"EQNInAppPurchaseDidFailNotification";
/// Notifica di nessun acquisto trovato
static NSNotificationName const EQNInAppPurchaseNoTransactionsNotification = @"EQNInAppPurchaseNoTransactionsNotification";
#pragma mark - Other constants
@@ -81,15 +95,14 @@ static NSTimeInterval const EQNSendReportDelayBetweenMessages = 5.0;
/// Tempo di attesa (minuti) per l'invio di due commenti
static NSTimeInterval const EQNSendReportDelayBetweenComments = 30.0;
// rete Smartphone
#define IDENTIFIER_ANNOTATION_RETESMARTPHONE @"IDENTIFIER_ANNOTATION_RETESMARTPHONE"
// pastequakes
#define IDENTIFIER_ANNOTATION_PASTQUAKES @"IDENTIFIER_ANNOTATION_PASTQUAKES"
#ifdef DEBUG
static NSString * const EQNAdMobAppIdAdaptiveBanner = @"ca-app-pub-3940256099942544/2934735716"; // test
static NSString * const EQNAdMobAppIdNativeBanner = @"ca-app-pub-0053870219990922/6195421224";
#else
static NSString * const EQNAdMobAppIdAdaptiveBanner = @"ca-app-pub-0053870219990922/3394298808";
static NSString * const EQNAdMobAppIdNativeBanner = @"ca-app-pub-0053870219990922/6195421224";
#endif
// sismi
#define IDENTIFIER_ANNOTATION_SISMI @"IDENTIFIER_ANNOTATION_SISMI"
// rete smartphone notifiche
#define IDENTIFIER_ANNOTATION_RS_NOTIFICA @"IDENTIFIER_ANNOTATION_RS_NOTIFICA"
// filtriMappaTime
typedef enum : NSInteger {
@@ -132,6 +145,7 @@ typedef NS_ENUM(NSInteger, EQNTipoChiamata) {
EQNTipoChiamataCommentoTerremoto,
EQNTipoChiamataImpostazioniNotifiche,
EQNTipoChiamataOfferTimeRemaining,
EQNTipoChiamataRegisterSubscription,
EQNTipoChiamataAlertPushTest,
EQNTipoChiamataAlertSimulator
};
@@ -153,12 +167,13 @@ typedef NS_ENUM(NSInteger, EQNTipoChiamata) {
#define SECONDI_RILIEVO 3
// Soglia deviazione standard se superata lo stato del rilievo è positivo altrimenti negativo
#define SOGLIA_DEVIAZIONE_RILIEVO 1.8
// stato rilievo
// il parametro viene inviato al server e_t1
typedef enum : NSInteger {
negativo = 0,
positivo
} EQNRilevamentoSoglia;
typedef NS_ENUM(NSInteger, EQNRilevamentoSoglia) {
EQNRilevamentoSogliaNegativo = 0,
EQNRilevamentoSogliaPositivo
};
//////////////////////////////////////// CALIBRAZIONE ////////////////////////////////////////
// secondi durata calibrazione
@@ -226,17 +241,6 @@ typedef enum : NSInteger {
#define TEMPO_VISUALIZZAZIONE_NOTIFICA 10800
// AD MOB
//ADMOB_APP_ID
#define EQN_ADMOB_APP_IDA @"ca-app-pub-0053870219990922~2021960172"
#define EQN_ADMOB_ANNUNCIO_IDA @"ca-app-pub-0053870219990922/3394298808"
#define EQN_ADMOB_ANNUNCIO_IDA_TEST @"ca-app-pub-3940256099942544/2934735716"
// ACQUISTI IN APP
#define CONTEGGIO_APERTURE_PER_SCONTO @"CONTEGGIO_APERTURE_PER_SCONTO"
#define PREZZO_SCONTATO_SCADUTO @"PREZZO_SCONTATO_SCADUTO"
#define IAPHelperPurchaseNotification @"IAPHelperPurchaseNotification"
// FILTRO ENTI
#define EQN_MAGNITUDO_MINIMA @"EQN_MAGNITUDO_MINIMA"
#define EQN_DISTANZA_MASSIMA @"EQN_DISTANZA_MASSIMA"
@@ -9,8 +9,11 @@
#import "EQNNotificheReteSismiche.h"
#import "EQNSisma.h"
#import "EQNBaseViewController.h"
#import "ReteSismiDettagliMappa.h"
#import "SettingsBaseViewController.h"
#import "PastquakesAnnotation.h"
#import "EQNMapAnnotationPastquakes.h"
#import "EQNGeneratoreURLServer.h"
#import "ServerRequest.h"
#import "EQNMapAnnotationSeismic.h"
#import "GADTTemplateView.h"
#import "GADTMediumTemplateView.h"
+7
View File
@@ -43,6 +43,13 @@
<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>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
</array>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
@@ -1,24 +0,0 @@
//
// EQNAdsUtility.h
// Earthquake Network
//
// Created by Busi Andrea on 15/10/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
@import GoogleMobileAds;
NS_ASSUME_NONNULL_BEGIN
@interface EQNAdsUtility : NSObject
/// Creates Ad-sense banner to show on a given controller
/// This method returns nil if the user has a Pro version, no banner has to be shown
/// @param controller Controller
/// @param isButton Is button
+ (nullable GADBannerView *)ottieniBannerWithController:(UIViewController *)controller position:(BOOL)isButton;
@end
NS_ASSUME_NONNULL_END
@@ -1,45 +0,0 @@
//
// EQNAdsUtility.m
// Earthquake Network
//
// Created by Busi Andrea on 15/10/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "EQNAdsUtility.h"
@implementation EQNAdsUtility
#pragma mark - Public
+ (GADBannerView *)ottieniBannerWithController:(UIViewController *)controller position:(BOOL)isButton
{
if ([EQNPurchaseUtility isProVersionEnabled]) {
return nil;
}
GADBannerView *bannerView = [[GADBannerView alloc]
initWithAdSize:kGADAdSizeBanner];
bannerView.adUnitID = EQN_ADMOB_ANNUNCIO_IDA;
bannerView.rootViewController = controller;
bannerView.backgroundColor = [UIColor whiteColor];
[bannerView loadRequest:[GADRequest request]];
[self addBanner:bannerView toController:controller isTopAnchored:isButton];
return bannerView;
}
#pragma mark - Private
+ (void)addBanner:(UIView *)bannerView toController:(UIViewController *)controller isTopAnchored:(BOOL)isButton
{
bannerView.translatesAutoresizingMaskIntoConstraints = NO;
[controller.view addSubview:bannerView];
[[bannerView.centerXAnchor constraintEqualToAnchor:controller.view.centerXAnchor] setActive:YES];
NSLayoutAnchor *parentAnchor = isButton ? controller.view.safeAreaLayoutGuide.bottomAnchor : controller.view.safeAreaLayoutGuide.topAnchor;
NSLayoutAnchor *bannerAnchor = isButton ? bannerView.bottomAnchor : bannerView.topAnchor;
[[bannerAnchor constraintEqualToAnchor:parentAnchor] setActive:YES];
}
@end
@@ -20,13 +20,13 @@ public class EQNPurchaseUtility: NSObject {
/// If zero, no discounted price is available
/// - Parameter completion: Completion
static func offerTimeRemaining(completion: @escaping (_ timeRemaining: Int) -> Void) {
let appOpenCounter = UserDefaults.standard.integer(forKey:CONTEGGIO_APERTURE_PER_SCONTO)
let appOpenCounter = UserDefaults.standard.integer(forKey:EQNUserDefaultProDiscountOpenCounter)
if appOpenCounter < Self.AppOpenCountForDiscount {
completion(0)
return
}
let discountExpired = UserDefaults.standard.bool(forKey: PREZZO_SCONTATO_SCADUTO)
let discountExpired = UserDefaults.standard.bool(forKey: EQNUserDefaultProDiscountExpired)
if discountExpired {
completion(0)
return
@@ -34,7 +34,7 @@ public class EQNPurchaseUtility: NSObject {
EQNUser.default().downloadOfferTimeRemaining { (timeOffer) in
if timeOffer == 0 {
UserDefaults.standard.set(true, forKey: PREZZO_SCONTATO_SCADUTO)
UserDefaults.standard.set(true, forKey: EQNUserDefaultProDiscountExpired)
}
let timeInHours = timeOffer / 60
@@ -90,13 +90,13 @@ public class EQNPurchaseUtility: NSObject {
VersioneProProducts.Identifier.identifiers.forEach { (identifier) in
UserDefaults.standard.removeObject(forKey: identifier)
}
NotificationCenter.default.post(name: .IAPHelperPurchaseNotification, object: nil)
NotificationCenter.default.post(name: .EQNInAppPurchaseDidComplete, object: nil)
}
/// Use to simulate the purchase of the Pro version
@objc public static func simulateProPurchase(identifier: String) {
// store and notify
UserDefaults.standard.set(true, forKey: identifier)
NotificationCenter.default.post(name: .IAPHelperPurchaseNotification, object: identifier)
NotificationCenter.default.post(name: .EQNInAppPurchaseDidComplete, object: identifier)
}
}
@@ -1,28 +0,0 @@
//
// EQNReteSmartphone.h
// Earthquake Network
//
// Created by Luca Beretta on 09/10/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface EQNReteSmartphone : NSObject
@property (nonatomic, strong) NSString *eq;
@property (nonatomic, strong) NSString *eq_p;
@property (nonatomic, strong) NSNumber *green;
@property (nonatomic, strong) NSNumber *g_man;
@property (nonatomic, strong) NSNumber *y_man;
@property (nonatomic, strong) NSNumber *r_man;
@property (nonatomic, strong) NSString *diff;
@property (nonatomic) BOOL subscriptionsDiscounted;
- (instancetype)initWithInfo:(NSArray *)list;
@end
NS_ASSUME_NONNULL_END
@@ -1,82 +0,0 @@
//
// EQNReteSmartphone.m
// Earthquake Network
//
// Created by Luca Beretta on 09/10/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "EQNReteSmartphone.h"
@implementation EQNReteSmartphone
#pragma mark - Init
- (instancetype)initWithInfo:(NSArray *)list
{
self = [super init];
if (self) {
for ( int i = 0; i < list.count; i++) {
NSDictionary *dict = list[i];
switch (i) {
case 0:
_eq = dict[@"eq"];
break;
case 1:
_eq_p = dict[@"eq_p"];
break;
case 2:
_green = dict[@"green"];
break;
case 3:
_g_man = dict[@"g_man"];
break;
case 4:
_y_man = dict[@"y_man"];
break;
case 5:
_r_man = dict[@"r_man"];
break;
case 6:
_diff = dict[@"diff"];
break;
case 7:
self.subscriptionsDiscounted = [dict[@"st"] boolValue];
break;
default:
break;
}
}
}
return self;
}
#pragma mark - NSCoding
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.eq forKey:@"eq"];
[encoder encodeObject:self.eq_p forKey:@"eq_p"];
[encoder encodeObject:self.green forKey:@"green"];
[encoder encodeObject:self.g_man forKey:@"g_man"];
[encoder encodeObject:self.y_man forKey:@"y_man"];
[encoder encodeObject:self.r_man forKey:@"r_man"];
[encoder encodeObject:self.diff forKey:@"diff"];
}
- (instancetype)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if (self) {
self.eq = [decoder decodeObjectForKey:@"eq"];
self.eq_p = [decoder decodeObjectForKey:@"eq_p"];
self.green = [decoder decodeObjectForKey:@"green"];
self.g_man = [decoder decodeObjectForKey:@"g_man"];
self.y_man = [decoder decodeObjectForKey:@"y_man"];
self.r_man = [decoder decodeObjectForKey:@"r_man"];
self.diff = [decoder decodeObjectForKey:@"diff"];
}
return self;
}
@end
@@ -0,0 +1,57 @@
//
// EQNReteSmartphone.swift
// Earthquake Network
//
// Created by Busi Andrea on 08/12/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
import Foundation
@objc
class EQNReteSmartphone: NSObject {
@objc let counterLastDayAlerts: Int
@objc let counterTotalAlerts: Int
@objc let counterSmartphones: Int
@objc let manualGreen: Int
@objc let manualYellow: Int
@objc let manualRed: Int
@objc let lastSubscriptionDiff: Int
@objc let subscriptionsDiscounted: Bool
// MARK: - Init
@objc init(info: [[String: Any]]) {
// merge array in a single dictionary
let allValues = info.reduce([:]) { (result, dictionary) -> [String: Any] in
return result.merging(dictionary, uniquingKeysWith: { (_, new) in new })
}
self.counterLastDayAlerts = Self.getValue(from: allValues, for: "eq")
self.counterTotalAlerts = Self.getValue(from: allValues, for: "eq_p")
self.counterSmartphones = Self.getValue(from: allValues, for: "green")
self.manualGreen = Self.getValue(from: allValues, for: "g_man")
self.manualYellow = Self.getValue(from: allValues, for: "y_man")
self.manualRed = Self.getValue(from: allValues, for: "r_man")
self.lastSubscriptionDiff = Self.getValue(from: allValues, for: "diff")
let subscriptionsDiscounted = Self.getValue(from: allValues, for: "st")
self.subscriptionsDiscounted = subscriptionsDiscounted == 1
super.init()
}
// MARK: - Private
/// This method helps to extract an int value from the received values (where data are both strings and integers).
/// If convertion is not possible, it will return zero.
private static func getValue(from values: [String: Any], for key: String) -> Int {
if let intValue = values[key] as? Int {
return intValue
}
if let stringValue = values[key] as? String, let intValue = Int(stringValue) {
return intValue
}
return 0
}
}
@@ -27,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)inviaPosizioneServer;
- (void)saveUserInfo;
- (void)removeUser;
- (void)verificaRegistrazione;
- (void)downloadOfferTimeRemainingWithCompletion:(timeRemainingCompletion)completionHandler;
+10 -9
View File
@@ -8,7 +8,7 @@
#import "EQNUser.h"
#import "Costanti.h"
#import "EQMAccelerometroManager.h"
#import "EQNAccelerometroManager.h"
#import "ServerRequest.h"
#import "EQNGeneratoreURLServer.h"
#import "EQNUtility.h"
@@ -49,12 +49,12 @@
self.registrato = YES;
}
[[EQMAccelerometroManager sharedInstance] addObserver:(id)self
[[EQNAccelerometroManager sharedInstance] addObserver:(id)self
forKeyPath:@"currentLocation"
options:NSKeyValueObservingOptionNew
context:nil];
[[EQMAccelerometroManager sharedInstance] startUpdatingLocationBackground];
[[EQNAccelerometroManager sharedInstance] startUpdatingLocationBackground];
}
return self;
}
@@ -83,23 +83,23 @@
if ([keyPath isEqualToString:@"currentLocation"]) {
// do some stuff
if (self.lastPosition) {
self.distanza = [self.lastPosition distanceFromLocation:[EQMAccelerometroManager sharedInstance].currentLocation];
self.distanza = [self.lastPosition distanceFromLocation:[EQNAccelerometroManager sharedInstance].currentLocation];
}
self.lastPosition = [EQMAccelerometroManager sharedInstance].currentLocation;
self.lastPosition = [EQNAccelerometroManager sharedInstance].currentLocation;
[self verificaRegistrazione];
if (![EQNManager defaultManager].isBackground)
[[EQMAccelerometroManager sharedInstance] stopUpdatingLocation];
[[EQNAccelerometroManager sharedInstance] stopUpdatingLocation];
}
}
- (void)verificaRegistrazione
{
if (!self.user_ID && self.tokenUser)
if (!self.user_ID && self.tokenUser) {
[self inviaregistrazioneServer:self.tokenUser withPosition:self.lastPosition];
else
} else {
[self inviaPosizioneServer];
}
}
- (void)inviaregistrazioneServer:(NSString *)token withPosition:(CLLocation *)location
@@ -111,6 +111,7 @@
} failure:^(NSError *errore) {
NSLog(@"USER_ID Error %@", errore);
[[NSNotificationCenter defaultCenter] postNotificationName:EQNServerRegistrationDidFailNotification object:nil];
}];
}
@@ -31,11 +31,6 @@ import StoreKit
public typealias ProductIdentifier = String
public typealias ProductsRequestCompletionHandler = (_ success: Bool, _ products: [SKProduct]?) -> Void
extension Notification.Name {
static let IAPHelperPurchaseNotification = Notification.Name("IAPHelperPurchaseNotification")
static let IAPHelperPurchaseNotificationFail = Notification.Name("IAPHelperPurchaseNotificationFail")
}
open class IAPHelper: NSObject {
@@ -83,11 +78,9 @@ extension IAPHelper {
}
public func buyProduct(_ product: SKProduct) {
print("Buying \(product.productIdentifier)...")
print("[IAPHelper] Buying product \(product.productIdentifier)...")
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
}
public func isProductPurchased(_ productIdentifier: ProductIdentifier) -> Bool {
@@ -108,23 +101,17 @@ extension IAPHelper {
extension IAPHelper: SKProductsRequestDelegate {
public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
print("[IAPHelper] Loaded list of products...")
let products = response.products
products.forEach { (p) in
print("[IAPHelper] Found product: \(p.productIdentifier) \(p.localizedTitle) \(p.price.floatValue)")
}
print("[IAPHelper] Products loaded (count: \(response.products.count))")
// this protocol method is not guaranteed to be dispatched on main thread
DispatchQueue.main.async {
self.productsRequestCompletionHandler?(true, products)
self.productsRequestCompletionHandler?(true, response.products)
self.clearRequestAndHandler()
}
}
public func request(_ request: SKRequest, didFailWithError error: Error) {
print("[IAPHelper] Failed to load list of products.")
print("[IAPHelper] Error: \(error.localizedDescription)")
print("[IAPHelper] Failed to load list of products (error: \(error.localizedDescription))")
// this protocol method is not guaranteed to be dispatched on main thread
DispatchQueue.main.async {
@@ -143,18 +130,29 @@ extension IAPHelper: SKProductsRequestDelegate {
extension IAPHelper: SKPaymentTransactionObserver {
public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
print("[IAPHelper] Restore transaction completed")
if queue.transactions.count == 0 {
NotificationCenter.default.post(name: .EQNInAppPurchaseNoTransactions, object: nil)
}
}
public func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
print("[IAPHelper] Restore transaction failed (error : \(error.localizedDescription))")
NotificationCenter.default.post(name: .EQNInAppPurchaseDidFail, object: nil)
}
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("[IAPHelper] Updated transactions (count: \(transactions.count))")
for transaction in transactions {
switch (transaction.transactionState) {
case .purchased:
complete(transaction: transaction)
break
handlePurchased(transaction: transaction)
case .failed:
fail(transaction: transaction)
break
handleFailed(transaction: transaction)
case .restored:
restore(transaction: transaction)
break
handleRestored(transaction: transaction)
case .deferred:
break
case .purchasing:
@@ -165,32 +163,38 @@ extension IAPHelper: SKPaymentTransactionObserver {
}
}
private func complete(transaction: SKPaymentTransaction) {
print("complete...")
private func handlePurchased(transaction: SKPaymentTransaction) {
print("[IAPHelper] Handle purchased transaction (product: \(transaction.payment.productIdentifier))")
deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier)
SKPaymentQueue.default().finishTransaction(transaction)
// register subscription
serverPurchaseRegistration(for: transaction.payment.productIdentifier, transactionId:transaction.transactionIdentifier)
}
private func restore(transaction: SKPaymentTransaction) {
guard let productIdentifier = transaction.original?.payment.productIdentifier else { return }
private func handleRestored(transaction: SKPaymentTransaction) {
guard let productIdentifier = transaction.original?.payment.productIdentifier else {
print("[IAPHelper] Handle restored transaction falied, cannot retrieve productIdentifier")
return
}
print("restore... \(productIdentifier)")
print("[IAPHelper] Handle restored transaction (product: \(productIdentifier))")
deliverPurchaseNotificationFor(identifier: productIdentifier)
SKPaymentQueue.default().finishTransaction(transaction)
// register subscription
serverPurchaseRegistration(for: productIdentifier, transactionId: transaction.transactionIdentifier)
}
private func fail(transaction: SKPaymentTransaction) {
print("fail...")
private func handleFailed(transaction: SKPaymentTransaction) {
print("[IAPHelper] Handle failed transaction (product: \(transaction.payment.productIdentifier))")
if let transactionError = transaction.error as NSError?,
let localizedDescription = transaction.error?.localizedDescription,
transactionError.code != SKError.paymentCancelled.rawValue {
print("Transaction Error: \(localizedDescription)")
print("[IAPHelper] Handle failed transaction error: \(localizedDescription)")
}
NotificationCenter.default.post(name: .IAPHelperPurchaseNotificationFail, object: nil)
NotificationCenter.default.post(name: .EQNInAppPurchaseDidFail, object: nil)
SKPaymentQueue.default().finishTransaction(transaction)
}
@@ -199,8 +203,19 @@ extension IAPHelper: SKPaymentTransactionObserver {
purchasedProductIdentifiers.insert(identifier)
UserDefaults.standard.set(true, forKey: identifier)
NotificationCenter.default.post(name: .IAPHelperPurchaseNotification, object: identifier)
NotificationCenter.default.post(name: .EQNInAppPurchaseDidComplete, object: identifier)
}
private func serverPurchaseRegistration(for productId: String, transactionId: String?) {
let idTransaction = transactionId ?? "NOT_AVAILABLE"
let url = EQNGeneratoreURLServer.urlRegisterSubscription(forProductId: productId, transactionId: idTransaction)
ServerRequest.default().inviaInformazioniAlServer(with: url, richiesta: .registerSubscription) { (response) in
// nope
print("[IAPHelper] Subscription registered with server")
} failure: { (error) in
// nope
print("[IAPHelper] Error when registering subscription (error: \(String(describing: error?.localizedDescription))")
}
}
}
@@ -1,9 +1,9 @@
//
// PastquakesAnnotation.h
// EQNMapAnnotationPastquakes.h
// Earthquake Network
//
// Created by Luca Beretta on 04/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi
// Copyright © 2021 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -11,7 +11,10 @@
NS_ASSUME_NONNULL_BEGIN
@interface PastquakesAnnotation : NSObject <MKAnnotation>
static NSString * const EQNMapAnnotationPastquakesIdentifier = @"EQNMapAnnotationPastquakesIdentifier";
@interface EQNMapAnnotationPastquakes : NSObject <MKAnnotation>
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@@ -1,15 +1,14 @@
//
// PastquakesAnnotation.m
// EQNMapAnnotationPastquakes.m
// Earthquake Network
//
// Created by Luca Beretta on 04/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi
// Copyright © 2021 Earthquake Network. All rights reserved.
//
#import "PastquakesAnnotation.h"
#import "Costanti.h"
#import "EQNMapAnnotationPastquakes.h"
@implementation PastquakesAnnotation
@implementation EQNMapAnnotationPastquakes
#pragma mark - Init
@@ -28,7 +27,7 @@
- (MKAnnotationView *)annotationView
{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:IDENTIFIER_ANNOTATION_PASTQUAKES];
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:EQNMapAnnotationPastquakesIdentifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
NSString *imageString;
@@ -0,0 +1,29 @@
//
// EQNMapAnnotationSeismic.h
// Earthquake Network
//
// Refactored by Andrea Busi
// Copyright © 2021 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
NS_ASSUME_NONNULL_BEGIN
static NSString * const EQNMapAnnotationSeismicIdentifier = @"EQNMapAnnotationSeismicIdentifier";
@interface EQNMapAnnotationSeismic : NSObject <MKAnnotation>
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, readonly) double magnitude;
- (instancetype)initWithTitle:(NSString *)title location:(CLLocationCoordinate2D)coordinate intensita:(double)magnitude;
- (MKAnnotationView *)annotationView;
@end
NS_ASSUME_NONNULL_END
@@ -1,20 +1,21 @@
//
// SismaAnnotation.m
// EQNMapAnnotationSeismic.m
// Earthquake Network
//
// Created by Luca Beretta on 08/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi
// Copyright © 2021 Earthquake Network. All rights reserved.
//
#import "SismaAnnotation.h"
#import "EQNMapAnnotationSeismic.h"
@implementation SismaAnnotation
@implementation EQNMapAnnotationSeismic
-(id)initWithTitle:(NSString *)title location:(CLLocationCoordinate2D )coordinate intensita:(double)magnitude{
#pragma mark - Init
- (instancetype)initWithTitle:(NSString *)title location:(CLLocationCoordinate2D )coordinate intensita:(double)magnitude{
self = [super init];
if (self) {
_title = title;
_coordinate = coordinate;
_magnitude = magnitude;
@@ -22,24 +23,23 @@
return self;
}
-(MKAnnotationView *)annotationView{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:IDENTIFIER_ANNOTATION_SISMI];
#pragma mark - Annotation
- (MKAnnotationView *)annotationView
{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:EQNMapAnnotationSeismicIdentifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
NSString *imageString;
NSLog(@"magnitudo %f", self.magnitude);
if(self.magnitude > 4.0){
if (self.magnitude > 4.0){
imageString = @"dyamond_red";
}else if (self.magnitude < 3.0){
} else if (self.magnitude < 3.0) {
imageString = @"dyamond_green";
}else{
} else {
imageString = @"dyamond_yellow";
}
annotationView.image = [UIImage imageNamed:imageString];
@@ -0,0 +1,29 @@
//
// EQNMapAnnotationSeismicNetwork.h
// Earthquake Network
//
// Refactored by Andrea Busi
// Copyright © 2021 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
NS_ASSUME_NONNULL_BEGIN
static NSString * const EQNMapAnnotationSeismicNetworkIdentifier = @"EQNMapAnnotationSeismicNetworkIdentifier";
@interface EQNMapAnnotationSeismicNetwork : NSObject <MKAnnotation>
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, readonly) int magnitude;
- (instancetype)initWithTitle:(NSString *)title location:(CLLocationCoordinate2D )coordinate magnitudo:(int)magnitude;
- (MKAnnotationView *)annotationView;
@end
NS_ASSUME_NONNULL_END
@@ -1,21 +1,21 @@
//
// ReteSismicaAnnotation.m
// EQNMapAnnotationSeismicNetwork.m
// Earthquake Network
//
// Created by Luca Beretta on 01/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi
// Copyright © 2021 Earthquake Network. All rights reserved.
//
#import "ReteSismicaAnnotation.h"
#import "Costanti.h"
#import "EQNMapAnnotationSeismicNetwork.h"
@implementation ReteSismicaAnnotation
@implementation EQNMapAnnotationSeismicNetwork
-(id)initWithTitle:(NSString *)title location:(CLLocationCoordinate2D )coordinate magnitudo:(int)magnitude{
#pragma mark - Init
- (instancetype)initWithTitle:(NSString *)title location:(CLLocationCoordinate2D )coordinate magnitudo:(int)magnitude
{
self = [super init];
if (self) {
_title = title;
_coordinate = coordinate;
_magnitude = magnitude;
@@ -23,11 +23,14 @@
return self;
}
-(MKAnnotationView *)annotationView{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:IDENTIFIER_ANNOTATION_RETESMARTPHONE];
#pragma mark - Public
- (MKAnnotationView *)annotationView
{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:EQNMapAnnotationSeismicNetworkIdentifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
NSString *imageString;
switch (self.magnitude) {
case 1:
@@ -48,4 +51,5 @@
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
@end
@@ -1,5 +1,5 @@
//
// EQMAccelerometroManager.h
// EQNAccelerometroManager.h
// Earthquake Network
//
// Created by Luca Beretta on 19/09/18.
@@ -11,7 +11,7 @@
NS_ASSUME_NONNULL_BEGIN
@interface EQMAccelerometroManager : NSObject
@interface EQNAccelerometroManager : NSObject
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic, nullable) CLLocation *currentLocation;
@@ -1,29 +1,29 @@
//
// EQMAccelerometroManager.m
// EQNAccelerometroManager.m
// Earthquake Network
//
// Created by Luca Beretta on 19/09/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "EQMAccelerometroManager.h"
#import "EQNAccelerometroManager.h"
#import <CoreMotion/CoreMotion.h>
#import "Costanti.h"
#import "EQNMath.h"
#import "EQNUser.h"
#import "EQNManager.h"
@interface EQMAccelerometroManager () <CLLocationManagerDelegate>
@interface EQNAccelerometroManager () <CLLocationManagerDelegate>
@property (nonatomic, assign) BOOL posizioneRilevata;
@end
@implementation EQMAccelerometroManager
@implementation EQNAccelerometroManager
#pragma mark - Singleton
+ (instancetype)sharedInstance
{
static EQMAccelerometroManager *instance = nil;
static EQNAccelerometroManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc]init];
@@ -36,7 +36,7 @@
- (instancetype)init
{
self = [super init];
if(self) {
if (self) {
self.locationManager = [[CLLocationManager alloc] init];
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){
[self.locationManager requestAlwaysAuthorization];
@@ -74,7 +74,7 @@
break;
}
[[NSNotificationCenter defaultCenter] postNotificationName:EQNNotificationDidChangeAuthorizationStatus object:nil userInfo:@{}];
[[NSNotificationCenter defaultCenter] postNotificationName:EQNAuthorizationStatusDidChangeNotification object:nil userInfo:@{}];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
@@ -9,7 +9,9 @@
#import <Foundation/Foundation.h>
#import "Costanti.h"
@interface EQNCalibrazione : NSObject <NSCopying>
NS_ASSUME_NONNULL_BEGIN
@interface EQNCalibrazione : NSObject <NSCopying>
@property (nonatomic, assign) float media;
@property (nonatomic, assign) float deviazione;
@@ -17,8 +19,8 @@
@property (nonatomic, assign) EQNStatoCal stato;
+(void)startCalibrazione:(void(^)(EQNCalibrazione *cal))cal;
//-(NSString *)serverMessage;
+ (void)startCalibrazione:(void(^)(EQNCalibrazione *cal))cal;
@end
NS_ASSUME_NONNULL_END
@@ -8,14 +8,27 @@
#import "EQNCalibrazione.h"
#import "EQNMath.h"
#import "EQMAccelerometroManager.h"
#import "EQNAccelerometroManager.h"
@implementation EQNCalibrazione
+(void)startCalibrazione:(void(^)(EQNCalibrazione *cal))cal{
#pragma mark - NSCopying
[EQMAccelerometroManager avviaLetturaAccellerometroIsCalibrazione:YES withCompletion:^(NSArray *dati) {
// [[EQMAccelerometroManager sharedInstance] startUpdatingLocation];
- (id)copyWithZone:(NSZone *)zone
{
EQNCalibrazione *model = [[[self class] allocWithZone:zone] init];
model.media = self.media;
model.deviazione = self.deviazione;
model.r3 = self.r3;
model.stato = self.stato;
return model;
}
#pragma mark - Public
+ (void)startCalibrazione:(void(^)(EQNCalibrazione *cal))cal
{
[EQNAccelerometroManager avviaLetturaAccellerometroIsCalibrazione:YES withCompletion:^(NSArray *dati) {
EQNCalibrazione *calibrazione = [[EQNCalibrazione alloc] init];
calibrazione.media = [[EQNMath meanOf:dati] floatValue];
calibrazione.deviazione = [[EQNMath standardDeviationOf:dati] floatValue];
@@ -23,29 +36,15 @@
float max = [rDic[rMax] floatValue] - calibrazione.media;
float min = [rDic[rMin] floatValue] - calibrazione.media;
calibrazione.r3 = max;
if ( max != min){
if (max != min){
if (min > SOGLIAMIN && max < SOGLIAMAX){
calibrazione.stato = calibrato;
}else
} else {
calibrazione.stato = nonCalibrato;
}
}
cal(calibrazione);
}];
}
-(id)copyWithZone:(NSZone *)zone {
EQNCalibrazione *model = [[[self class] allocWithZone:zone] init];
model.media = self.media;
model.deviazione = self.deviazione;
model.r3 = self.r3;
model.stato = self.stato;
return model;
}
@end
@@ -9,15 +9,22 @@
#import <Foundation/Foundation.h>
#import <CoreMotion/CoreMotion.h>
NS_ASSUME_NONNULL_BEGIN
@interface EQNMath : NSObject
// calcola la somma dei quadrati delle assi/G ottenute dall'accelerometro
/// Calcola la somma dei quadrati delle assi/G ottenute dall'accelerometro
+ (float)powSum:(CMAccelerometerData *)accelerometerData;
// calcola la media dei valori contenuta nell'array passato
/// Calcola la media dei valori contenuta nell'array passato
+ (NSNumber *)meanOf:(NSArray *)array;
// calcola la deviazione standard dei valori contenuti nell'array passato
+ (NSNumber *)standardDeviationOf:(NSArray *)array;
// restituisce valore massimo e valore minimo contenuto nellarray
/// Calcola la deviazione standard dei valori contenuti nell'array passato
+ (nullable NSNumber *)standardDeviationOf:(NSArray *)array;
// Restituisce valore massimo e valore minimo contenuto nellarray
+ (NSDictionary *)rLimiti:(NSArray *)array;
@end
NS_ASSUME_NONNULL_END
@@ -7,12 +7,14 @@
//
#import "EQNMath.h"
#include <math.h>
#import "Costanti.h"
#include <math.h>
@implementation EQNMath
#pragma mark - Public
+ (float)powSum:(CMAccelerometerData *)accelerometerData {
return sqrt(pow(accelerometerData.acceleration.x, 2.0)+pow(accelerometerData.acceleration.y, 2.0)+pow(accelerometerData.acceleration.z, 2.0));
@@ -21,7 +23,7 @@
+ (NSNumber *)meanOf:(NSArray *)array
{
double runningTotal = 0.0;
for(NSNumber *number in array)
for (NSNumber *number in array)
{
runningTotal += [number doubleValue];
}
@@ -31,10 +33,12 @@
+ (NSNumber *)standardDeviationOf:(NSArray *)array
{
if(![array count]) return nil;
if (![array count]) {
return nil;
}
double mean = [[self meanOf:array] doubleValue];
double sumOfSquaredDifferences = 0.0;
for(NSNumber *number in array)
for (NSNumber *number in array)
{
double valueOfNumber = [number doubleValue];
double difference = valueOfNumber - mean;
@@ -43,8 +47,9 @@
return [NSNumber numberWithDouble:sqrt(sumOfSquaredDifferences / [array count])];
}
+ (NSDictionary *)rLimiti:(NSArray *)array{
+ (NSDictionary *)rLimiti:(NSArray *)array
{
float xmax = -MAXFLOAT;
float xmin = MAXFLOAT;
@@ -56,4 +61,5 @@
return @{rMax : @(xmax), rMin : @(xmin)};
}
@end
@@ -10,6 +10,13 @@
#import "EQNCalibrazione.h"
#import "Costanti.h"
NS_ASSUME_NONNULL_BEGIN
@class EQNRilevamento;
typedef void (^calibrationCompletion)(EQNRilevamento * _Nullable rilevamento);
@interface EQNRilevamento : NSObject
@property (nonatomic, assign) float media;
@@ -18,7 +25,11 @@
@property (nonatomic, assign) EQNRilevamentoSoglia rilievo;
@property (nonatomic, strong) NSDate *timestamp;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithMedia:(float)media deviazione:(float)deviazione maxAssoluto:(float)maxAssoluto rilievo:(EQNRilevamentoSoglia)rilievo timestamp:(NSDate *)timestamp;
+(void)startRilevamentoWithCalibrazione:(EQNCalibrazione *)cal result:(void(^)(EQNRilevamento *ril))rilevamento;
+ (void)startRilevamentoWithCalibrazione:(EQNCalibrazione *)cal result:(calibrationCompletion)rilevamento;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,57 @@
//
// EQNRilevamento.m
// Earthquake Network
//
// Created by Luca Beretta on 19/09/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "EQNRilevamento.h"
#import <CoreMotion/CoreMotion.h>
#import "EQNMath.h"
#import "EQNAccelerometroManager.h"
@implementation EQNRilevamento
#pragma mark - Init
- (instancetype)initWithMedia:(float)media deviazione:(float)deviazione maxAssoluto:(float)maxAssoluto rilievo:(EQNRilevamentoSoglia)rilievo timestamp:(NSDate *)timestamp
{
self = [super init];
if (self) {
self.media = media;
self.deviazione = deviazione;
self.maxAssoluto = maxAssoluto;
self.rilievo = rilievo;
self.timestamp = timestamp;
}
return self;
}
#pragma mark - Public
+ (void)startRilevamentoWithCalibrazione:(EQNCalibrazione *)cal result:(calibrationCompletion)rilevamento
{
if (!cal) {
rilevamento(nil);
return;
}
[EQNAccelerometroManager avviaLetturaAccellerometroIsCalibrazione:NO withCompletion:^(NSArray *dati) {
float media = [[EQNMath meanOf:dati] floatValue];
float deviazione = [[EQNMath standardDeviationOf:dati] floatValue];
NSDictionary *rDic = [EQNMath rLimiti:dati];
float max = [rDic[rMax] floatValue] - cal.media;
float maxAssoluto = fabsf(max);
EQNRilevamentoSoglia rilievo = (deviazione > SOGLIA_DEVIAZIONE_RILIEVO*cal.deviazione) ? EQNRilevamentoSogliaPositivo : EQNRilevamentoSogliaNegativo;
EQNRilevamento *aRilievo = [[EQNRilevamento alloc] initWithMedia:media
deviazione:deviazione
maxAssoluto:maxAssoluto
rilievo:rilievo
timestamp:[NSDate date]];
rilevamento(aRilievo);
}];
}
@end
@@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSURL *)urlInvioCommentoTerremoto:(NSString *)commento codeMessage:(NSString *)code;
+ (NSURL *)urlInvioImpostazioniNotifiche;
+ (NSURL *)urlDownloadOfferTimeRemaining;
+ (NSURL *)urlRegisterSubscriptionForProductId:(NSString *)productId transactionId:(NSString *)transactionId;
+ (NSURL *)urlAlertPushTest;
+ (NSURL *)urlAlertSimulator;
@@ -48,7 +48,7 @@
NSString *e_t = @"0";
NSString *a_max = @"0";
if (rilevamento.rilievo == positivo){
if (rilevamento.rilievo == EQNRilevamentoSogliaPositivo){
e_t = @"1";
a_max =[NSString stringWithFormat:@"%f",rilevamento.maxAssoluto];
}
@@ -243,6 +243,13 @@
return [NSURL URLWithString:stringUrl];
}
+ (NSURL *)urlRegisterSubscriptionForProductId:(NSString *)productId transactionId:(NSString *)transactionId
{
NSString *walletSub = @""; // codice associato all'acquisto che conosce anche l'utente (se esiste)
NSString *stringUrl = [NSString stringWithFormat:@"%@?u_id=%@&token_sub=%@&wallet_sub=%@&sku=%@&ios=1", EQNServerUrlRegisterSubscription, [EQNUser defaultUser].user_ID, transactionId, walletSub, productId];
return [NSURL URLWithString:stringUrl];
}
+ (NSURL *)urlAlertPushTest
{
EQNGenericValue *radius = [EQNData raggioSismaFor:[EQNAllertaSismica sharedInstance].raggioSismiLievi];
@@ -7,7 +7,6 @@
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "Costanti.h"
NS_ASSUME_NONNULL_BEGIN
@@ -24,6 +23,8 @@ typedef void (^errorCompletionHandler)(NSError * _Nullable error);
- (void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata)chiamata success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure;
/// NOTA: questo metodo è implementato ma non contiene un URL valido per l'invio della ricevuta
/// Al momento non viene utilizzato dall'app perchè è inutile
- (void)inviaRicevuta:(NSData *)ricevuta success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure;
@end
@@ -125,7 +125,7 @@
}
} else {
NSString *newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (newStr) {
if (newStr && (httpResp.statusCode >= 200 && httpResp.statusCode <= 299)) {
if (EQNDebugPrintResponse) {
NSLog(@"[ServerRequest] response string: %@", newStr);
}
@@ -140,6 +140,7 @@
case EQNTipoChiamataCalibrazione:
case EQNTipoChiamataImpostazioniNotifiche:
case EQNTipoChiamataAlertSimulator:
case EQNTipoChiamataRegisterSubscription:
onSuccess(newStr);
default:
// don't call the callback
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="CWo-PE-Dqp">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="CWo-PE-Dqp">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17126"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -313,29 +313,19 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="q4o-YO-KLX">
<rect key="frame" x="0.0" y="140" width="414" height="618"/>
<rect key="frame" x="0.0" y="140" width="414" height="673"/>
<connections>
<outlet property="dataSource" destination="tVM-DH-fmv" id="XVf-fb-5Kl"/>
<outlet property="delegate" destination="tVM-DH-fmv" id="dWO-2A-Ukg"/>
</connections>
</tableView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Nac-25-EPW">
<rect key="frame" x="0.0" y="758" width="414" height="55"/>
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="55" id="GGM-Kn-QVU"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="VUD-fs-xgm"/>
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
<constraints>
<constraint firstItem="VUD-fs-xgm" firstAttribute="bottom" secondItem="q4o-YO-KLX" secondAttribute="bottom" id="3P1-fP-chi"/>
<constraint firstItem="q4o-YO-KLX" firstAttribute="top" secondItem="VUD-fs-xgm" secondAttribute="top" id="IeK-TW-jL5"/>
<constraint firstItem="Nac-25-EPW" firstAttribute="top" secondItem="q4o-YO-KLX" secondAttribute="bottom" id="TKT-yo-pRg"/>
<constraint firstItem="Nac-25-EPW" firstAttribute="bottom" secondItem="VUD-fs-xgm" secondAttribute="bottom" id="YXT-r6-DPc"/>
<constraint firstItem="q4o-YO-KLX" firstAttribute="leading" secondItem="VUD-fs-xgm" secondAttribute="leading" id="Yyx-Tc-hnn"/>
<constraint firstItem="Nac-25-EPW" firstAttribute="trailing" secondItem="VUD-fs-xgm" secondAttribute="trailing" id="a5L-LI-EDT"/>
<constraint firstItem="Nac-25-EPW" firstAttribute="leading" secondItem="VUD-fs-xgm" secondAttribute="leading" id="gFt-0T-8rP"/>
<constraint firstItem="VUD-fs-xgm" firstAttribute="trailing" secondItem="q4o-YO-KLX" secondAttribute="trailing" id="yd6-Pa-c2s"/>
</constraints>
</view>
@@ -364,15 +354,13 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
</rightBarButtonItems>
</navigationItem>
<connections>
<outlet property="bannerContainerHeightConstraint" destination="GGM-Kn-QVU" id="vm3-SN-HrQ"/>
<outlet property="bannerContainerView" destination="Nac-25-EPW" id="aJ3-kF-jA3"/>
<outlet property="expandeCollapseButton" destination="HTN-07-s5p" id="lxP-Im-NME"/>
<outlet property="tableView" destination="q4o-YO-KLX" id="tee-h5-dZi"/>
<segue destination="LHm-XT-f2y" kind="presentation" identifier="ShowMapDetail" id="say-mL-Iyg"/>
<segue destination="rZ4-xN-lLk" kind="presentation" identifier="ShowSettings" modalPresentationStyle="overCurrentContext" modalTransitionStyle="crossDissolve" id="5R7-S8-R7P"/>
<segue destination="lTI-GM-Lum" kind="presentation" identifier="ShowSeismicNetworks" id="JKE-mg-BIk"/>
<segue destination="6LP-zk-O1z" kind="presentation" identifier="ShowFilters" modalPresentationStyle="overCurrentContext" modalTransitionStyle="crossDissolve" id="Nzu-iH-UgB"/>
<segue destination="Rfp-kt-2Kx" kind="presentation" identifier="ShowCardSettings" modalPresentationStyle="overCurrentContext" modalTransitionStyle="crossDissolve" id="VWw-16-xGw"/>
<segue destination="6Ia-ax-PLl" kind="presentation" identifier="ShowMapDetail" id="UNr-Av-Xcw"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="34i-9D-p3O" userLabel="First Responder" sceneMemberID="firstResponder"/>
@@ -1228,7 +1216,7 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
<toolbarItems/>
<navigationItem key="navigationItem" id="oAm-fG-yGd"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Lnw-v0-Fdj">
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="56"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
@@ -1245,14 +1233,14 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
<objects>
<viewController id="fdS-yL-Xoy" customClass="PastquakesDettagliMappa" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="rHU-U8-Tsf">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="842"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="ExJ-I4-Mfq">
<rect key="frame" x="0.0" y="88" width="414" height="670"/>
<rect key="frame" x="0.0" y="56" width="414" height="647"/>
</mapView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lSE-rp-Mve">
<rect key="frame" x="0.0" y="758" width="414" height="55"/>
<rect key="frame" x="0.0" y="703" width="414" height="55"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GCe-cb-Wlp">
<rect key="frame" x="15" y="0.0" width="344" height="55"/>
@@ -1263,49 +1251,59 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_arrow_drop_down_48px-128" translatesAutoresizingMaskIntoConstraints="NO" id="8sR-8Z-tr5">
<rect key="frame" x="359" y="0.0" width="55" height="55"/>
<constraints>
<constraint firstAttribute="height" constant="55" id="Wv0-Fq-H0d"/>
<constraint firstAttribute="width" constant="55" id="dDZ-PW-YZZ"/>
<constraint firstAttribute="width" constant="55" id="vPg-iW-NEN"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="GCe-cb-Wlp" firstAttribute="top" secondItem="lSE-rp-Mve" secondAttribute="top" id="6c0-XC-3aA"/>
<constraint firstAttribute="bottom" secondItem="GCe-cb-Wlp" secondAttribute="bottom" id="HGX-Hi-6IM"/>
<constraint firstAttribute="trailing" secondItem="8sR-8Z-tr5" secondAttribute="trailing" id="RvX-fW-xAe"/>
<constraint firstAttribute="height" constant="55" id="Tlh-ri-Vgd"/>
<constraint firstItem="8sR-8Z-tr5" firstAttribute="top" secondItem="lSE-rp-Mve" secondAttribute="top" id="krQ-yR-gxi"/>
<constraint firstAttribute="bottom" secondItem="8sR-8Z-tr5" secondAttribute="bottom" id="ks6-xX-xcg"/>
<constraint firstItem="8sR-8Z-tr5" firstAttribute="leading" secondItem="GCe-cb-Wlp" secondAttribute="trailing" id="qPA-Nd-emF"/>
<constraint firstItem="GCe-cb-Wlp" firstAttribute="leading" secondItem="lSE-rp-Mve" secondAttribute="leading" constant="15" id="uRw-tP-FQm"/>
<constraint firstAttribute="bottom" secondItem="GCe-cb-Wlp" secondAttribute="bottom" id="1Es-Ic-xO6"/>
<constraint firstAttribute="trailing" secondItem="8sR-8Z-tr5" secondAttribute="trailing" id="7eT-TU-wHu"/>
<constraint firstItem="GCe-cb-Wlp" firstAttribute="top" secondItem="lSE-rp-Mve" secondAttribute="top" id="8xw-ns-HjS"/>
<constraint firstAttribute="height" constant="55" id="Flj-Sf-TI2"/>
<constraint firstAttribute="bottom" secondItem="8sR-8Z-tr5" secondAttribute="bottom" id="Nds-Py-0SE"/>
<constraint firstItem="8sR-8Z-tr5" firstAttribute="leading" secondItem="GCe-cb-Wlp" secondAttribute="trailing" id="ddM-AV-wik"/>
<constraint firstItem="GCe-cb-Wlp" firstAttribute="leading" secondItem="lSE-rp-Mve" secondAttribute="leading" constant="15" id="fJx-Rh-0JH"/>
<constraint firstItem="8sR-8Z-tr5" firstAttribute="top" secondItem="lSE-rp-Mve" secondAttribute="top" id="vLj-f9-flk"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eqZ-br-SO8">
<rect key="frame" x="0.0" y="758" width="414" height="55"/>
<rect key="frame" x="0.0" y="703" width="414" height="55"/>
<connections>
<action selector="visualizzaPikerFiltro:" destination="fdS-yL-Xoy" eventType="touchUpInside" id="OCO-nd-ca2"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tRo-KE-tea">
<rect key="frame" x="0.0" y="758" width="414" height="50"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="Bcg-7j-fRh"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="F4b-eJ-oaF"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="eqZ-br-SO8" firstAttribute="bottom" secondItem="F4b-eJ-oaF" secondAttribute="bottom" id="3uM-y4-ucm"/>
<constraint firstItem="lSE-rp-Mve" firstAttribute="bottom" secondItem="F4b-eJ-oaF" secondAttribute="bottom" id="PFu-3h-T0C"/>
<constraint firstItem="ExJ-I4-Mfq" firstAttribute="leading" secondItem="F4b-eJ-oaF" secondAttribute="leading" id="PeC-ya-jB9"/>
<constraint firstItem="ExJ-I4-Mfq" firstAttribute="trailing" secondItem="F4b-eJ-oaF" secondAttribute="trailing" id="Seq-if-3LN"/>
<constraint firstItem="lSE-rp-Mve" firstAttribute="top" secondItem="ExJ-I4-Mfq" secondAttribute="bottom" id="Sz6-3c-zdx"/>
<constraint firstItem="eqZ-br-SO8" firstAttribute="leading" secondItem="F4b-eJ-oaF" secondAttribute="leading" id="TZ4-ht-eeM"/>
<constraint firstItem="F4b-eJ-oaF" firstAttribute="bottom" secondItem="ExJ-I4-Mfq" secondAttribute="bottom" constant="55" id="Ybj-Hf-gP1"/>
<constraint firstItem="ExJ-I4-Mfq" firstAttribute="top" secondItem="F4b-eJ-oaF" secondAttribute="top" id="gVx-Xt-pEl"/>
<constraint firstItem="eqZ-br-SO8" firstAttribute="top" secondItem="ExJ-I4-Mfq" secondAttribute="bottom" id="gq4-P9-TJp"/>
<constraint firstItem="lSE-rp-Mve" firstAttribute="leading" secondItem="F4b-eJ-oaF" secondAttribute="leading" id="iU0-nH-fMB"/>
<constraint firstItem="eqZ-br-SO8" firstAttribute="trailing" secondItem="F4b-eJ-oaF" secondAttribute="trailing" id="ifh-cM-CCe"/>
<constraint firstItem="lSE-rp-Mve" firstAttribute="trailing" secondItem="F4b-eJ-oaF" secondAttribute="trailing" id="nNF-Ef-z8Z"/>
<constraint firstItem="ExJ-I4-Mfq" firstAttribute="top" secondItem="F4b-eJ-oaF" secondAttribute="top" id="7Cd-tF-c9l"/>
<constraint firstItem="lSE-rp-Mve" firstAttribute="leading" secondItem="F4b-eJ-oaF" secondAttribute="leading" id="DLZ-Tv-d6i"/>
<constraint firstItem="eqZ-br-SO8" firstAttribute="height" secondItem="lSE-rp-Mve" secondAttribute="height" id="Hwc-Cd-Xly"/>
<constraint firstItem="eqZ-br-SO8" firstAttribute="width" secondItem="lSE-rp-Mve" secondAttribute="width" id="PmS-Gh-hNB"/>
<constraint firstItem="lSE-rp-Mve" firstAttribute="trailing" secondItem="F4b-eJ-oaF" secondAttribute="trailing" id="ZgG-Ya-dxQ"/>
<constraint firstItem="tRo-KE-tea" firstAttribute="top" secondItem="lSE-rp-Mve" secondAttribute="bottom" id="eIS-dn-Cze"/>
<constraint firstItem="tRo-KE-tea" firstAttribute="bottom" secondItem="F4b-eJ-oaF" secondAttribute="bottom" id="efc-bq-Uq3"/>
<constraint firstItem="eqZ-br-SO8" firstAttribute="centerY" secondItem="lSE-rp-Mve" secondAttribute="centerY" id="gp1-zh-3Hn"/>
<constraint firstItem="ExJ-I4-Mfq" firstAttribute="leading" secondItem="F4b-eJ-oaF" secondAttribute="leading" id="jFg-f9-Kju"/>
<constraint firstItem="eqZ-br-SO8" firstAttribute="centerX" secondItem="lSE-rp-Mve" secondAttribute="centerX" id="kZM-ig-qxe"/>
<constraint firstItem="tRo-KE-tea" firstAttribute="trailing" secondItem="F4b-eJ-oaF" secondAttribute="trailing" id="oMi-WC-0ee"/>
<constraint firstItem="tRo-KE-tea" firstAttribute="leading" secondItem="F4b-eJ-oaF" secondAttribute="leading" id="pLa-Hb-kK6"/>
<constraint firstItem="ExJ-I4-Mfq" firstAttribute="trailing" secondItem="F4b-eJ-oaF" secondAttribute="trailing" id="pO5-eS-Yst"/>
<constraint firstItem="lSE-rp-Mve" firstAttribute="top" secondItem="ExJ-I4-Mfq" secondAttribute="bottom" id="pyZ-S1-2EU"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="1lc-GD-9UQ"/>
<connections>
<outlet property="bannerContainerHeightConstraint" destination="Bcg-7j-fRh" id="6eX-0S-NXy"/>
<outlet property="bannerContainerView" destination="tRo-KE-tea" id="K8n-uF-e4r"/>
<outlet property="buttonAzione" destination="eqZ-br-SO8" id="dh1-pF-aTB"/>
<outlet property="containerView" destination="lSE-rp-Mve" id="ckk-gd-YSf"/>
<outlet property="imageAzione" destination="8sR-8Z-tr5" id="SGO-zu-R0w"/>
@@ -1315,7 +1313,7 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Q8y-Fc-DjQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-4413.75" y="-7439.788732394366"/>
<point key="canvasLocation" x="-4414.4927536231889" y="-7440.4017857142853"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="pK6-is-2fg">
@@ -1344,10 +1342,23 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="iko-a1-LWv">
<rect key="frame" x="0.0" y="56" width="414" height="697"/>
<rect key="frame" x="0.0" y="56" width="414" height="647"/>
</mapView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CTZ-OY-cgW">
<rect key="frame" x="0.0" y="703" width="414" height="55"/>
<connections>
<action selector="visualizzaPikerFiltro:" destination="pNh-Ni-Yv5" eventType="touchUpInside" id="eoW-3k-k9E"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kCt-Dd-MaY">
<rect key="frame" x="0.0" y="758" width="414" height="50"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="ljc-h5-JHC"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8TU-C5-fRW">
<rect key="frame" x="0.0" y="753" width="414" height="55"/>
<rect key="frame" x="0.0" y="703" width="414" height="55"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Sx2-Xi-NrV">
<rect key="frame" x="15" y="0.0" width="344" height="55"/>
@@ -1358,49 +1369,46 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_arrow_drop_down_48px-128" translatesAutoresizingMaskIntoConstraints="NO" id="pv8-Xy-9z0">
<rect key="frame" x="359" y="0.0" width="55" height="55"/>
<constraints>
<constraint firstAttribute="height" constant="55" id="Kme-YI-quM"/>
<constraint firstAttribute="width" constant="55" id="P1j-Ao-TXX"/>
<constraint firstAttribute="width" constant="55" id="gT5-qw-bCr"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="pv8-Xy-9z0" firstAttribute="leading" secondItem="Sx2-Xi-NrV" secondAttribute="trailing" id="0AN-IL-loQ"/>
<constraint firstAttribute="bottom" secondItem="pv8-Xy-9z0" secondAttribute="bottom" id="7J3-0E-PIb"/>
<constraint firstItem="Sx2-Xi-NrV" firstAttribute="top" secondItem="8TU-C5-fRW" secondAttribute="top" id="8ES-et-vzx"/>
<constraint firstAttribute="bottom" secondItem="Sx2-Xi-NrV" secondAttribute="bottom" id="EO2-Kp-MPQ"/>
<constraint firstItem="Sx2-Xi-NrV" firstAttribute="leading" secondItem="8TU-C5-fRW" secondAttribute="leading" constant="15" id="anH-2w-cLJ"/>
<constraint firstAttribute="trailing" secondItem="pv8-Xy-9z0" secondAttribute="trailing" id="eN7-l2-b5V"/>
<constraint firstAttribute="height" constant="55" id="j1c-n2-b4Y"/>
<constraint firstItem="pv8-Xy-9z0" firstAttribute="top" secondItem="8TU-C5-fRW" secondAttribute="top" id="s6s-F4-AW3"/>
<constraint firstAttribute="height" constant="55" id="3s0-7U-bQj"/>
<constraint firstItem="pv8-Xy-9z0" firstAttribute="leading" secondItem="Sx2-Xi-NrV" secondAttribute="trailing" id="Ba8-Rj-cIS"/>
<constraint firstAttribute="bottom" secondItem="Sx2-Xi-NrV" secondAttribute="bottom" id="H0f-c4-IVt"/>
<constraint firstItem="Sx2-Xi-NrV" firstAttribute="leading" secondItem="8TU-C5-fRW" secondAttribute="leading" constant="15" id="HOa-2v-KDD"/>
<constraint firstAttribute="bottom" secondItem="pv8-Xy-9z0" secondAttribute="bottom" id="Zse-cX-dcV"/>
<constraint firstAttribute="trailing" secondItem="pv8-Xy-9z0" secondAttribute="trailing" id="kjJ-Jx-Ioi"/>
<constraint firstItem="Sx2-Xi-NrV" firstAttribute="top" secondItem="8TU-C5-fRW" secondAttribute="top" id="tKe-p2-O3p"/>
<constraint firstItem="pv8-Xy-9z0" firstAttribute="top" secondItem="8TU-C5-fRW" secondAttribute="top" id="wYT-x6-A1N"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CTZ-OY-cgW">
<rect key="frame" x="0.0" y="753" width="414" height="55"/>
<connections>
<action selector="visualizzaPikerFiltro:" destination="pNh-Ni-Yv5" eventType="touchUpInside" id="eoW-3k-k9E"/>
</connections>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="fDH-pM-Eay"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="CTZ-OY-cgW" firstAttribute="leading" secondItem="fDH-pM-Eay" secondAttribute="leading" id="4kg-Dv-bIf"/>
<constraint firstItem="CTZ-OY-cgW" firstAttribute="bottom" secondItem="fDH-pM-Eay" secondAttribute="bottom" id="6va-wN-8eE"/>
<constraint firstItem="8TU-C5-fRW" firstAttribute="top" secondItem="iko-a1-LWv" secondAttribute="bottom" id="Fjo-LQ-gHL"/>
<constraint firstItem="8TU-C5-fRW" firstAttribute="leading" secondItem="fDH-pM-Eay" secondAttribute="leading" id="N2u-wn-Bxt"/>
<constraint firstItem="iko-a1-LWv" firstAttribute="trailing" secondItem="fDH-pM-Eay" secondAttribute="trailing" id="SGY-iP-sD6"/>
<constraint firstItem="iko-a1-LWv" firstAttribute="top" secondItem="fDH-pM-Eay" secondAttribute="top" id="SL9-Jt-R7x"/>
<constraint firstItem="CTZ-OY-cgW" firstAttribute="trailing" secondItem="fDH-pM-Eay" secondAttribute="trailing" id="SP7-gs-RfF"/>
<constraint firstItem="iko-a1-LWv" firstAttribute="leading" secondItem="fDH-pM-Eay" secondAttribute="leading" id="Y29-aa-3yq"/>
<constraint firstItem="8TU-C5-fRW" firstAttribute="trailing" secondItem="fDH-pM-Eay" secondAttribute="trailing" id="kym-06-eOn"/>
<constraint firstItem="fDH-pM-Eay" firstAttribute="bottom" secondItem="iko-a1-LWv" secondAttribute="bottom" constant="55" id="m89-E5-28R"/>
<constraint firstItem="8TU-C5-fRW" firstAttribute="bottom" secondItem="fDH-pM-Eay" secondAttribute="bottom" id="tbB-Et-6Pb"/>
<constraint firstItem="CTZ-OY-cgW" firstAttribute="top" secondItem="iko-a1-LWv" secondAttribute="bottom" id="wkd-56-YTg"/>
<constraint firstItem="8TU-C5-fRW" firstAttribute="trailing" secondItem="fDH-pM-Eay" secondAttribute="trailing" id="1L6-2l-kr2"/>
<constraint firstItem="iko-a1-LWv" firstAttribute="top" secondItem="fDH-pM-Eay" secondAttribute="top" id="FCZ-a9-IpJ"/>
<constraint firstItem="CTZ-OY-cgW" firstAttribute="width" secondItem="8TU-C5-fRW" secondAttribute="width" id="Haq-uM-Pk9"/>
<constraint firstItem="8TU-C5-fRW" firstAttribute="leading" secondItem="fDH-pM-Eay" secondAttribute="leading" id="NXE-Lw-aXn"/>
<constraint firstItem="kCt-Dd-MaY" firstAttribute="top" secondItem="8TU-C5-fRW" secondAttribute="bottom" id="d1j-xi-Kvc"/>
<constraint firstItem="kCt-Dd-MaY" firstAttribute="trailing" secondItem="fDH-pM-Eay" secondAttribute="trailing" id="fle-IU-Uqv"/>
<constraint firstItem="CTZ-OY-cgW" firstAttribute="centerX" secondItem="8TU-C5-fRW" secondAttribute="centerX" id="fuC-ta-9tn"/>
<constraint firstItem="8TU-C5-fRW" firstAttribute="top" secondItem="iko-a1-LWv" secondAttribute="bottom" id="iDZ-TX-1dv"/>
<constraint firstItem="iko-a1-LWv" firstAttribute="leading" secondItem="fDH-pM-Eay" secondAttribute="leading" id="n2e-k3-tjm"/>
<constraint firstItem="kCt-Dd-MaY" firstAttribute="leading" secondItem="fDH-pM-Eay" secondAttribute="leading" id="ors-Mh-Crn"/>
<constraint firstItem="CTZ-OY-cgW" firstAttribute="centerY" secondItem="8TU-C5-fRW" secondAttribute="centerY" id="qNd-8j-uYC"/>
<constraint firstItem="iko-a1-LWv" firstAttribute="trailing" secondItem="fDH-pM-Eay" secondAttribute="trailing" id="rTW-4m-9My"/>
<constraint firstItem="CTZ-OY-cgW" firstAttribute="height" secondItem="8TU-C5-fRW" secondAttribute="height" id="vkj-Xb-NpT"/>
<constraint firstItem="kCt-Dd-MaY" firstAttribute="bottom" secondItem="fDH-pM-Eay" secondAttribute="bottom" id="wSn-ss-ZAz"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="aQo-9D-Bwb"/>
<connections>
<outlet property="bannerContainerHeightConstraint" destination="ljc-h5-JHC" id="5OR-fA-Hrx"/>
<outlet property="bannerContainerView" destination="kCt-Dd-MaY" id="BVk-Cz-RfM"/>
<outlet property="buttonAzione" destination="CTZ-OY-cgW" id="dG4-M5-PPF"/>
<outlet property="containerView" destination="8TU-C5-fRW" id="d4g-SV-NI6"/>
<outlet property="imageAzione" destination="pv8-Xy-9z0" id="pLN-TH-GdZ"/>
@@ -1410,7 +1418,7 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="rgA-5b-IRk" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-6178" y="-6364"/>
<point key="canvasLocation" x="-6178.2608695652179" y="-6364.2857142857138"/>
</scene>
<!--Log View Controller-->
<scene sceneID="bCB-QP-zCq">
@@ -1457,53 +1465,50 @@ In più sostieni il progetto di ricerca il quale non riceve finanziamenti estern
</objects>
<point key="canvasLocation" x="-10929" y="-7374"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="DjR-k2-Uke">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="LHm-XT-f2y" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="zMO-g0-QNp">
<rect key="frame" x="0.0" y="0.0" width="414" height="56"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="g91-vR-Oi1" kind="relationship" relationship="rootViewController" id="YJC-in-eGh"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ynl-Z3-Typ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-7586" y="-5464"/>
</scene>
<!--Rete Sismi Dettagli Mappa-->
<!--Seismic Networks Map Detail View Controller-->
<scene sceneID="Sdn-cf-5DS">
<objects>
<viewController id="g91-vR-Oi1" customClass="ReteSismiDettagliMappa" sceneMemberID="viewController">
<viewController id="g91-vR-Oi1" customClass="SeismicNetworksMapDetailViewController" customModule="Earthquake_Network" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="IDp-uY-aLk">
<rect key="frame" x="0.0" y="0.0" width="414" height="842"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="U9W-fH-WlC">
<rect key="frame" x="0.0" y="56" width="414" height="752"/>
<rect key="frame" x="0.0" y="56" width="414" height="702"/>
<connections>
<outlet property="delegate" destination="g91-vR-Oi1" id="D0c-pw-wKq"/>
</connections>
</mapView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ncH-7F-a3K">
<rect key="frame" x="0.0" y="758" width="414" height="50"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="Bwj-hF-heI"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="Zod-NC-YLT"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Zod-NC-YLT" firstAttribute="bottom" secondItem="U9W-fH-WlC" secondAttribute="bottom" id="EOv-ch-LrG"/>
<constraint firstItem="ncH-7F-a3K" firstAttribute="bottom" secondItem="Zod-NC-YLT" secondAttribute="bottom" id="3FB-XQ-wdb"/>
<constraint firstItem="ncH-7F-a3K" firstAttribute="top" secondItem="U9W-fH-WlC" secondAttribute="bottom" id="UR6-zp-txx"/>
<constraint firstItem="U9W-fH-WlC" firstAttribute="trailing" secondItem="Zod-NC-YLT" secondAttribute="trailing" id="auD-wh-YAA"/>
<constraint firstItem="ncH-7F-a3K" firstAttribute="leading" secondItem="Zod-NC-YLT" secondAttribute="leading" id="mZi-y4-Eu2"/>
<constraint firstItem="Zod-NC-YLT" firstAttribute="trailing" secondItem="ncH-7F-a3K" secondAttribute="trailing" id="pj6-Iv-JRe"/>
<constraint firstItem="U9W-fH-WlC" firstAttribute="leading" secondItem="Zod-NC-YLT" secondAttribute="leading" id="ruS-YM-kiK"/>
<constraint firstItem="U9W-fH-WlC" firstAttribute="top" secondItem="Zod-NC-YLT" secondAttribute="top" id="wkd-21-Q06"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="h9X-ff-rCA"/>
<connections>
<outlet property="bannerContainerHeightConstraint" destination="Bwj-hF-heI" id="7hG-Ai-1vh"/>
<outlet property="bannerContainerView" destination="ncH-7F-a3K" id="ee8-UF-HHJ"/>
<outlet property="mapView" destination="U9W-fH-WlC" id="QAC-GP-eaH"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="tNk-gG-6jK" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-6854" y="-5464"/>
<point key="canvasLocation" x="-6815.9420289855079" y="-5464.2857142857138"/>
</scene>
<!--Settings-->
<scene sceneID="nIl-RI-AZv">
@@ -2107,13 +2112,13 @@ Sisma rilevato da 10 smartphone</string>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="0lY-aw-fec">
<rect key="frame" x="11.5" y="0.0" width="106.5" height="25"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Last 24h:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hbH-vC-Yma">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Last 24h:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hbH-vC-Yma">
<rect key="frame" x="0.0" y="0.0" width="89" height="25"/>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<color key="textColor" name="Gray (dark)"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BRv-IS-2fA">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BRv-IS-2fA">
<rect key="frame" x="93" y="0.0" width="13.5" height="25"/>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<color key="textColor" name="Gray (dark)"/>
@@ -2124,13 +2129,13 @@ Sisma rilevato da 10 smartphone</string>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="0O0-8K-ugz">
<rect key="frame" x="0.0" y="29" width="129.5" height="25"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Since 2013:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l5q-I9-iOb">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Since 2013:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l5q-I9-iOb">
<rect key="frame" x="0.0" y="0.0" width="112" height="25"/>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<color key="textColor" name="Gray (dark)"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lj5-Dk-elk">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lj5-Dk-elk">
<rect key="frame" x="116" y="0.0" width="13.5" height="25"/>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<color key="textColor" name="Gray (dark)"/>
@@ -2553,13 +2558,32 @@ Sisma rilevato da 10 smartphone</string>
<outlet property="tableView" destination="a35-sg-TCr" id="OhR-Ty-elu"/>
<segue destination="rRh-R0-bas" kind="show" identifier="ShowProVersion" id="phk-Ww-RSV"/>
<segue destination="cXN-cY-DjM" kind="show" identifier="ShowPrioritySubscriptions" id="yhm-9X-yNM"/>
<segue destination="HV4-Bn-4kA" kind="show" identifier="ShowMap" id="HN8-eT-960"/>
<segue destination="HV4-Bn-4kA" kind="presentation" identifier="ShowMap" id="HN8-eT-960"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="9hV-CI-LbC" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-7691.3043478260879" y="-7441.0714285714284"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="kQU-hR-Qtg">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="6Ia-ax-PLl" sceneMemberID="viewController">
<toolbarItems/>
<navigationItem key="navigationItem" id="fda-TG-1Z9"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="nEk-36-kMO">
<rect key="frame" x="0.0" y="0.0" width="414" height="56"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="g91-vR-Oi1" kind="relationship" relationship="rootViewController" id="KfK-Za-MMz"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Bu7-hO-QIb" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-7726.0869565217399" y="-5464.2857142857138"/>
</scene>
</scenes>
<resources>
<image name="eq_icon_pro" width="166" height="166"/>
@@ -2594,54 +2618,6 @@ Sisma rilevato da 10 smartphone</string>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="opaqueSeparatorColor">
<color red="0.77647058823529413" green="0.77647058823529413" blue="0.78431372549019607" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
@@ -10,13 +10,14 @@
#import "Costanti.h"
#import "EQNSegnalazione.h"
#import "EQNManager.h"
#import "ReteSismicaAnnotation.h"
#import "EQNMapAnnotationSeismicNetwork.h"
#import "EQNUtility.h"
#import "EQNPastquakes.h"
#import "PickerViewController.h"
#import "EQNBaseViewController.h"
@import MapKit;
@interface DettagliMappaViewController : UIViewController <MKMapViewDelegate>
@interface DettagliMappaViewController : EQNBaseViewController <MKMapViewDelegate>
@property (nonatomic, assign) EQNTipoDettagliMappa tipoMappa;
@property (nonatomic, strong) IBOutlet MKMapView *mapView;
@@ -102,7 +102,7 @@
if(!self.annotationArray)
self.annotationArray = [NSMutableArray array];
CLLocationCoordinate2D location = CLLocationCoordinate2DMake([segnalazione.latitude doubleValue], [segnalazione.longitude doubleValue]);
ReteSismicaAnnotation *anAnnotation = [[ReteSismicaAnnotation alloc] initWithTitle:segnalazione.users location:location magnitudo:[segnalazione.intensity intValue]];
EQNMapAnnotationSeismicNetwork *anAnnotation = [[EQNMapAnnotationSeismicNetwork alloc] initWithTitle:segnalazione.users location:location magnitudo:[segnalazione.intensity intValue]];
[self.annotationArray addObject:anAnnotation];*/
}
@@ -111,8 +111,8 @@
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
/*
if ([annotation isKindOfClass:[ReteSismicaAnnotation class]]) {
ReteSismicaAnnotation *anLocation = (ReteSismicaAnnotation *)annotation;
if ([annotation isKindOfClass:[EQNMapAnnotationSeismicNetwork class]]) {
EQNMapAnnotationSeismicNetwork *anLocation = (EQNMapAnnotationSeismicNetwork *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_RETESMARTPHONE];
if (annotationView == nil)
annotationView = anLocation.annotationView;
@@ -7,13 +7,11 @@
//
#import "PastquakesDettagliMappa.h"
#import "PastquakesAnnotation.h"
#import "EQNAdsUtility.h"
#import "EQNMapAnnotationPastquakes.h"
@interface PastquakesDettagliMappa () <MKMapViewDelegate>
@property (nonatomic, strong) NSMutableArray *annotationArray;
@property (nonatomic, strong) GADBannerView *bannerView;
@end
@@ -39,8 +37,6 @@
[self.buttonAzione addTarget:self action:@selector(visualizzaPikerFiltro:) forControlEvents:UIControlEventTouchDown];
[self applicaFiltroWithTime:@(2)];
self.bannerView = [EQNAdsUtility ottieniBannerWithController:self position:NO];
}
- (void)creaMarcherWithSegnalazione:(id)segnalazione
@@ -53,7 +49,7 @@
EQNPastquakes *pasq = (EQNPastquakes *)segnalazione;
CLLocationCoordinate2D location = CLLocationCoordinate2DMake([pasq.latitude doubleValue], [pasq.longitude doubleValue]);
PastquakesAnnotation *anAnnotation = [[PastquakesAnnotation alloc] initWithTitle:[NSString stringWithFormat:@"%@ %@ %@",NSLocalizedString(@"Sisma rilevato da", @"") ,pasq.users, NSLocalizedString(@"smartphones", @"")] location:location intensita:[pasq.intensity intValue]];
EQNMapAnnotationPastquakes *anAnnotation = [[EQNMapAnnotationPastquakes alloc] initWithTitle:[NSString stringWithFormat:@"%@ %@ %@",NSLocalizedString(@"Sisma rilevato da", @"") ,pasq.users, NSLocalizedString(@"smartphones", @"")] location:location intensita:[pasq.intensity intValue]];
[self.annotationArray addObject:anAnnotation];
}
@@ -61,9 +57,9 @@
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[PastquakesAnnotation class]]) {
PastquakesAnnotation *anLocation = (PastquakesAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_PASTQUAKES];
if ([annotation isKindOfClass:[EQNMapAnnotationPastquakes class]]) {
EQNMapAnnotationPastquakes *anLocation = (EQNMapAnnotationPastquakes *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:EQNMapAnnotationPastquakesIdentifier];
if (annotationView == nil)
annotationView = anLocation.annotationView;
else
@@ -7,13 +7,11 @@
//
#import "SegnalazioniUtenteDettagliMappa.h"
#import "ReteSismicaAnnotation.h"
#import "EQNAdsUtility.h"
#import "EQNMapAnnotationSeismicNetwork.h"
@interface SegnalazioniUtenteDettagliMappa ()
@property (nonatomic, strong) NSMutableArray *annotationArray;
@property (nonatomic, strong) GADBannerView *bannerView;
@end
@@ -44,9 +42,7 @@
self.mapView.delegate = self;
[self.buttonAzione addTarget:self action:@selector(visualizzaPikerFiltro:) forControlEvents:UIControlEventTouchDown];
[self applicaFiltroWithTime:@(0)];
self.bannerView = [EQNAdsUtility ottieniBannerWithController:self position:NO];
[self applicaFiltroWithTime:@(0)];
}
@@ -63,16 +59,16 @@
EQNSegnalazione *anSegnalazione = (EQNSegnalazione *)segnalazione;
CLLocationCoordinate2D location = CLLocationCoordinate2DMake([anSegnalazione.latitude doubleValue], [anSegnalazione.longitude doubleValue]);
ReteSismicaAnnotation *anAnnotation = [[ReteSismicaAnnotation alloc] initWithTitle:anSegnalazione.address location:location magnitudo:[anSegnalazione.magnitude intValue]];
EQNMapAnnotationSeismicNetwork *anAnnotation = [[EQNMapAnnotationSeismicNetwork alloc] initWithTitle:anSegnalazione.address location:location magnitudo:[anSegnalazione.magnitude intValue]];
[self.annotationArray addObject:anAnnotation];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[ReteSismicaAnnotation class]]) {
ReteSismicaAnnotation *anLocation = (ReteSismicaAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:IDENTIFIER_ANNOTATION_RETESMARTPHONE];
if ([annotation isKindOfClass:[EQNMapAnnotationSeismicNetwork class]]) {
EQNMapAnnotationSeismicNetwork *anLocation = (EQNMapAnnotationSeismicNetwork *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:EQNMapAnnotationSeismicNetworkIdentifier];
if (annotationView == nil)
annotationView = anLocation.annotationView;
else
@@ -8,7 +8,7 @@
#import "LogViewController.h"
#import "EQNManager.h"
#import "EQMAccelerometroManager.h"
#import "EQNAccelerometroManager.h"
#import "EQNUser.h"
@interface LogViewController ()
@@ -27,7 +27,7 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(aggiornaLog:) name:@"AGGIORNA_LOG" object:nil];
[[EQNManager defaultManager] avviaManager];
[[EQMAccelerometroManager sharedInstance] startUpdatingLocationBackground];
[[EQNAccelerometroManager sharedInstance] startUpdatingLocationBackground];
self.testo = [NSString stringWithFormat:@" LOG ID UTENTE %@\n\nTOKEN FIREBASE:\n%@\n\n", [EQNUser defaultUser].user_ID, [EQNUser defaultUser].tokenUser];
@@ -42,7 +42,7 @@
[[EQNManager defaultManager] stopManager];
[[EQMAccelerometroManager sharedInstance] stopUpdatingLocation];
[[EQNAccelerometroManager sharedInstance] stopUpdatingLocation];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self dismissViewControllerAnimated:YES completion:nil];
@@ -244,6 +244,7 @@
"purchase_pro_restore" = "Restore";
"purchase_pro_restore_alert_title" = "Restore completed";
"purchase_pro_restore_alert_message" = "You have restored the product you purchased";
"purchase_pro_no_subscriptions_alert_message" = "No purchase was found to restore. Make sure you are logged into the account the purchase was made with.";
"inapp_available_10k" = "Top 10K: %lu subscriptions still available to be alerted in less than 1 second since the detection of the quake";
"inapp_available_100k" = "Top 100K: %lu subscriptions still available to be alerted in less than 1 second since the detection of the quake";
@@ -343,3 +344,6 @@
"globe_simulation_message5" = "With this epicentre, thanks to the %@ priority service you should receive the alert %.0f seconds in advance. %.0f people will be alerted before you. To increase the warning time you can subscribe to the %@ priority service";
"globe_simulation_message6" = "With this epicentre, thanks to the %@ priority service you should receive the alert %.0f seconds in advance. You will be the first to be alerted!";
"globe_simulation_priority" = "Priority service";
"error_server_registration" = "It was not possible to register with the Earthquake Network server. Registration is required to receive real-time alerts and earthquake notifications.";
"retry" = "Retry";
@@ -244,6 +244,7 @@
"purchase_pro_restore" = "Reiniciar";
"purchase_pro_restore_alert_title" = "Restauración completada";
"purchase_pro_restore_alert_message" = "Has restaurado el producto que compraste";
"purchase_pro_no_subscriptions_alert_message" = "No se encontró ninguna compra para restaurar. Asegúrese de haber iniciado sesión en la cuenta con la que realizó la compra.";
"inapp_available_10k" = "Top 10K: %d suscripciones aún disponibles para recibir la alerta en menos de 1 segundo a partir de la detección del sismo";
"inapp_available_100k" = "Top 100K: %d suscripciones aún disponibles para recibir la alerta en menos de 1 segundo a partir de la detección del sismo";
@@ -343,3 +344,6 @@
"globe_simulation_message5" = "Con este epicentro, gracias al servicio de prioridad %@, deberías recibir la alerta %.0f segundos antes. %.0f personas serán alertadas antes que tú. Para aumentar el tiempo de advertencia, puede suscribirse al servicio de prioridad %@";
"globe_simulation_message6" = "Con este epicentro, gracias al servicio de prioridad %@, deberías recibir la alerta %.0f segundos antes. ¡Serás la primera persona en ser alertada!";
"globe_simulation_priority" = "Servicio prioritario";
"error_server_registration" = "No fue posible registrarse en el servidor de Sismo Detector. Es necesario registrarse para recibir alertas en tiempo real y notificaciones de sismos";
"retry" = "Riprova";
@@ -244,6 +244,7 @@
"purchase_pro_restore" = "Ripristina";
"purchase_pro_restore_alert_title" = "Ripristino effettuato";
"purchase_pro_restore_alert_message" = "Hai ripristinato il prodotto da te acquistato";
"purchase_pro_no_subscriptions_alert_message" = "Attenzione, non è stato trovato alcun acquisto da ripristinare. Assicurati di essere collegato con l'account con il quale era stato effettuato l'acquisto.";
"inapp_available_10k" = "Top 10K: %lu sottoscrizioni ancora disponibili per essere allertato in meno di 1 secondo dal rilevamento del sisma";
"inapp_available_100k" = "Top 100K: %lu sottoscrizioni ancora disponibili per essere allertato in meno di 5 secondi dal rilevamento del sisma";
@@ -342,3 +343,6 @@
"globe_simulation_message5" = "Con epicentro nella posizione scelta, grazie al servizio prioritario %@ dovresti ricevere l'allerta con %.0f secondi di anticipo. Prima di te devono essere allertate %.0f persone. Puoi aumentare il tempo di pre-allerta iscrivendoti al servizio di priorità %@";
"globe_simulation_message6" = "Con epicentro nella posizione scelta, grazie al servizio prioritario %@ dovresti ricevere l'allerta con %.0f secondi di anticipo. Sarai il primo ad essere allertato!";
"globe_simulation_priority" = "Servizio priorità";
"error_server_registration" = "Non è stato possibile registrarsi al server di Rilevatore Terremoto. La registrazione è necessaria per ricevere allerte in tempo reale e notifiche sui sismi.";
"retry" = "Riprova";
@@ -7,10 +7,10 @@
//
#import <Foundation/Foundation.h>
#import "EQNReteSmartphone.h"
#import "EQNAreaCheck.h"
@class EQNSisma;
@class EQNReteSmartphone;
@interface EQNManager : NSObject
@@ -7,14 +7,12 @@
//
#import "EQNManager.h"
#import <UIKit/UIKit.h>
#import "EQNCalibrazione.h"
#import "EQNRilevamento.h"
#import "EQNUser.h"
#import "Costanti.h"
#import "ServerRequest.h"
#import "EQNGeneratoreURLServer.h"
#import "EQNReteSmartphone.h"
#import "EQNPastquakes.h"
#import "EQNSegnalazione.h"
#import "EQNSisma.h"
@@ -158,7 +156,7 @@
[EQNUtility storeArray:array toUserDefaultForKey:EQNUserDefaultSeismicNetworkCards];
[[NSNotificationCenter defaultCenter] postNotificationName:EQNNotificationDidDownloadData object:nil userInfo:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:EQNDownloadDataDidCompleteNotification object:nil userInfo:nil];
} failure:^(NSError * error) {
NSLog(@"[EQNManager] Download reti sismiche fallito. Errore: %@", error.localizedDescription);
}];
@@ -314,7 +312,7 @@
}
switch (ril.rilievo) {
case positivo:{
case EQNRilevamentoSogliaPositivo:{
[self performSelectorOnMainThread:@selector(iniviaMessaggioAlServer:)
withObject:ril
waitUntilDone:YES];
@@ -322,7 +320,7 @@
self.calibrazione = nil;
}
break;
case negativo:
case EQNRilevamentoSogliaNegativo:
/* [self performSelectorOnMainThread:@selector(riavviaRilevamento)
withObject:nil
waitUntilDone:YES];*/
@@ -347,7 +345,7 @@
{
EQNTipoChiamata tipo = EQNTipoChiamataCalibrazione;
EQNCalibrazione *anCalibrazione = [self.calibrazione copy];
if (anRilevamento.rilievo == positivo){
if (anRilevamento.rilievo == EQNRilevamentoSogliaPositivo){
tipo = EQNTipoChiamataRilevamento;
[self annullaCalibrazione];
}
@@ -1,39 +0,0 @@
//
// EQNRilevamento.m
// Earthquake Network
//
// Created by Luca Beretta on 19/09/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "EQNRilevamento.h"
#import <CoreMotion/CoreMotion.h>
#import "EQNMath.h"
#import "EQMAccelerometroManager.h"
@implementation EQNRilevamento
+(void)startRilevamentoWithCalibrazione:(EQNCalibrazione *)cal result:(void(^)(EQNRilevamento *ril))rilevamento{
if (!cal)
rilevamento(NULL);
[EQMAccelerometroManager avviaLetturaAccellerometroIsCalibrazione:NO withCompletion:^(NSArray *dati) {
EQNRilevamento *anRilievo = [[EQNRilevamento alloc] init];
anRilievo.media = [[EQNMath meanOf:dati] floatValue];
anRilievo.deviazione = [[EQNMath standardDeviationOf:dati] floatValue];
NSDictionary *rDic = [EQNMath rLimiti:dati];
float max = [rDic[rMax] floatValue] - cal.media;
anRilievo.maxAssoluto = fabsf(max);
if (anRilievo.deviazione > SOGLIA_DEVIAZIONE_RILIEVO*cal.deviazione)
anRilievo.rilievo = positivo;
else
anRilievo.rilievo = negativo;
anRilievo.timestamp = [NSDate date];
rilevamento(anRilievo);
}];
}
@end
@@ -1,22 +0,0 @@
//
// ReteSismicaAnnotation.h
// Earthquake Network
//
// Created by Luca Beretta on 01/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import "Costanti.h"
@interface ReteSismicaAnnotation : NSObject <MKAnnotation>
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, readonly) int magnitude;
-(id)initWithTitle:(NSString *)title location:(CLLocationCoordinate2D )coordinate magnitudo:(int)magnitude;
-(MKAnnotationView *)annotationView ;
@end
@@ -1,22 +0,0 @@
//
// SismaAnnotation.h
// Earthquake Network
//
// Created by Luca Beretta on 08/11/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import "Costanti.h"
@interface SismaAnnotation : NSObject <MKAnnotation>
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, readonly) double magnitude;
-(id)initWithTitle:(NSString *)title location:(CLLocationCoordinate2D )coordinate intensita:(double)magnitude;
-(MKAnnotationView *)annotationView ;
@end
+56 -56
View File
@@ -1,94 +1,94 @@
PODS:
- DZNEmptyDataSet (1.8.1)
- Firebase/Core (7.1.0):
- Firebase/Core (7.6.0):
- Firebase/CoreOnly
- FirebaseAnalytics (= 7.1.0)
- Firebase/CoreOnly (7.1.0):
- FirebaseCore (= 7.1.0)
- Firebase/Crashlytics (7.1.0):
- FirebaseAnalytics (= 7.6.0)
- Firebase/CoreOnly (7.6.0):
- FirebaseCore (= 7.6.0)
- Firebase/Crashlytics (7.6.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 7.1.0)
- Firebase/Messaging (7.1.0):
- FirebaseCrashlytics (~> 7.6.0)
- Firebase/Messaging (7.6.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 7.1.0)
- FirebaseAnalytics (7.1.0):
- FirebaseMessaging (~> 7.6.0)
- FirebaseAnalytics (7.6.0):
- FirebaseCore (~> 7.0)
- FirebaseInstallations (~> 7.0)
- GoogleAppMeasurement (= 7.1.0)
- GoogleAppMeasurement (= 7.6.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.0)
- GoogleUtilities/MethodSwizzler (~> 7.0)
- GoogleUtilities/Network (~> 7.0)
- "GoogleUtilities/NSData+zlib (~> 7.0)"
- nanopb (~> 2.30906.0)
- FirebaseCore (7.1.0):
- FirebaseCoreDiagnostics (~> 7.0)
- nanopb (~> 2.30907.0)
- FirebaseCore (7.6.0):
- FirebaseCoreDiagnostics (~> 7.4)
- GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/Logger (~> 7.0)
- FirebaseCoreDiagnostics (7.1.0):
- FirebaseCoreDiagnostics (7.6.0):
- GoogleDataTransport (~> 8.0)
- GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/Logger (~> 7.0)
- nanopb (~> 2.30906.0)
- FirebaseCrashlytics (7.1.0):
- nanopb (~> 2.30907.0)
- FirebaseCrashlytics (7.6.0):
- FirebaseCore (~> 7.0)
- FirebaseInstallations (~> 7.0)
- GoogleDataTransport (~> 8.0)
- nanopb (~> 2.30906.0)
- nanopb (~> 2.30907.0)
- PromisesObjC (~> 1.2)
- FirebaseInstallations (7.1.0):
- FirebaseInstallations (7.6.0):
- FirebaseCore (~> 7.0)
- GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/UserDefaults (~> 7.0)
- PromisesObjC (~> 1.2)
- FirebaseInstanceID (7.1.0):
- FirebaseInstanceID (7.6.0):
- FirebaseCore (~> 7.0)
- FirebaseInstallations (~> 7.0)
- GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/UserDefaults (~> 7.0)
- FirebaseMessaging (7.1.0):
- FirebaseMessaging (7.6.0):
- FirebaseCore (~> 7.0)
- FirebaseInstanceID (~> 7.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.0)
- GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/Reachability (~> 7.0)
- GoogleUtilities/UserDefaults (~> 7.0)
- Google-Mobile-Ads-SDK (7.68.0):
- Google-Mobile-Ads-SDK (8.1.0):
- GoogleAppMeasurement (~> 7.0)
- GoogleUserMessagingPlatform (~> 1.1)
- GoogleAppMeasurement (7.1.0):
- GoogleAppMeasurement (7.6.0):
- GoogleUtilities/AppDelegateSwizzler (~> 7.0)
- GoogleUtilities/MethodSwizzler (~> 7.0)
- GoogleUtilities/Network (~> 7.0)
- "GoogleUtilities/NSData+zlib (~> 7.0)"
- nanopb (~> 2.30906.0)
- GoogleDataTransport (8.0.1):
- nanopb (~> 2.30906.0)
- GoogleUserMessagingPlatform (1.3.0)
- GoogleUtilities/AppDelegateSwizzler (7.1.0):
- nanopb (~> 2.30907.0)
- GoogleDataTransport (8.2.0):
- nanopb (~> 2.30907.0)
- GoogleUserMessagingPlatform (1.4.0)
- GoogleUtilities/AppDelegateSwizzler (7.2.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (7.1.0):
- GoogleUtilities/Environment (7.2.2):
- PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (7.1.0):
- GoogleUtilities/Logger (7.2.2):
- GoogleUtilities/Environment
- GoogleUtilities/MethodSwizzler (7.1.0):
- GoogleUtilities/MethodSwizzler (7.2.2):
- GoogleUtilities/Logger
- GoogleUtilities/Network (7.1.0):
- GoogleUtilities/Network (7.2.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.1.0)"
- GoogleUtilities/Reachability (7.1.0):
- "GoogleUtilities/NSData+zlib (7.2.2)"
- GoogleUtilities/Reachability (7.2.2):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (7.1.0):
- GoogleUtilities/UserDefaults (7.2.2):
- GoogleUtilities/Logger
- nanopb (2.30906.0):
- nanopb/decode (= 2.30906.0)
- nanopb/encode (= 2.30906.0)
- nanopb/decode (2.30906.0)
- nanopb/encode (2.30906.0)
- PromisesObjC (1.2.11)
- nanopb (2.30907.0):
- nanopb/decode (= 2.30907.0)
- nanopb/encode (= 2.30907.0)
- nanopb/decode (2.30907.0)
- nanopb/encode (2.30907.0)
- PromisesObjC (1.2.12)
- Solar (2.1.0)
DEPENDENCIES:
@@ -121,23 +121,23 @@ SPEC REPOS:
SPEC CHECKSUMS:
DZNEmptyDataSet: 9525833b9e68ac21c30253e1d3d7076cc828eaa7
Firebase: 78e8dd2e39d653de6270432ad84fe8b59f7bf4e8
FirebaseAnalytics: 7f165a56dea86ddd5b8ce02af3bee982c683405c
FirebaseCore: 20046127eef0fcb8fa25df7fc12f7b97d4e48611
FirebaseCoreDiagnostics: 872cdb9b749b23346dddd5c1014d1babd2257de3
FirebaseCrashlytics: c722e4ca283272eb90eb5bc245fdc6588e2f22c2
FirebaseInstallations: 3de38553e86171b5f81d83cdeef63473d37bfdb0
FirebaseInstanceID: 61e8d10a4192a582c6239378169d10e504ca8d91
FirebaseMessaging: 076054895c9260f82c7304cc7709dbf19b8f3e4a
Google-Mobile-Ads-SDK: 29bbdb182d69ff606cc0301da1590b40be8d2205
GoogleAppMeasurement: 89e1a64593f968713b0506ba1b53b38a154bf9a5
GoogleDataTransport: e4085e6762f36a6141738f46b0153473ce57fb18
GoogleUserMessagingPlatform: 1d4b6946710d18cec34742054092e2c2bddae61f
GoogleUtilities: f734da554aade8cc7928a31c2f3311897933a1bd
nanopb: 1bf24dd71191072e120b83dd02d08f3da0d65e53
PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
Firebase: e1e089d9aac215a52442583f818ab61de3c4581b
FirebaseAnalytics: 9f8f4feab1f3fddf4e4515f8f022fe6aa9e51043
FirebaseCore: 0a43b7f1c5b36f3358cd703011ca4c7e0df55870
FirebaseCoreDiagnostics: ee1184d51da3293335b83355aad20f537acc24cf
FirebaseCrashlytics: 1e87b25303b1840b3c99c37ee427c3e9564a4be1
FirebaseInstallations: 6e4e77396559bc2ae0504823837ed737b1c7e47f
FirebaseInstanceID: cf243611700eddc916b093353adbd4da822cfa63
FirebaseMessaging: 4b9b2850fcfcaac2820097ee3703ba6cfff3df84
Google-Mobile-Ads-SDK: efb7fb74595668fbbe680f0d1c06f9a8ff694c7c
GoogleAppMeasurement: c542a2feaac9ab98fd074e8f1a02c3585bbfbd47
GoogleDataTransport: 1024b1a4dfbd7a0e92cb20d7e0a6f1fb66b449a4
GoogleUserMessagingPlatform: b168e8c46cd8f92aa3e34b584c4ca78a411ce367
GoogleUtilities: 31c5b01f978a70c6cff2afc6272b3f1921614b43
nanopb: 59221d7f958fb711001e6a449489542d92ae113e
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
Solar: 2dc6e7cc39186cb0c8228fa08df76fb50c7d8f24
PODFILE CHECKSUM: dd5131b6d7a83fb7c22ecc161ed4fc143eda0ac1
COCOAPODS: 1.10.0
COCOAPODS: 1.10.1