Files
2025-07-24 16:46:29 +02:00

250 lines
10 KiB
Objective-C

//
// AppDelegate.m
// Earthquake Network
//
// Created by Luca Beretta on 12/09/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "AppDelegate.h"
#import "Costanti.h"
#import "EQNUser.h"
#import "EQNAccelerometroManager.h"
#import "EQNManager.h"
#import "EQNMainTabBarController.h"
#import "NSDictionary+EQNExtensions.h"
@import UserNotifications;
@import AppTrackingTransparency;
@import FirebaseCore;
@import FirebaseMessaging;
@import FirebaseCrashlytics;
@import GoogleMobileAds;
@import FBSDKCoreKit;
@interface AppDelegate () <FIRMessagingDelegate, UNUserNotificationCenterDelegate>
@property (strong, nonatomic) NSArray<id<EQNCommandProtocol>> *commands;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef DEBUG
// Test ads on specific devices
GADMobileAds.sharedInstance.requestConfiguration.testDeviceIdentifiers = @[ @"81392581e1790d4fbc6eff919815088d" ];
#endif
#if ADS_ENABLED
// start 3rd party SDKs and custom managers
[GADMobileAds.sharedInstance startWithCompletionHandler:^(GADInitializationStatus *status) {
NSLog(@"[AppDelegate] GADMobileAds started with status: %@", status);
}];
#endif
// execute commands
EQNStartupCommandsBuilder *builder = [[EQNStartupCommandsBuilder alloc] init];
self.commands = [builder build];
[builder executeWithCommands:self.commands];
[EQNUser defaultUser];
[EQNManager defaultManager];
[self configureFirebase];
[self configureFacebookSDKWithApplication:application andOptions:launchOptions];
// schedule background tasks
[BackgroundTaskManager.shared registerTasks];
[BackgroundTaskManager.shared scheduleUpdateServerPosition];
// add some generic logs for Crashlytics
NSString *language = [[NSLocale preferredLanguages] firstObject];
[[FIRCrashlytics crashlytics] setCustomValue:language forKey:@"lang"];
[self configurePushNotifications];
[application registerForRemoteNotifications];
return YES;
}
-(void)registraNotifica{
UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"notifica_con_mappa" actions:@[] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObject: category]];
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// 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.
// disabilitiamo logica calibrazione/monitoraggio perchè attualmente non utilizzata dal server
//[[EQNManager defaultManager] avviaManager];
//[[EQNAccelerometroManager sharedInstance] startUpdatingLocationBackground];
NSUInteger counter = [[NSUserDefaults standardUserDefaults] integerForKey:NSUserDefaults.UserDataProDiscountOpenCounter];
counter += 1;
[[NSUserDefaults standardUserDefaults] setInteger:counter forKey:NSUserDefaults.UserDataProDiscountOpenCounter];
}
- (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];
[[EQNAccelerometroManager sharedInstance] stopUpdatingLocation];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token = [self stringWithDeviceToken:deviceToken];
NSLog(@"[DEBUG] push token: %@", token);
[[NSUserDefaults standardUserDefaults] setObject:token forKey:NSUserDefaults.UserDataPushToken];
FIRMessaging.messaging.APNSToken = deviceToken;
}
- (NSString *)stringWithDeviceToken:(NSData *)deviceToken
{
const char *data = [deviceToken bytes];
NSMutableString *token = [NSMutableString string];
for (NSUInteger i = 0; i < [deviceToken length]; i++) {
[token appendFormat:@"%02.2hhX", data[i]];
}
return [token copy];
}
#pragma mark - UNUserNotificationCenterDelegate
// Receive displayed notifications for iOS 10 devices.
// Handle incoming notification messages while app is in the foreground.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
// execute common logic and refresh the proper tab
UNNotificationContent *content = notification.request.content;
[self handlePushNotificationWithNotificationContent:content];
// Change this to your preferred presentation option
completionHandler(UNNotificationPresentationOptionList | UNNotificationPresentationOptionBanner | UNNotificationPresentationOptionSound);
}
// Handle notification messages after display notification is tapped by the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler
{
NSLog(@"[DEBUG] push payload\n%@", [response.notification.request.content.userInfo eqn_jsonStringWithPrettyPrint:YES]);
// execute common logic and refresh the proper tab
UNNotificationContent *content = response.notification.request.content;
[self handlePushNotificationWithNotificationContent:content];
completionHandler();
}
#pragma mark - Private
- (void)handlePushNotificationWithNotificationContent:(UNNotificationContent *)content
{
NSString *type = content.userInfo[@"type"];
// Store both original payload and modified title/body
// This will be usefull to avoid to re-evaluate logic for title display.
NSDictionary *notification = @{
@"title": content.title,
@"body": content.body,
@"userInfo": content.userInfo
};
EQNTabBarSection section = EQNTabBarSectionAllerte;
if ([type isEqualToString:@"eqn"]) {
[EQNRealtimePushNotification storeNotificationWithPayload:notification];
section = EQNTabBarSectionAllerte;
} else if([type isEqualToString:@"manual"]) {
section = EQNTabBarSectionSegnalazioni;
} else if([type isEqualToString:@"official"]) {
[EQNOfficialPushNotification storeNotificationWithPayload:notification];
section = EQNTabBarSectionRetiSismiche;
}
[self.mainTabBarController sincronizza];
[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
{
// 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;
}
}];
});
}
- (void)configureFirebase
{
[FIRApp configure];
[FIRMessaging messaging].delegate = self;
}
- (void)configureFacebookSDKWithApplication:(UIApplication *)application andOptions:(NSDictionary *)launchOptions
{
[FBSDKApplicationDelegate.sharedInstance application:application didFinishLaunchingWithOptions:launchOptions];
FBSDKSettings.sharedSettings.isAdvertiserIDCollectionEnabled = YES;
}
#pragma mark - FIRMessagingDelegate
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken
{
NSLog(@"[Firebase] fcmToken %@", fcmToken);
if (EQNUserData.sharedData.isFirstStart) {
// save default values for notification settings
[EQNSettingRealTimeAlert saveDefaultValues];
[EQNSettingUserReportNotification saveDefaultValues];
[EQNSettingSeismicNetworkNotification saveDefaultValues];
}
[EQNUser.defaultUser registerUserIfNeededWithFirebaseToken:fcmToken];
}
@end