Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 15088b744f | |||
| ac03a0cccb | |||
| 76a26e3100 | |||
| cac6ed67ac | |||
| 094c682dbd | |||
| c44f46ca46 | |||
| 5e8c3d0796 | |||
| 61ce27ed4b | |||
| 3aea60e560 | |||
| 84b61fd7e2 | |||
| a5a8c6f5c5 | |||
| 61587a0341 | |||
| a56a04a4ad | |||
| 7173dc7031 | |||
| 35dbdbab28 | |||
| 14614267d4 | |||
| 32833010ed | |||
| ecc77e9f2b | |||
| e69747f133 | |||
| 09685fd4a7 | |||
| 3e122240dc |
@@ -1,5 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## Versione 5.4
|
||||
|
||||
- Aggiunto SDK Facebook
|
||||
|
||||
## Versione 5.3.2
|
||||
|
||||
- Corretto problema con notifiche critiche
|
||||
|
||||
## Versione 5.3.1
|
||||
|
||||
- Ricreato progetto NotificationService
|
||||
- Correzioni minori
|
||||
|
||||
## Versione 5.3
|
||||
|
||||
- Rivista gestione registrazione utente
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
EQNMapAnnotationUserReport *report = (EQNMapAnnotationUserReport *)annotation;
|
||||
|
||||
EQNCustomAnnotationView *annotationView = (EQNCustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:EQNCustomAnnotationView.SmallIdentifier];
|
||||
annotationView.image = report.image;
|
||||
annotationView.image = [report imageWithHeight:EQNCustomAnnotationView.SmallViewImageHeight];
|
||||
annotationView.title = report.timeDifference;
|
||||
return annotationView;
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
#import "NotificationService.h"
|
||||
@@ -2,35 +2,12 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>EQNNotificationService</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.usernotifications.service</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>NotificationService</string>
|
||||
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
//
|
||||
// NotificationService+Extension.swift
|
||||
// EQNNotificationService
|
||||
//
|
||||
// Created by Andrea Busi on 28/05/22.
|
||||
// Copyright © 2022 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UserNotifications
|
||||
|
||||
|
||||
extension NotificationService {
|
||||
|
||||
@objc(removeNotificationsForType:completion:)
|
||||
func removeNotifications(
|
||||
for type: String?,
|
||||
completion: @escaping() -> Void
|
||||
) {
|
||||
guard let type = type else {
|
||||
completion()
|
||||
return
|
||||
}
|
||||
|
||||
let notificationCenter = UNUserNotificationCenter.current()
|
||||
|
||||
notificationCenter.getDeliveredNotifications { notifications in
|
||||
let sameTypeNotifications = notifications.filter { notification in
|
||||
let payload = notification.request.content.userInfo
|
||||
if let notificationType = payload["type"] as? String {
|
||||
return notificationType == type
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
let identifiers = sameTypeNotifications.map { $0.request.identifier }
|
||||
notificationCenter.removeDeliveredNotifications(withIdentifiers: identifiers)
|
||||
|
||||
// !! Note: this is a known issue/bug
|
||||
// we need to add a delay before invoking the completion, otherwise the notification will not be remved
|
||||
// ref: https://stackoverflow.com/questions/53697279/why-are-notifications-not-removed-with-removedeliverednotifications
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
//
|
||||
// NotificationService.h
|
||||
// EQNNotificationService
|
||||
//
|
||||
// Refactored by Andrea Busi
|
||||
// Copyright © 2020 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
|
||||
@interface NotificationService : UNNotificationServiceExtension
|
||||
|
||||
@end
|
||||
@@ -1,170 +0,0 @@
|
||||
//
|
||||
// NotificationService.m
|
||||
// EQNNotificationService
|
||||
//
|
||||
// Refactored by Andrea Busi
|
||||
// Copyright © 2020 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NotificationService.h"
|
||||
#import "EQNAllertaSismica.h"
|
||||
#import "Costanti.h"
|
||||
#import "EQNNotificationService-Swift.h"
|
||||
|
||||
|
||||
@interface NotificationService ()
|
||||
|
||||
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
|
||||
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
|
||||
@end
|
||||
|
||||
@implementation NotificationService
|
||||
|
||||
static NSString * const EQNSoundNotificationEQN = @"alert_sound.wav";
|
||||
|
||||
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler
|
||||
{
|
||||
self.contentHandler = contentHandler;
|
||||
self.bestAttemptContent = [request.content mutableCopy];
|
||||
|
||||
// Configure the notification's payload.
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
content.title = [NSString localizedUserNotificationStringForKey:request.content.title arguments:nil];
|
||||
content.body = [NSString localizedUserNotificationStringForKey:request.content.body arguments:nil];
|
||||
|
||||
self.bestAttemptContent.title = content.title;
|
||||
self.bestAttemptContent.body = content.body;
|
||||
|
||||
// check for required informations
|
||||
NSDictionary *userInfo = request.content.userInfo;
|
||||
NSString *notificationType = [userInfo objectForKey:@"type"];
|
||||
if (userInfo == nil || notificationType == nil) {
|
||||
[self contentComplete];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
NSString *iconName = @"";
|
||||
if ([notificationType isEqualToString:@"eqn"]) {
|
||||
// check if user has enabled critical alerts
|
||||
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:EQNUserDefaultAppGroupSuite];
|
||||
BOOL criticalAlertsEnabled = [sharedDefaults boolForKey:NOTIFICHE_ALLERA_SISMICA_CRITICAL_ALERTS];
|
||||
|
||||
// !!WORKAROUND
|
||||
// this is a workaround to use critical alerts with legacy FCM api
|
||||
// when the server implementation will be migrated to Firebase v1 APIs, this could be removed
|
||||
BOOL isCritical = [[userInfo objectForKey:@"critical"] boolValue];
|
||||
if (isCritical && criticalAlertsEnabled) {
|
||||
self.bestAttemptContent.sound = [UNNotificationSound criticalSoundNamed:EQNSoundNotificationEQN withAudioVolume:1.0];
|
||||
} else {
|
||||
self.bestAttemptContent.sound = [UNNotificationSound soundNamed:EQNSoundNotificationEQN];
|
||||
}
|
||||
|
||||
NSString *intensity = [userInfo objectForKey:@"intensity"];
|
||||
switch ([intensity intValue]) {
|
||||
case 0:
|
||||
iconName = @"star_realtime_white.png";
|
||||
break;
|
||||
case 1:
|
||||
iconName = @"star_realtime_lightblue.png";
|
||||
break;
|
||||
case 2:
|
||||
iconName = @"star_realtime_blue.png";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if ([notificationType isEqualToString:@"manual"]) {
|
||||
// there are 12 levels, so a customized icon doesn't make sense
|
||||
// use a generic warning icon instead
|
||||
iconName = @"warning_yellow.png";
|
||||
} else if ([notificationType isEqualToString:@"official"]) {
|
||||
NSString *provaider = [userInfo objectForKey:@"provider"];
|
||||
double intensity = [[userInfo objectForKey:@"magnitude"] doubleValue];
|
||||
|
||||
NSString *colore = @"";
|
||||
if (intensity < 2.0) {
|
||||
colore = @"_white";
|
||||
} else if (intensity < 3.5) {
|
||||
colore = @"_green";
|
||||
} else if (intensity < 4.5) {
|
||||
colore = @"_yellow";
|
||||
} else if (intensity < 5.5) {
|
||||
colore = @"_red";
|
||||
} else {
|
||||
colore = @"_purple";
|
||||
}
|
||||
|
||||
if ([provaider isEqualToString:@"USGS"]) {
|
||||
iconName = [NSString stringWithFormat:@"star%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"SGC"]) {
|
||||
iconName = [NSString stringWithFormat:@"star3%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"CSN"]) {
|
||||
iconName = [NSString stringWithFormat:@"star3f%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"SSN"]) {
|
||||
iconName = [NSString stringWithFormat:@"star4%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"INPRES"]) {
|
||||
iconName = [NSString stringWithFormat:@"star4r%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"FUNVISIS"]) {
|
||||
iconName = [NSString stringWithFormat:@"star6%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"Ineter"]) {
|
||||
iconName = [NSString stringWithFormat:@"triangle%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"RSN"]) {
|
||||
iconName = [NSString stringWithFormat:@"triangle2%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"PHIVOLCS"]) {
|
||||
iconName = [NSString stringWithFormat:@"triround_inner%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"IGEPN"]) {
|
||||
iconName = [NSString stringWithFormat:@"triround%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"INGV"]) {
|
||||
iconName = [NSString stringWithFormat:@"circle%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"EMSC"]) {
|
||||
iconName = [NSString stringWithFormat:@"dyamond%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"IGP"]) {
|
||||
iconName = [NSString stringWithFormat:@"dyamond_round%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"JMA"]) {
|
||||
iconName = [NSString stringWithFormat:@"esa%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"GEONET"]) {
|
||||
iconName = [NSString stringWithFormat:@"oct%@.png", colore];
|
||||
} if ([provaider isEqualToString:@"CSI"]) {
|
||||
iconName = [NSString stringWithFormat:@"penta%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"IGN"]) {
|
||||
iconName = [NSString stringWithFormat:@"square%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"UASD"] || [provaider isEqualToString:@"BDTIM"] || [provaider isEqualToString:@"NCS"]) {
|
||||
iconName = [NSString stringWithFormat:@"thick_star%@.png", colore];
|
||||
} else if ([provaider isEqualToString:@"RSPR"]) {
|
||||
iconName = [NSString stringWithFormat:@"star6f%@.png", colore];
|
||||
}
|
||||
}
|
||||
|
||||
if (![iconName isEqualToString:@""]) {
|
||||
iconName = [iconName stringByReplacingOccurrencesOfString:@".png" withString:@""];
|
||||
NSURL *imageUrl = [NSBundle.mainBundle URLForResource:iconName withExtension:@"png"];
|
||||
NSError *attachmentError = nil;
|
||||
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:iconName
|
||||
URL:imageUrl
|
||||
options:nil
|
||||
error:&attachmentError];
|
||||
if (!attachmentError) {
|
||||
self.bestAttemptContent.attachments = @[attachment];
|
||||
}
|
||||
}
|
||||
|
||||
// remove same type posted notification
|
||||
[self removeNotificationsForType:notificationType completion:^{
|
||||
[self contentComplete];
|
||||
}];;
|
||||
}
|
||||
|
||||
- (void)serviceExtensionTimeWillExpire
|
||||
{
|
||||
// Called just before the extension will be terminated by the system.
|
||||
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
|
||||
[self contentComplete];
|
||||
}
|
||||
|
||||
- (void)contentComplete
|
||||
{
|
||||
self.contentHandler(self.bestAttemptContent);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,184 @@
|
||||
//
|
||||
// NotificationService.swift
|
||||
// EQNNotificationService
|
||||
//
|
||||
// Created by Andrea Busi on 24/11/22.
|
||||
// Copyright © 2022 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import UserNotifications
|
||||
import Shogun
|
||||
|
||||
class NotificationService: UNNotificationServiceExtension {
|
||||
|
||||
// riportiamo queste costanti dall'app bundle, per non dover referenziare file in ObjC
|
||||
private static let EQNUserDefaultAppGroupSuite = "group.com.finazzi.distquake"
|
||||
private static let NOTIFICHE_ALLERA_SISMICA_CRITICAL_ALERTS = "NOTIFICHE_ALLERA_SISMICA_CRITICAL_ALERTS"
|
||||
private static let EQNSoundNotification = UNNotificationSoundName("alert_sound.wav")
|
||||
|
||||
|
||||
var contentHandler: ((UNNotificationContent) -> Void)?
|
||||
var bestAttemptContent: UNMutableNotificationContent?
|
||||
|
||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||
self.contentHandler = contentHandler
|
||||
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
||||
|
||||
guard let bestAttemptContent = bestAttemptContent else {
|
||||
print("[NotificationService] Unable to get notification content")
|
||||
contentComplete()
|
||||
return
|
||||
}
|
||||
|
||||
let userInfo = request.content.userInfo
|
||||
guard let notificationType = userInfo.string(forKey: "type") else {
|
||||
print("[NotificationService] Unable to get notification type")
|
||||
contentComplete()
|
||||
return
|
||||
}
|
||||
|
||||
var iconName = ""
|
||||
switch notificationType.lowercased() {
|
||||
case "eqn":
|
||||
// check if user has enabled critical alerts
|
||||
let sharedDefaults = UserDefaults(suiteName: Self.EQNUserDefaultAppGroupSuite)
|
||||
let criticalAlertsEnabled = sharedDefaults?.bool(forKey: Self.NOTIFICHE_ALLERA_SISMICA_CRITICAL_ALERTS) ?? false
|
||||
|
||||
// !!WORKAROUND
|
||||
// this is a workaround to use critical alerts with legacy FCM api
|
||||
// when the server implementation will be migrated to Firebase v1 APIs, this could be removed
|
||||
let isCritical = userInfo.integer(forKey: "critical", orDefault: 0) == 1
|
||||
if isCritical && criticalAlertsEnabled {
|
||||
bestAttemptContent.sound = UNNotificationSound.criticalSoundNamed(Self.EQNSoundNotification)
|
||||
} else {
|
||||
bestAttemptContent.sound = UNNotificationSound(named: Self.EQNSoundNotification)
|
||||
}
|
||||
|
||||
let intensity = userInfo.integer(forKey: "intensity")
|
||||
switch intensity {
|
||||
case 0:
|
||||
iconName = "star_realtime_white.png"
|
||||
case 1:
|
||||
iconName = "star_realtime_lightblue.png"
|
||||
case 2:
|
||||
iconName = "star_realtime_blue.png"
|
||||
default:
|
||||
break
|
||||
}
|
||||
case "manual":
|
||||
// there are 12 levels, so a customized icon doesn't make sense
|
||||
// use a generic warning icon instead
|
||||
iconName = "warning_yellow.png"
|
||||
case "official":
|
||||
let provider = userInfo.string(forKey: "provider", orDefault: "")
|
||||
let intensity = userInfo.double(forKey: "magnitude", orDefault: 0)
|
||||
|
||||
let color: String
|
||||
if intensity < 2.0 {
|
||||
color = "_white"
|
||||
} else if intensity < 3.5 {
|
||||
color = "_green"
|
||||
} else if intensity < 4.5 {
|
||||
color = "_yellow"
|
||||
} else if intensity < 5.5 {
|
||||
color = "_red"
|
||||
} else {
|
||||
color = "_purple"
|
||||
}
|
||||
|
||||
iconName = manualIconName(for: provider, color: color)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
// add the icon as notification attachment
|
||||
if !iconName.isEmpty {
|
||||
iconName = iconName.replacingOccurrences(of: ".png", with: "")
|
||||
|
||||
if let imageUrl = Bundle(for: NotificationService.self).url(forResource: iconName, withExtension: "png"),
|
||||
let attachment = try? UNNotificationAttachment(identifier: iconName, url: imageUrl) {
|
||||
bestAttemptContent.attachments = [ attachment ]
|
||||
}
|
||||
}
|
||||
|
||||
// remove same type posted notification
|
||||
removeNotifications(for: notificationType) { [weak self] in
|
||||
self?.contentComplete()
|
||||
}
|
||||
}
|
||||
|
||||
override func serviceExtensionTimeWillExpire() {
|
||||
// Called just before the extension will be terminated by the system.
|
||||
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
|
||||
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func contentComplete() {
|
||||
if let bestAttemptContent {
|
||||
contentHandler?(bestAttemptContent)
|
||||
}
|
||||
}
|
||||
|
||||
private func removeNotifications(
|
||||
for type: String?,
|
||||
completion: @escaping() -> Void
|
||||
) {
|
||||
guard let type = type else {
|
||||
completion()
|
||||
return
|
||||
}
|
||||
|
||||
let notificationCenter = UNUserNotificationCenter.current()
|
||||
|
||||
notificationCenter.getDeliveredNotifications { notifications in
|
||||
let sameTypeNotifications = notifications.filter { notification in
|
||||
let payload = notification.request.content.userInfo
|
||||
if let notificationType = payload["type"] as? String {
|
||||
return notificationType == type
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
let identifiers = sameTypeNotifications.map { $0.request.identifier }
|
||||
notificationCenter.removeDeliveredNotifications(withIdentifiers: identifiers)
|
||||
|
||||
// !! Note: this is a known issue/bug
|
||||
// we need to add a delay before invoking the completion, otherwise the notification will not be remved
|
||||
// ref: https://stackoverflow.com/questions/53697279/why-are-notifications-not-removed-with-removedeliverednotifications
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private func manualIconName(for provider: String, color: String) -> String {
|
||||
switch provider.uppercased() {
|
||||
case "USGS": return "star\(color).png"
|
||||
case "SGC": return "star3\(color).png"
|
||||
case "CSN": return "star3f\(color).png"
|
||||
case "SSN": return "star4\(color).png"
|
||||
case "INPRES": return "star4r\(color).png"
|
||||
case "FUNVISIS": return "star6\(color).png"
|
||||
case "INETER": return "triangle\(color).png"
|
||||
case "RSN": return "triangle2\(color).png"
|
||||
case "PHIVOLCS": return "triround_inner\(color).png"
|
||||
case "IGEPN": return "triround\(color).png"
|
||||
case "INGV": return "circle\(color).png"
|
||||
case "EMSC": return "dyamond\(color).png"
|
||||
case "IGP": return "dyamond_round\(color).png"
|
||||
case "JMA": return "esa\(color).png"
|
||||
case "GEONET": return "oct\(color).png"
|
||||
case "CSI": return "penta\(color).png"
|
||||
case "IGN": return "square\(color).png"
|
||||
case "UASD", "BDTIM", "NCS": return "thick_star\(color).png"
|
||||
case "RSPR": return "star6f\(color).png"
|
||||
default: return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/andreabusi-it/Shogun",
|
||||
"state" : {
|
||||
"revision" : "63d1fdb957d917410e58a958a49fdb52f8de10ac",
|
||||
"version" : "0.2.3"
|
||||
"revision" : "4120014b7e567296a95cd05a8a801a198f4cdac9",
|
||||
"version" : "0.5.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
#import "EQNNotificheReteSismiche.h"
|
||||
#import "EQNMainTabBarController.h"
|
||||
|
||||
@import UserNotifications;
|
||||
@import AppTrackingTransparency;
|
||||
@import Firebase;
|
||||
@import FirebaseCrashlytics;
|
||||
@import UserNotifications;
|
||||
@import GoogleMobileAds;
|
||||
@import FBSDKCoreKit;
|
||||
|
||||
@interface AppDelegate () <FIRMessagingDelegate, UNUserNotificationCenterDelegate>
|
||||
@property (strong, nonatomic) NSArray<id<EQNCommandProtocol>> *commands;
|
||||
@@ -50,20 +52,14 @@
|
||||
|
||||
[EQNUser defaultUser];
|
||||
[EQNManager defaultManager];
|
||||
[FIRApp configure];
|
||||
[FIRMessaging messaging].delegate = self;
|
||||
[self configureFirebase];
|
||||
[self configureFacebookSDKWithApplication:application andOptions:launchOptions];
|
||||
|
||||
// add some generic logs for Crashlytics
|
||||
NSString *language = [[NSLocale preferredLanguages] firstObject];
|
||||
[[FIRCrashlytics crashlytics] setCustomValue:language forKey:@"lang"];
|
||||
|
||||
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
||||
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
|
||||
[[UNUserNotificationCenter currentNotificationCenter]
|
||||
requestAuthorizationWithOptions:authOptions
|
||||
completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
||||
[self registraNotifica];
|
||||
}];
|
||||
[self configurePushNotifications];
|
||||
|
||||
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
|
||||
[application registerForRemoteNotifications];
|
||||
@@ -197,6 +193,49 @@
|
||||
[self.mainTabBarController selectSection:section];
|
||||
}
|
||||
|
||||
#pragma mark - Configurations
|
||||
|
||||
- (void)configurePushNotifications
|
||||
{
|
||||
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
||||
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
|
||||
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
||||
[self registraNotifica];
|
||||
[self configureAppTracking];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)configureAppTracking
|
||||
{
|
||||
if (@available(iOS 14, *)) {
|
||||
// add a delay otherwise the alert will not be displayed
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
|
||||
if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
|
||||
FBSDKSettings.sharedSettings.isAdvertiserTrackingEnabled = YES;
|
||||
} else {
|
||||
FBSDKSettings.sharedSettings.isAdvertiserTrackingEnabled = NO;
|
||||
}
|
||||
}];
|
||||
});
|
||||
} else {
|
||||
FBSDKSettings.sharedSettings.isAdvertiserTrackingEnabled = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)configureFirebase
|
||||
{
|
||||
[FIRApp configure];
|
||||
[FIRMessaging messaging].delegate = self;
|
||||
}
|
||||
|
||||
- (void)configureFacebookSDKWithApplication:(UIApplication *)application andOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
[FBSDKApplicationDelegate.sharedInstance application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
[FBSDKSettings.sharedSettings setIsAdvertiserIDCollectionEnabled:YES];
|
||||
[FBSDKSettings.sharedSettings setIsAdvertiserIDCollectionEnabled:YES];
|
||||
}
|
||||
|
||||
#pragma mark - FIRMessagingDelegate
|
||||
|
||||
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken
|
||||
|
||||
@@ -113,7 +113,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
[super refreshUI];
|
||||
|
||||
// `AllerteTableRowReteSmartphone` and `AllerteTableRowDatiPosizione` are hidden bu default, user can show them
|
||||
BOOL showAllCards = [[NSUserDefaults standardUserDefaults] boolForKey:EQNUserDefaultKeyAlertsShowAllCards];
|
||||
BOOL showAllCards = AppPreferences.shared.alertsShowAllCards;
|
||||
self.expandeCollapseButton.image = showAllCards ? [UIImage imageNamed:@"navbar-icon-arrow-collapse"] : [UIImage imageNamed:@"navbar-icon-arrow-expand"];
|
||||
|
||||
// controlliamo se c'è una notifica in tempo reale da mostrare
|
||||
@@ -177,9 +177,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
- (IBAction)collapseExpandTapped:(id)sender
|
||||
{
|
||||
// toggle saved value
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
BOOL showAll = [defaults boolForKey:EQNUserDefaultKeyAlertsShowAllCards];
|
||||
[defaults setBool:!showAll forKey:EQNUserDefaultKeyAlertsShowAllCards];
|
||||
AppPreferences.shared.alertsShowAllCards = !AppPreferences.shared.alertsShowAllCards;
|
||||
|
||||
[self refreshUI];
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Shogun
|
||||
|
||||
class SegnalazioniLast24HoursCell: EQNBaseTableViewCell {
|
||||
|
||||
@@ -49,6 +50,15 @@ class SegnalazioniLast24HoursCell: EQNBaseTableViewCell {
|
||||
return
|
||||
}
|
||||
|
||||
self.reportsLabel.text = "\(smartphoneNetwork.manual)"
|
||||
let reports = smartphoneNetwork.manual
|
||||
self.reportsLabel.text = "\(reports)"
|
||||
|
||||
if reports < 100 {
|
||||
self.reportsLabel.textColor = UIColor(hex6: 0x01b400)
|
||||
} else if reports < 1000 {
|
||||
self.reportsLabel.textColor = UIColor(hex6: 0xe8da00)
|
||||
} else {
|
||||
self.reportsLabel.textColor = UIColor(hex6: 0xff0000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,11 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
false
|
||||
}
|
||||
|
||||
private let appPreferences = AppPreferences.shared
|
||||
/// Contains circles and related colors to draw overlays on the map
|
||||
private var mapCircles = [MapCircle]()
|
||||
/// Reports currently showned on the map
|
||||
private var filteredReports = [EQNSegnalazione]()
|
||||
/// Defines if time has to be shown on map annotations
|
||||
private var showAnnotationTime = false
|
||||
|
||||
// MARK: - UI
|
||||
|
||||
@@ -191,7 +190,7 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
}
|
||||
|
||||
@objc private func onTapMapDetailStyleButton(_ sender: Any) {
|
||||
showAnnotationTime.toggle()
|
||||
appPreferences.userReportExpandedView.toggle()
|
||||
loadDataSource()
|
||||
}
|
||||
|
||||
@@ -339,10 +338,11 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
return nil
|
||||
}
|
||||
|
||||
let identifier = showAnnotationTime ? EQNCustomAnnotationView.SingleLineIdentifier : EQNCustomAnnotationView.SmallIdentifier
|
||||
let identifier = appPreferences.userReportExpandedView ? EQNCustomAnnotationView.SingleLineIdentifier : EQNCustomAnnotationView.SmallIdentifier
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as! EQNCustomAnnotationView
|
||||
|
||||
annotationView.image = annotation.image
|
||||
let size = appPreferences.userReportExpandedView ? EQNCustomAnnotationView.SingleLineImageHeight : EQNCustomAnnotationView.SmallViewImageHeight
|
||||
annotationView.image = annotation.image(with: size)
|
||||
annotationView.title = annotation.timeDifference
|
||||
annotationView.canShowCallout = true
|
||||
// Psizioniamo più in alto le segnalazioni con intensità maggiore.
|
||||
|
||||
-1
@@ -204,7 +204,6 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
|
||||
private func setupUI() {
|
||||
selectionStyle = .default
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
backgroundColor = .clear
|
||||
|
||||
// container view
|
||||
|
||||
@@ -75,6 +75,7 @@ static NSString * const EQNUserDefaultLastLocation = @"EQNLast_Location";
|
||||
static NSString * const EQNUserDefaultSeismicNetworkCards = @"EQNData.RetiSismiche";
|
||||
static NSString * const EQNUserDefaultRealTimeAlertPayload = @"EQNData.RealtimeAlertPayload";
|
||||
static NSString * const EQNUserDefaultRealTimeAlertDate = @"EQNData.RealtimeAlertDate";
|
||||
static NSString * const EQNUserDefaultUserReportExpandedView = @"EQNData.UserReportExpandedView";
|
||||
|
||||
static NSString * const EQNUserDefaultMigrationV5_3 = @"EQNUserDefaultMigrationV5_3";
|
||||
|
||||
|
||||
@@ -78,5 +78,31 @@
|
||||
</array>
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>fb1444404982546319</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>FacebookAppID</key>
|
||||
<string>1444404982546319</string>
|
||||
<key>FacebookClientToken</key>
|
||||
<string>46c7a338b2bbd2186b2f1c12865b4004</string>
|
||||
<key>FacebookDisplayName</key>
|
||||
<string>Earthquake Network</string>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>fbapi</string>
|
||||
<string>fb-messenger-share-api</string>
|
||||
</array>
|
||||
<key>FacebookAutoLogAppEventsEnabled</key>
|
||||
<true/>
|
||||
<key>FacebookAdvertiserIDCollectionEnabled</key>
|
||||
<true/>
|
||||
<key>NSUserTrackingUsageDescription</key>
|
||||
<string>Il tracciamento serve a capire se la pubblicità dell'app è efficace</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// AppPreferences.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 17/11/22.
|
||||
// Copyright © 2022 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
@objc
|
||||
class AppPreferences: NSObject {
|
||||
|
||||
@objc
|
||||
static let shared = AppPreferences()
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
/// Defines if time has to be shown on map annotations in User Reports
|
||||
var userReportExpandedView: Bool {
|
||||
get { UserDefaults.standard.bool(forKey: EQNUserDefaultUserReportExpandedView) }
|
||||
set { UserDefaults.standard.set(newValue, forKey: EQNUserDefaultUserReportExpandedView) }
|
||||
}
|
||||
|
||||
@objc
|
||||
var alertsShowAllCards: Bool {
|
||||
get { UserDefaults.standard.bool(forKey: EQNUserDefaultKeyAlertsShowAllCards) }
|
||||
set { UserDefaults.standard.set(newValue, forKey: EQNUserDefaultKeyAlertsShowAllCards) }
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@ class EQNMapAnnotationUserReport: NSObject, MKAnnotation {
|
||||
@objc var coordinate: CLLocationCoordinate2D
|
||||
@objc var title: String?
|
||||
@objc var subtitle: String?
|
||||
@objc var image: UIImage?
|
||||
@objc var timeDifference: String?
|
||||
|
||||
private let magnitude: Int
|
||||
var report: EQNSegnalazione?
|
||||
|
||||
// MARK: - Init
|
||||
@@ -37,21 +37,24 @@ class EQNMapAnnotationUserReport: NSObject, MKAnnotation {
|
||||
magnitude: Int,
|
||||
coordinate: CLLocationCoordinate2D
|
||||
) {
|
||||
self.magnitude = magnitude
|
||||
self.coordinate = coordinate
|
||||
self.title = Self.title(for: magnitude)
|
||||
self.subtitle = Self.subtitle(for: magnitude)
|
||||
self.coordinate = coordinate
|
||||
self.image = Self.image(for: magnitude)
|
||||
}
|
||||
|
||||
// MARK: - Helper
|
||||
|
||||
private static func image(for magnitute: Int) -> UIImage? {
|
||||
guard let color = UIColor(named: "Mercalli \(magnitute)") else {
|
||||
print("[EQNMapAnnotationUserReport] Unable to get a color for magnitude: \(magnitute)")
|
||||
@objc(imageWithHeight:)
|
||||
func image(
|
||||
with height: CGFloat
|
||||
) -> UIImage? {
|
||||
guard let color = UIColor(named: "Mercalli \(magnitude)") else {
|
||||
print("[EQNMapAnnotationUserReport] Unable to get a color for magnitude: \(magnitude)")
|
||||
return nil
|
||||
}
|
||||
|
||||
return UIImage.circle(diameter: EQNCustomAnnotationView.SmallHeight, color: color, borderWidth: 1.0, borderColor: .darkGray)
|
||||
return UIImage.circle(diameter: height, color: color, borderWidth: 1.0, borderColor: .black)
|
||||
}
|
||||
|
||||
private static func title(for magnitude: Int) -> String {
|
||||
|
||||
@@ -2032,19 +2032,19 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="190"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1qM-9D-X99">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1qM-9D-X99">
|
||||
<rect key="frame" x="8" y="8" width="398" height="174"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="No real time alert recently received by your smartphone" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aqv-yY-TAs">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No real time alert recently received by your smartphone" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aqv-yY-TAs">
|
||||
<rect key="frame" x="8" y="8" width="382" height="62"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="22"/>
|
||||
<color key="textColor" red="0.047058823529411764" green="0.62745098039215685" blue="0.13725490196078433" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="R9F-ba-WMK">
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="R9F-ba-WMK">
|
||||
<rect key="frame" x="8" y="78" width="382" height="40"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BjK-4E-Vhw" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BjK-4E-Vhw" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="187" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="TEST ALERT 🚨">
|
||||
@@ -2054,7 +2054,7 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<action selector="testAlertTapped" destination="vSa-gk-t22" eventType="touchUpInside" id="HNp-eo-vpW"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qkR-Lg-s4B" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qkR-Lg-s4B" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="195" y="0.0" width="187" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="SIMULATOR ⏱">
|
||||
@@ -2069,10 +2069,10 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<constraint firstAttribute="height" constant="40" id="EgR-4H-j5l"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="ETL-qq-Abj">
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="ETL-qq-Abj">
|
||||
<rect key="frame" x="8" y="126" width="382" height="40"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aAC-Wz-fKA" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aAC-Wz-fKA" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="187" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="HOW IT WORKS 💡">
|
||||
@@ -2082,7 +2082,7 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<action selector="howItWorksTapped" destination="vSa-gk-t22" eventType="touchUpInside" id="kLj-v8-6JR"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tml-Pn-Faa" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tml-Pn-Faa" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="195" y="0.0" width="187" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="SHARE APP 👥">
|
||||
@@ -2137,10 +2137,10 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8aY-un-i0P">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8aY-un-i0P">
|
||||
<rect key="frame" x="8" y="8" width="398" height="144"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Past seismic alerts" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="13" translatesAutoresizingMaskIntoConstraints="NO" id="qss-8q-f70" customClass="EQNEdgeInsetLabel" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Past seismic alerts" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="13" translatesAutoresizingMaskIntoConstraints="NO" id="qss-8q-f70" customClass="EQNEdgeInsetLabel" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="146" height="26"/>
|
||||
<color key="backgroundColor" red="0.50766238939999997" green="0.75272958739999996" blue="0.98132258650000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
@@ -2150,16 +2150,16 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" distribution="fillEqually" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="Wn0-ni-ud8">
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="Wn0-ni-ud8">
|
||||
<rect key="frame" x="134" y="34" width="130.5" height="54"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Last 24h: 0" 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: 0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hbH-vC-Yma">
|
||||
<rect key="frame" x="11.5" y="0.0" width="107.5" 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="Since 2013: 0" 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: 0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l5q-I9-iOb">
|
||||
<rect key="frame" x="0.0" y="29" width="130.5" height="25"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="22"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
@@ -2167,7 +2167,7 @@ Sisma rilevato da 10 smartphone</string>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<button opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="o3D-zn-NCG" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="o3D-zn-NCG" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="8" y="96" width="382" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="I5V-bX-rod"/>
|
||||
@@ -2216,10 +2216,10 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="170"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ahE-3v-miX">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ahE-3v-miX">
|
||||
<rect key="frame" x="8" y="8" width="398" height="154"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Smartphone network" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ngu-Uw-4wO" customClass="EQNEdgeInsetLabel" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Smartphone network" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ngu-Uw-4wO" customClass="EQNEdgeInsetLabel" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="164" height="26"/>
|
||||
<color key="backgroundColor" red="0.50766238939999997" green="0.75272958739999996" blue="0.98132258650000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
@@ -2229,24 +2229,24 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" distribution="fillProportionally" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="niE-pg-jos">
|
||||
<rect key="frame" x="8" y="34" width="382" height="64"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillProportionally" translatesAutoresizingMaskIntoConstraints="NO" id="niE-pg-jos">
|
||||
<rect key="frame" x="8" y="30" width="382" height="72"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="r3y-EB-oyz">
|
||||
<rect key="frame" x="0.0" y="0.0" width="382" height="31.5"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="r3y-EB-oyz">
|
||||
<rect key="frame" x="0.0" y="0.0" width="382" height="37"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="40"/>
|
||||
<color key="textColor" red="0.0039215686274509803" green="0.70588235294117641" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="smartphones are
monitoring for earthquakes" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dnR-12-9yN">
|
||||
<rect key="frame" x="0.0" y="35.5" width="382" height="28.5"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="smartphones are
monitoring for earthquakes" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dnR-12-9yN">
|
||||
<rect key="frame" x="0.0" y="37" width="382" height="35"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="19"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<button opaque="NO" tag="200" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Pkb-ih-spD" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<button opaque="NO" tag="200" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Pkb-ih-spD" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="8" y="106" width="382" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="QAZ-gl-lSE"/>
|
||||
@@ -2267,9 +2267,9 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<constraint firstAttribute="trailing" secondItem="Ngu-Uw-4wO" secondAttribute="trailing" priority="250" id="EOC-za-7F4"/>
|
||||
<constraint firstAttribute="trailing" secondItem="niE-pg-jos" secondAttribute="trailing" constant="8" id="Ntr-m9-veW"/>
|
||||
<constraint firstItem="niE-pg-jos" firstAttribute="leading" secondItem="ahE-3v-miX" secondAttribute="leading" constant="8" id="S5y-GR-Zra"/>
|
||||
<constraint firstItem="Pkb-ih-spD" firstAttribute="top" secondItem="niE-pg-jos" secondAttribute="bottom" constant="8" id="ed8-Gm-NMS"/>
|
||||
<constraint firstItem="Pkb-ih-spD" firstAttribute="top" secondItem="niE-pg-jos" secondAttribute="bottom" constant="4" id="ed8-Gm-NMS"/>
|
||||
<constraint firstItem="Ngu-Uw-4wO" firstAttribute="leading" secondItem="ahE-3v-miX" secondAttribute="leading" id="ggT-NO-C0P"/>
|
||||
<constraint firstItem="niE-pg-jos" firstAttribute="top" secondItem="Ngu-Uw-4wO" secondAttribute="bottom" constant="8" id="hlw-bV-hHd"/>
|
||||
<constraint firstItem="niE-pg-jos" firstAttribute="top" secondItem="Ngu-Uw-4wO" secondAttribute="bottom" constant="4" id="hlw-bV-hHd"/>
|
||||
<constraint firstItem="Pkb-ih-spD" firstAttribute="leading" secondItem="ahE-3v-miX" secondAttribute="leading" constant="8" id="htT-dX-lAU"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Pkb-ih-spD" secondAttribute="bottom" constant="8" id="xtX-bh-EPd"/>
|
||||
</constraints>
|
||||
@@ -2298,10 +2298,10 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="170"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GF8-ah-qqT">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GF8-ah-qqT">
|
||||
<rect key="frame" x="8" y="8" width="398" height="154"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Priority service" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JeR-MS-yEq" customClass="EQNEdgeInsetLabel" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Priority service" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JeR-MS-yEq" customClass="EQNEdgeInsetLabel" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="117.5" height="26"/>
|
||||
<color key="backgroundColor" red="0.50766238939999997" green="0.75272958739999996" blue="0.98132258650000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
@@ -2311,31 +2311,31 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" ambiguous="YES" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="zHS-h1-Tdo">
|
||||
<stackView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="zHS-h1-Tdo">
|
||||
<rect key="frame" x="8" y="34" width="284" height="112"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Be the first to be alerted when a quake is detected real time." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1mF-xh-GVj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="284" height="36"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Be the first to be alerted when a quake is detected real time." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1mF-xh-GVj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="284" height="42.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="A user has subscribed to the service only %d minute ago!" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3dQ-Eh-0Iw">
|
||||
<rect key="frame" x="0.0" y="76" width="284" height="36"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="A user has subscribed to the service only %d minute ago!" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3dQ-Eh-0Iw">
|
||||
<rect key="frame" x="0.0" y="69.5" width="284" height="42.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" name="Red"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="priority" translatesAutoresizingMaskIntoConstraints="NO" id="3Hs-fb-4gz">
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="priority" translatesAutoresizingMaskIntoConstraints="NO" id="3Hs-fb-4gz">
|
||||
<rect key="frame" x="296" y="8" width="98" height="95"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="98" id="e82-JS-FuC"/>
|
||||
<constraint firstAttribute="height" constant="95" id="jV5-l5-FhY"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<button opaque="NO" tag="10" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fko-1v-doJ">
|
||||
<button opaque="NO" tag="10" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fko-1v-doJ">
|
||||
<rect key="frame" x="296" y="29.5" width="94" height="95"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="94" id="f5j-RJ-bnc"/>
|
||||
@@ -2624,43 +2624,43 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<color red="0.10999999940395355" green="0.13300000131130219" blue="0.14900000393390656" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Light blue">
|
||||
<color red="0.50588235294117645" green="0.75294117647058822" blue="0.98039215686274506" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.50599998235702515" green="0.75300002098083496" blue="0.98000001907348633" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 100">
|
||||
<color red="0.792156862745098" green="0.15294117647058825" blue="0.14901960784313725" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.79199999570846558" green="0.15299999713897705" blue="0.14900000393390656" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 110">
|
||||
<color red="0.8666666666666667" green="0.066666666666666666" blue="0.32941176470588235" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.86699998378753662" green="0.067000001668930054" blue="0.32899999618530273" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 120">
|
||||
<color red="0.792156862745098" green="0.023529411764705882" blue="0.52941176470588236" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.79199999570846558" green="0.024000000208616257" blue="0.52899998426437378" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 20">
|
||||
<color red="0.92941176470588238" green="0.93725490196078431" blue="0.95294117647058818" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.92900002002716064" green="0.93699997663497925" blue="0.95300000905990601" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 30">
|
||||
<color red="0.74901960784313726" green="0.7686274509803922" blue="0.85098039215686272" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.74900001287460327" green="0.76899999380111694" blue="0.85100001096725464" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 40">
|
||||
<color red="0.6705882352941176" green="0.84313725490196079" blue="0.8901960784313725" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.67100000381469727" green="0.84299999475479126" blue="0.88999998569488525" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 50">
|
||||
<color red="0.59607843137254901" green="0.78431372549019607" blue="0.56470588235294117" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.59600001573562622" green="0.7839999794960022" blue="0.56499999761581421" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 60">
|
||||
<color red="0.96078431372549022" green="0.92549019607843142" blue="0.13725490196078433" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.96100002527236938" green="0.92500001192092896" blue="0.13699999451637268" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 70">
|
||||
<color red="0.93725490196078431" green="0.76470588235294112" blue="0.058823529411764705" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.93699997663497925" green="0.76499998569488525" blue="0.059000000357627869" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 80">
|
||||
<color red="0.8666666666666667" green="0.52941176470588236" blue="0.14509803921568629" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.86699998378753662" green="0.52899998426437378" blue="0.14499999582767487" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Mercalli 90">
|
||||
<color red="0.81960784313725488" green="0.32941176470588235" blue="0.14117647058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.81999999284744263" green="0.32899999618530273" blue="0.14100000262260437" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="Red">
|
||||
<color red="1" green="0.14901960784313725" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="1" green="0.14900000393390656" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<systemColor name="groupTableViewBackgroundColor">
|
||||
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
||||
@@ -17,9 +17,14 @@ public class EQNCustomAnnotationView: MKAnnotationView {
|
||||
@objc static let SingleLineIdentifier = "EQNCustomAnnotationViewSingleLine"
|
||||
@objc static let DoubleLineIdentifier = "EQNCustomAnnotationViewDoubleLine"
|
||||
|
||||
static let SmallHeight: CGFloat = 12.0
|
||||
private static let HeightLabel: CGFloat = 15.0
|
||||
|
||||
@objc static let SmallViewHeight: CGFloat = 12.0
|
||||
@objc static let SmallViewImageHeight: CGFloat = SmallViewHeight
|
||||
@objc static let SingleLineViewHeight: CGFloat = 40.0
|
||||
@objc static let SingleLineLabelHeight: CGFloat = 15.0
|
||||
@objc static let SingleLineImageHeight: CGFloat = SingleLineViewHeight - SingleLineLabelHeight
|
||||
@objc static let DoubleLineViewHeight: CGFloat = 55.0
|
||||
@objc static let DoubleLineLabelHeight: CGFloat = 15.0
|
||||
@objc static let DoubleLineImageHeight: CGFloat = DoubleLineViewHeight - 2*DoubleLineLabelHeight
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
@@ -70,13 +75,13 @@ public class EQNCustomAnnotationView: MKAnnotationView {
|
||||
backgroundColor = .clear
|
||||
|
||||
if reuseIdentifier == Self.SmallIdentifier {
|
||||
frame = CGRect(x: 0, y: 0, width: Self.SmallHeight, height: Self.SmallHeight)
|
||||
frame = CGRect(x: 0, y: 0, width: Self.SmallViewHeight, height: Self.SmallViewHeight)
|
||||
setupSmallUI()
|
||||
} else if reuseIdentifier == Self.SingleLineIdentifier {
|
||||
frame = CGRect(x: 0, y: 0, width: 40, height: 40)
|
||||
frame = CGRect(x: 0, y: 0, width: Self.SingleLineViewHeight, height: Self.SingleLineViewHeight)
|
||||
setupSingleLineUI()
|
||||
} else if reuseIdentifier == Self.DoubleLineIdentifier {
|
||||
frame = CGRect(x: 0, y: 0, width: 40, height: 55)
|
||||
frame = CGRect(x: 0, y: 0, width: 40, height: Self.DoubleLineViewHeight)
|
||||
setupDoubleLineUI()
|
||||
}
|
||||
}
|
||||
@@ -93,7 +98,7 @@ public class EQNCustomAnnotationView: MKAnnotationView {
|
||||
}
|
||||
|
||||
private func setupSingleLineUI() {
|
||||
let labelFrame = CGRect(x: 0, y: 0, width: frame.width, height: Self.HeightLabel)
|
||||
let labelFrame = CGRect(x: 0, y: 0, width: frame.width, height: Self.SingleLineLabelHeight)
|
||||
labelTop.frame = labelFrame
|
||||
addSubview(labelTop)
|
||||
|
||||
@@ -101,12 +106,12 @@ public class EQNCustomAnnotationView: MKAnnotationView {
|
||||
imageView.frame = CGRect(x: 0, y: labelFrame.height, width: frame.width, height: imageViewHeight)
|
||||
addSubview(imageView)
|
||||
|
||||
let yOffeset = frame.height / 2.0 - (Self.HeightLabel + imageViewHeight / 2.0)
|
||||
let yOffeset = frame.height / 2.0 - (Self.SingleLineLabelHeight + imageViewHeight / 2.0)
|
||||
centerOffset = CGPoint(x: 0, y: yOffeset)
|
||||
}
|
||||
|
||||
private func setupDoubleLineUI() {
|
||||
let labelTopFrame = CGRect(x: 0, y: 0, width: frame.width, height: Self.HeightLabel)
|
||||
let labelTopFrame = CGRect(x: 0, y: 0, width: frame.width, height: Self.DoubleLineLabelHeight)
|
||||
labelTop.frame = labelTopFrame
|
||||
addSubview(labelTop)
|
||||
|
||||
@@ -114,7 +119,7 @@ public class EQNCustomAnnotationView: MKAnnotationView {
|
||||
imageView.frame = CGRect(x: 0, y: labelTopFrame.height, width: frame.width, height: imageViewHeight)
|
||||
addSubview(imageView)
|
||||
|
||||
labelBottom.frame = CGRect(x: 0, y: imageView.frame.maxY, width: frame.width, height: Self.HeightLabel)
|
||||
labelBottom.frame = CGRect(x: 0, y: imageView.frame.maxY, width: frame.width, height: Self.DoubleLineLabelHeight)
|
||||
addSubview(labelBottom)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
"NSPhotoLibraryAddUsageDescription" = "Απαιτείται πρόσβαση στη βιβλιοθήκη για να αποθηκεύσετε τις εικόνες που δημιουργούνται από την εφαρμογή";
|
||||
"NSCalendarsUsageDescription" = "Απαιτείται πρόσβαση στο ημερολόγιο προκειμένου να σωθούν οι πληροφορίες των σεισμών ενδιαφέροντος";
|
||||
"NSContactsUsageDescription" = "Απαιτείται πρόσβαση στις επαφές για να προσθέσετε άτομα στα δημιουργημένα συμβάντα";
|
||||
"NSUserTrackingUsageDescription" = "Η παρακολούθηση χρησιμοποιείται για να κατανοήσουμε εάν η διαφήμιση της εφαρμογής είναι αποτελεσματική";
|
||||
"CFBundleDisplayName" = "Ανιχνευτής Σεισμών";
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
"NSPhotoLibraryAddUsageDescription" = "Access to the library is required in order to save the images generated by the app";
|
||||
"NSCalendarsUsageDescription" = "Access to the calendar is required in order to save the information of the earthquakes of interest";
|
||||
"NSContactsUsageDescription" = "Access to contacts is required in order to add people to the created events";
|
||||
"NSUserTrackingUsageDescription" = "Tracking is used to understand if the advertising of the app is effective";
|
||||
"CFBundleDisplayName" = "Earthquake Network";
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
"NSPhotoLibraryAddUsageDescription" = "Se requiere acceso a la biblioteca para guardar las imágenes generadas por la aplicación";
|
||||
"NSCalendarsUsageDescription" = "Se requiere acceso al calendario para guardar la información de los terremotos de interés";
|
||||
"NSContactsUsageDescription" = "Se requiere acceso a los contactos para agregar personas a los eventos creados";
|
||||
"NSUserTrackingUsageDescription" = "El seguimiento se utiliza para comprender si la publicidad de la aplicación es efectiva";
|
||||
"CFBundleDisplayName" = "Sismos Detector";
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
"NSPhotoLibraryAddUsageDescription" = "L'accès à la bibliothèque est nécessaire pour enregistrer les images générées par l'application";
|
||||
"NSCalendarsUsageDescription" = "L'accès au calendrier est nécessaire afin de sauvegarder les informations des tremblements de terre d'intérêt";
|
||||
"NSContactsUsageDescription" = "L'accès aux contacts est requis pour ajouter des personnes aux événements créés";
|
||||
"NSUserTrackingUsageDescription" = "Le suivi est utilisé pour comprendre si la publicité de l'application est efficace";
|
||||
"CFBundleDisplayName" = "Détecteur de Séisme";
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
"NSPhotoLibraryAddUsageDescription" = "Pristup knjižnici potreban je kako biste spremili slike generirane u aplikaciji";
|
||||
"NSCalendarsUsageDescription" = "Pristup kalendaru potreban je kako bi se sačuvale informacije o potresima od interesa";
|
||||
"NSContactsUsageDescription" = "Pristup kontaktima potreban je kako biste dodali ljude u stvorene događaje";
|
||||
"NSUserTrackingUsageDescription" = "Praćenje se koristi kako bi se shvatilo je li oglašavanje aplikacije učinkovito";
|
||||
"CFBundleDisplayName" = "Detektor Potresa";
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
"NSPhotoLibraryAddUsageDescription" = "Akses ke perpustakaan diperlukan untuk menyimpan gambar yang dihasilkan oleh aplikasi";
|
||||
"NSCalendarsUsageDescription" = "Akses ke kalender diperlukan untuk menyimpan informasi gempa yang menarik";
|
||||
"NSContactsUsageDescription" = "Akses ke kontak diperlukan untuk menambahkan orang ke acara yang dibuat";
|
||||
"NSUserTrackingUsageDescription" = "Pelacakan digunakan untuk memahami apakah iklan aplikasi efektif";
|
||||
"CFBundleDisplayName" = "Detektor Gempa";
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
"NSPhotoLibraryAddUsageDescription" = "L'accesso alla libreria è richiesto per poter salvare le immagini generate dall'app";
|
||||
"NSCalendarsUsageDescription" = "L'accesso al calendario è richiesto per poter salvare le informazioni dei sismi di interesse";
|
||||
"NSContactsUsageDescription" = "L'accesso ai contatti è richiesto per poter aggiungere persone agli eventi creati";
|
||||
"NSUserTrackingUsageDescription" = "Il tracciamento serve a capire se la pubblicità dell'app è efficace";
|
||||
"CFBundleDisplayName" = "Rilevatore Terremoto";
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
"NSPhotoLibraryAddUsageDescription" = "Uygulama tarafından oluşturulan görüntüleri kaydetmek için kitaplığa erişim gereklidir";
|
||||
"NSCalendarsUsageDescription" = "İlgili depremlere ait bilgilerin kaydedilebilmesi için takvime erişim gereklidir.";
|
||||
"NSContactsUsageDescription" = "Kişileri oluşturulan etkinliklere eklemek için kişilere erişim gereklidir";
|
||||
"NSUserTrackingUsageDescription" = "İzleme, uygulamanın reklamının etkili olup olmadığını anlamak için kullanılır";
|
||||
"CFBundleDisplayName" = "Deprem Ağı";
|
||||
|
||||
@@ -8,6 +8,7 @@ target 'Earthquake Network' do
|
||||
pod 'Firebase/Messaging'
|
||||
pod 'Firebase/Crashlytics'
|
||||
pod 'Google-Mobile-Ads-SDK'
|
||||
pod 'FBSDKCoreKit'
|
||||
pod 'DZNEmptyDataSet'
|
||||
pod 'Solar'
|
||||
end
|
||||
|
||||
+14
-1
@@ -1,5 +1,11 @@
|
||||
PODS:
|
||||
- DZNEmptyDataSet (1.8.1)
|
||||
- FBAEMKit (15.1.0):
|
||||
- FBSDKCoreKit_Basics (= 15.1.0)
|
||||
- FBSDKCoreKit (15.1.0):
|
||||
- FBAEMKit (= 15.1.0)
|
||||
- FBSDKCoreKit_Basics (= 15.1.0)
|
||||
- FBSDKCoreKit_Basics (15.1.0)
|
||||
- Firebase/Core (10.1.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (~> 10.1.0)
|
||||
@@ -113,6 +119,7 @@ PODS:
|
||||
|
||||
DEPENDENCIES:
|
||||
- DZNEmptyDataSet
|
||||
- FBSDKCoreKit
|
||||
- Firebase/Core
|
||||
- Firebase/Crashlytics
|
||||
- Firebase/Messaging
|
||||
@@ -122,6 +129,9 @@ DEPENDENCIES:
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- DZNEmptyDataSet
|
||||
- FBAEMKit
|
||||
- FBSDKCoreKit
|
||||
- FBSDKCoreKit_Basics
|
||||
- Firebase
|
||||
- FirebaseAnalytics
|
||||
- FirebaseCore
|
||||
@@ -140,6 +150,9 @@ SPEC REPOS:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
DZNEmptyDataSet: 9525833b9e68ac21c30253e1d3d7076cc828eaa7
|
||||
FBAEMKit: c7f82b5145d446bcbbcd50485c032689032fc6a2
|
||||
FBSDKCoreKit: 7542746fc63a2a38dd6a865eeb54268341f37b83
|
||||
FBSDKCoreKit_Basics: 92d6b26c0bed30ab09bbdd96dccaa26e6c9978d1
|
||||
Firebase: 444b35a9c568a516666213c2f6cccd10cb12559f
|
||||
FirebaseAnalytics: 24cb27b52b2e11ad5013528195b4ca0755dec960
|
||||
FirebaseCore: 55e7ae35991ccca4db03ff8d8df6ed5f17a3e4c7
|
||||
@@ -156,6 +169,6 @@ SPEC CHECKSUMS:
|
||||
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
|
||||
Solar: 2dc6e7cc39186cb0c8228fa08df76fb50c7d8f24
|
||||
|
||||
PODFILE CHECKSUM: dd5131b6d7a83fb7c22ecc161ed4fc143eda0ac1
|
||||
PODFILE CHECKSUM: 8ea8b5074e46a5d9288cef7a482f8c5bebe2d6e2
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
Reference in New Issue
Block a user