2021-01-22 06:54:11 +01:00
|
|
|
//
|
|
|
|
// AppDelegate.swift
|
|
|
|
// Mastodon
|
|
|
|
//
|
|
|
|
// Created by MainasuK Cirno on 2021/1/22.
|
|
|
|
//
|
|
|
|
|
2021-04-25 06:48:29 +02:00
|
|
|
import os.log
|
2021-01-22 06:54:11 +01:00
|
|
|
import UIKit
|
2021-04-27 11:27:03 +02:00
|
|
|
import UserNotifications
|
2021-04-27 10:26:59 +02:00
|
|
|
import AppShared
|
2021-06-30 12:02:01 +02:00
|
|
|
import AVFoundation
|
2021-07-19 11:12:45 +02:00
|
|
|
@_exported import MastodonUI
|
2021-01-22 06:54:11 +01:00
|
|
|
|
2021-06-22 07:41:40 +02:00
|
|
|
#if ASDK
|
|
|
|
import AsyncDisplayKit
|
|
|
|
#endif
|
|
|
|
|
2021-01-22 06:54:11 +01:00
|
|
|
@main
|
|
|
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
|
|
|
2021-01-27 07:50:13 +01:00
|
|
|
let appContext = AppContext()
|
2021-01-22 06:54:11 +01:00
|
|
|
|
|
|
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
2021-02-26 11:36:38 +01:00
|
|
|
|
2021-04-27 10:26:59 +02:00
|
|
|
AppSecret.default.register()
|
2021-07-05 10:07:17 +02:00
|
|
|
|
|
|
|
// configure appearance
|
|
|
|
ThemeService.shared.apply(theme: ThemeService.shared.currentTheme.value)
|
2021-04-27 10:26:59 +02:00
|
|
|
|
2021-02-26 11:36:38 +01:00
|
|
|
// Update app version info. See: `Settings.bundle`
|
|
|
|
UserDefaults.standard.setValue(UIApplication.appVersion(), forKey: "Mastodon.appVersion")
|
|
|
|
UserDefaults.standard.setValue(UIApplication.appBuild(), forKey: "Mastodon.appBundle")
|
2021-03-01 05:28:08 +01:00
|
|
|
|
2021-06-17 08:30:24 +02:00
|
|
|
// Setup notification
|
2021-04-27 10:26:59 +02:00
|
|
|
UNUserNotificationCenter.current().delegate = self
|
2021-04-25 06:48:29 +02:00
|
|
|
application.registerForRemoteNotifications()
|
|
|
|
|
2021-06-22 07:41:40 +02:00
|
|
|
#if ASDK && DEBUG
|
2021-06-20 18:14:47 +02:00
|
|
|
// PerformanceMonitor.shared().start()
|
2021-06-19 12:33:29 +02:00
|
|
|
// ASDisplayNode.shouldShowRangeDebugOverlay = true
|
2021-06-20 18:14:47 +02:00
|
|
|
// ASControlNode.enableHitTestDebug = true
|
|
|
|
// ASImageNode.shouldShowImageScalingOverlay = true
|
2021-06-17 10:31:34 +02:00
|
|
|
#endif
|
|
|
|
|
2021-03-01 05:28:08 +01:00
|
|
|
return true
|
2021-01-22 06:54:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: UISceneSession Lifecycle
|
|
|
|
|
|
|
|
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
|
|
|
// Called when a new scene session is being created.
|
|
|
|
// Use this method to select a configuration to create the new scene with.
|
|
|
|
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
|
|
|
}
|
|
|
|
|
|
|
|
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
|
|
|
|
// Called when the user discards a scene session.
|
|
|
|
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
|
|
|
|
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
|
|
|
|
}
|
|
|
|
|
2021-07-01 05:49:30 +02:00
|
|
|
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2021-01-22 06:54:11 +01:00
|
|
|
}
|
|
|
|
|
2021-01-27 07:50:13 +01:00
|
|
|
extension AppDelegate {
|
2021-06-28 13:41:41 +02:00
|
|
|
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
|
|
|
|
#if DEBUG
|
|
|
|
return .all
|
|
|
|
#else
|
2021-03-02 06:45:47 +01:00
|
|
|
return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all
|
2021-06-28 13:41:41 +02:00
|
|
|
#endif
|
2021-01-27 07:50:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-25 06:48:29 +02:00
|
|
|
extension AppDelegate {
|
|
|
|
|
|
|
|
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
|
|
|
appContext.notificationService.deviceToken.value = deviceToken
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - UNUserNotificationCenterDelegate
|
|
|
|
extension AppDelegate: UNUserNotificationCenterDelegate {
|
2021-04-27 11:45:11 +02:00
|
|
|
|
|
|
|
// notification present in the foreground
|
2021-04-27 10:26:59 +02:00
|
|
|
func userNotificationCenter(
|
|
|
|
_ center: UNUserNotificationCenter,
|
|
|
|
willPresent notification: UNNotification,
|
|
|
|
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
|
|
|
|
) {
|
|
|
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: [Push Notification]", ((#file as NSString).lastPathComponent), #line, #function)
|
2021-04-27 11:27:03 +02:00
|
|
|
guard let mastodonPushNotification = AppDelegate.mastodonPushNotification(from: notification) else {
|
|
|
|
completionHandler([])
|
|
|
|
return
|
2021-04-27 10:26:59 +02:00
|
|
|
}
|
2021-04-27 11:27:03 +02:00
|
|
|
|
|
|
|
let notificationID = String(mastodonPushNotification.notificationID)
|
|
|
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: [Push Notification] notification %s", ((#file as NSString).lastPathComponent), #line, #function, notificationID)
|
2021-09-16 10:30:21 +02:00
|
|
|
|
|
|
|
let accessToken = mastodonPushNotification.accessToken
|
|
|
|
UserDefaults.shared.increaseNotificationCount(accessToken: accessToken)
|
|
|
|
appContext.notificationService.applicationIconBadgeNeedsUpdate.send()
|
|
|
|
|
2021-04-27 12:05:29 +02:00
|
|
|
appContext.notificationService.handle(mastodonPushNotification: mastodonPushNotification)
|
2021-04-27 11:27:03 +02:00
|
|
|
completionHandler([.sound])
|
2021-04-27 10:26:59 +02:00
|
|
|
}
|
2021-04-25 06:48:29 +02:00
|
|
|
|
2021-10-11 13:19:27 +02:00
|
|
|
// response to user action for notification (e.g. redirect to post)
|
2021-04-27 10:26:59 +02:00
|
|
|
func userNotificationCenter(
|
|
|
|
_ center: UNUserNotificationCenter,
|
|
|
|
didReceive response: UNNotificationResponse,
|
|
|
|
withCompletionHandler completionHandler: @escaping () -> Void
|
|
|
|
) {
|
|
|
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: [Push Notification]", ((#file as NSString).lastPathComponent), #line, #function)
|
|
|
|
|
2021-04-27 11:27:03 +02:00
|
|
|
guard let mastodonPushNotification = AppDelegate.mastodonPushNotification(from: response.notification) else {
|
|
|
|
completionHandler()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
let notificationID = String(mastodonPushNotification.notificationID)
|
|
|
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: [Push Notification] notification %s", ((#file as NSString).lastPathComponent), #line, #function, notificationID)
|
2021-04-27 12:05:29 +02:00
|
|
|
appContext.notificationService.handle(mastodonPushNotification: mastodonPushNotification)
|
2021-10-11 13:19:27 +02:00
|
|
|
appContext.notificationService.requestRevealNotificationPublisher.send(mastodonPushNotification)
|
2021-04-27 11:27:03 +02:00
|
|
|
completionHandler()
|
|
|
|
}
|
|
|
|
|
|
|
|
private static func mastodonPushNotification(from notification: UNNotification) -> MastodonPushNotification? {
|
|
|
|
guard let plaintext = notification.request.content.userInfo["plaintext"] as? Data,
|
|
|
|
let mastodonPushNotification = try? JSONDecoder().decode(MastodonPushNotification.self, from: plaintext) else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return mastodonPushNotification
|
2021-04-27 10:26:59 +02:00
|
|
|
}
|
2021-04-27 11:45:11 +02:00
|
|
|
|
2021-04-25 06:48:29 +02:00
|
|
|
}
|
2021-01-27 07:50:13 +01:00
|
|
|
|
|
|
|
extension AppContext {
|
|
|
|
static var shared: AppContext {
|
|
|
|
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
|
|
|
return appDelegate.appContext
|
|
|
|
}
|
|
|
|
}
|