// // AppDelegate.m // Juick // // Created by Vitaly Takmazov on 26.10.13. // Copyright (c) 2013 com.juick. All rights reserved. // #import "ThreadViewController.h" #import "LoginViewController.h" #import "Message.h" #import "User.h" #import "DeviceRegistration.h" #import "NewPostViewController.h" #import "FeedViewController.h" #import "NSData+Hex.h" @interface AppDelegate() -(void) parseNotificationPayload:(NSDictionary *)userInfo; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // cleanup synchronized credentials which are not used anymore NSDictionary *dict = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials]; NSDictionary *dictCopy = [dict copy]; for(NSURLProtectionSpace *key in [dictCopy keyEnumerator]) { if ([key.host isEqual:@"api.juick.com"]) { NSDictionary *value = [dict objectForKey:key]; NSArray *creds = [value allValues]; for (NSURLCredential *cred in creds) { [[NSURLCredentialStorage sharedCredentialStorage] removeCredential:cred forProtectionSpace:key options:@{ NSURLCredentialStorageRemoveSynchronizableCredentials:@YES}]; } } } self.api = [API new]; self.sharedDateFormatter = [NSDateFormatter new]; self.sharedDateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss"; [self.sharedDateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]]; NSDictionary *titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor colorNamed:@"Muted"]}; if (@available(iOS 13.0, *)) { UINavigationBarAppearance *appearance = [UINavigationBarAppearance new]; [appearance configureWithOpaqueBackground]; [appearance setTitleTextAttributes:titleTextAttributes]; [UINavigationBar appearance].standardAppearance = appearance; if (@available(iOS 15.0, *)) { [UINavigationBar appearance].scrollEdgeAppearance = appearance; } } else { [[UINavigationBar appearance] setTitleTextAttributes:titleTextAttributes]; [[UINavigationBar appearance] setTranslucent:NO]; } [[UITabBar appearance] setTintColor:[UIColor colorNamed:@"Title"]]; [self registerForRemoteNotifications]; NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]; if (userInfo) { [self parseNotificationPayload:userInfo]; } UISplitViewController *splitViewController = (UISplitViewController *)[self window].rootViewController; #if TARGET_OS_MACCATALYST splitViewController.primaryBackgroundStyle = UISplitViewControllerBackgroundStyleSidebar; #else splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; #endif return YES; } - (void)registerForRemoteNotifications { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){ if (!error) { [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [[UIApplication sharedApplication] registerForRemoteNotifications]; }]; } }]; } -(void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [deviceToken hexString]; [[NSOperationQueue new] addOperationWithBlock:^{ DeviceRegistration *registration = [DeviceRegistration new]; registration.type = @"apns"; registration.token = token; [self.api refreshDeviceRegistration:registration callback:^(BOOL success) { if (success) { NSLog(@"successfully refreshed registration with %@", token); } }]; }]; } -(void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"Error: %@", [error debugDescription]); } //Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{ completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); } //Called to let your app know which action was selected by the user for a given notification. -(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler{ NSDictionary *userInfo = response.notification.request.content.userInfo; [self parseNotificationPayload:userInfo]; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ UITabBarController *main = (UITabBarController *)[self navigator]; UINavigationController *root = main.navigationController; [root popToRootViewControllerAnimated:NO]; if ([self.pushedThread integerValue] > 0) { [main setSelectedIndex:0]; MessagesViewController *discover = (MessagesViewController *)[main.viewControllers objectAtIndex:0]; [discover viewThreadForMessage:nil mid:self.pushedThread scrollTo:self.pushedReplyId]; [self cleanupPushedData]; } else { [main setSelectedIndex:2]; MessagesViewController *dialogs = (MessagesViewController *)[main.viewControllers objectAtIndex:2]; [dialogs performSegueWithIdentifier:@"chatSegue" sender:dialogs]; } completionHandler(); }]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { if (userInfo[@"service"]) { User *user = [User fromJSON:userInfo[@"user"]]; application.applicationIconBadgeNumber = user.unreadCount; [[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray * _Nonnull notifications) { for (UNNotification* notification in notifications) { if ([notification.request.content.userInfo[@"mid"] integerValue] == [userInfo[@"mid"] integerValue]) { [[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[notification.request.identifier]]; } } completionHandler(UIBackgroundFetchResultNewData); }]; } else { completionHandler(UIBackgroundFetchResultNoData); } } -(void) parseNotificationPayload:(NSDictionary *)userInfo { self.pushedThread = userInfo[@"mid"]; self.pushedUname = userInfo[@"uname"]; self.pushedReplyId = userInfo[@"rid"]; } -(void) cleanupPushedData { self.pushedUname = nil; self.pushedThread = nil; self.pushedReplyId = nil; } +(AppDelegate *) shared { return (AppDelegate *)[UIApplication sharedApplication].delegate; } - (void)presentThread:(UIViewController *)vc { [[self navigator] performSegueWithIdentifier:@"threadSegue" sender:vc]; } - (void) presentEditor:(UIViewController *)vc { [[self navigator] performSegueWithIdentifier:@"editorSegue" sender:vc]; } - (void) presentLoginView:(UIViewController *)vc { [[self navigator] performSegueWithIdentifier:@"loginSegue" sender:vc]; } - (void)unauthorized { [self presentLoginView:self.window.rootViewController]; } @end