AppDelegate.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import FirebaseCore
  2. import FirebaseCrashlytics
  3. import SwiftUI
  4. import UIKit
  5. import UserNotifications
  6. class AppDelegate: NSObject, UIApplicationDelegate, ObservableObject, UNUserNotificationCenterDelegate {
  7. func application(
  8. _: UIApplication,
  9. didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?
  10. ) -> Bool {
  11. FirebaseApp.configure()
  12. // Default to `true` if the key doesn't exist
  13. let crashReportingEnabled: Bool = PropertyPersistentFlags.shared.diagnosticsSharingEnabled ?? true
  14. // The docs say that changes to this don't take effect until
  15. // the next app boot, but this is fine since the app will need
  16. // to boot after a crash
  17. Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(crashReportingEnabled)
  18. Crashlytics.crashlytics().setCustomValue(Bundle.main.appDevVersion ?? "unknown", forKey: "app_dev_version")
  19. // Telemetry: record this cold launch into the sliding 7-day window. If
  20. // consent is set and the build SHA changed since the last successful
  21. // send, fire an immediate ping — the 24h scheduler can't notice a
  22. // build update on its own. Then arm the recurring 24h timer.
  23. TelemetryClient.shared.recordColdLaunch()
  24. Task.detached {
  25. if TelemetryClient.shared.buildShaChangedSinceLastSend() {
  26. await TelemetryClient.shared.maybeSend()
  27. }
  28. TelemetryClient.shared.scheduleRecurring()
  29. }
  30. return true
  31. }
  32. func application(
  33. _: UIApplication,
  34. didReceiveRemoteNotification userInfo: [AnyHashable: Any],
  35. fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
  36. ) {
  37. debug(.remoteControl, "Received notification")
  38. do {
  39. let jsonData = try JSONSerialization.data(withJSONObject: userInfo)
  40. let encryptedMessage = try JSONDecoder().decode(EncryptedPushMessage.self, from: jsonData)
  41. Task {
  42. do {
  43. try await TrioRemoteControl.shared.handleRemoteNotification(encryptedData: encryptedMessage.encryptedData)
  44. completionHandler(.newData)
  45. } catch {
  46. debug(
  47. .default,
  48. "\(DebuggingIdentifiers.failed) failed to handle remote notification with error: \(error)"
  49. )
  50. completionHandler(.failed)
  51. }
  52. }
  53. } catch {
  54. debug(.remoteControl, "Error decoding push message shell: \(error)")
  55. completionHandler(.failed)
  56. }
  57. }
  58. func application(
  59. _: UIApplication,
  60. didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
  61. ) {
  62. let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
  63. let token = tokenParts.joined()
  64. Task {
  65. do {
  66. try await TrioRemoteControl.shared.handleAPNSChanges(deviceToken: token)
  67. } catch {
  68. debug(
  69. .remoteControl,
  70. "\(DebuggingIdentifiers.failed) failed to register for remote notifications: \(error)"
  71. )
  72. }
  73. }
  74. }
  75. func application(
  76. _: UIApplication,
  77. didFailToRegisterForRemoteNotificationsWithError error: Error
  78. ) {
  79. debug(.remoteControl, "Failed to register for remote notifications: \(error)")
  80. }
  81. }