Newer
Older
public class AppDelegate: UIResponder, UIApplicationDelegate {
@Dependency private var pushRouter: PushRouter
@Dependency private var pushHandler: PushHandling
@Dependency private var crashReporter: CrashReporter
@Dependency private var dropboxService: DropboxInterface
@KeyObject(.hideAppList, defaultValue: false) var hideAppList: Bool
@KeyObject(.recordingLogs, defaultValue: true) var recordingLogs: Bool
@KeyObject(.crashReporting, defaultValue: true) var isCrashReportingEnabled: Bool
var calledStopNetwork = false
var forceFailedPendingMessages = false
var coverView: UIView?
var backgroundTimer: Timer?
public var window: UIWindow?
public func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
#if DEBUG
DependencyRegistrator.registerForMock()
#else
DependencyRegistrator.registerForLive()
#endif
if recordingLogs {
XXLogger.start()
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
crashReporter.configure()
crashReporter.setEnabled(isCrashReportingEnabled)
UNUserNotificationCenter.current().delegate = self
let window = Window()
let navController = UINavigationController(rootViewController: LaunchController())
window.rootViewController = StatusBarViewController(ToastViewController(navController))
window.backgroundColor = UIColor.white
window.makeKeyAndVisible()
self.window = window
DependencyInjection.Container.shared.register(
PushRouter.live(navigationController: navController)
)
return true
}
public func application(application: UIApplication, shouldAllowExtensionPointIdentifier: String) -> Bool {
false
}
public func applicationDidEnterBackground(_ application: UIApplication) {
if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger,
let database = try? DependencyInjection.Container.shared.resolve() as Database,
let cMix = try? messenger.cMix.tryGet() {
let backgroundTask = application.beginBackgroundTask(withName: "xx.stop.network") {}
backgroundTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { timer in
print(">>> .backgroundTimeRemaining: \(UIApplication.shared.backgroundTimeRemaining)")
guard UIApplication.shared.backgroundTimeRemaining > 8 else {
if !self.calledStopNetwork {
self.calledStopNetwork = true
try! messenger.stop()
print(">>> Called stopNetworkFollower")
} else {
if cMix.hasRunningProcesses() == false {
application.endBackgroundTask(backgroundTask)
timer.invalidate()
}
}
return
guard UIApplication.shared.backgroundTimeRemaining > 9 else {
if !self.forceFailedPendingMessages {
self.forceFailedPendingMessages = true
let query = Message.Query(status: [.sending])
let assignment = Message.Assignments(status: .sendingFailed)
_ = try? database.bulkUpdateMessages(query, assignment)
}
}
public func applicationWillResignActive(_ application: UIApplication) {
if hideAppList {
coverView?.removeFromSuperview()
coverView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
coverView?.frame = window?.bounds ?? .zero
window?.addSubview(coverView!)
public func applicationWillTerminate(_ application: UIApplication) {
if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger {
try? messenger.stop()
public func applicationWillEnterForeground(_ application: UIApplication) {
if backgroundTimer != nil {
backgroundTimer?.invalidate()
backgroundTimer = nil
print(">>> Invalidated background timer")
}
if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger,
let cMix = messenger.cMix.get() {
guard self.calledStopNetwork == true else { return }
try? cMix.startNetworkFollower(timeoutMS: 10_000)
print(">>> Called startNetworkFollower")
self.calledStopNetwork = false
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
}
public func applicationDidBecomeActive(_ application: UIApplication) {
application.applicationIconBadgeNumber = 0
coverView?.removeFromSuperview()
}
public func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
dropboxService.handleOpenUrl(url)
}
public func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL,
let username = getUsernameFromInvitationDeepLink(incomingURL),
let router = try? DependencyInjection.Container.shared.resolve() as PushRouter else {
return false
}
router.navigateTo(.search(username: username), {})
return true
}
func getUsernameFromInvitationDeepLink(_ url: URL) -> String? {
if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
components.scheme == "https",
components.host == "elixxir.io",
components.path == "/connect",
let queryItem = components.queryItems?.first(where: { $0.name == "username" }),
let username = queryItem.value {
return username
}
return nil
// MARK: Notifications
extension AppDelegate: UNUserNotificationCenterDelegate {
public func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
pushHandler.handleAction(pushRouter, userInfo, completionHandler)
}
public func application(
_ application: UIApplication,
didReceiveRemoteNotification notification: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
) {
pushHandler.handlePush(notification, completionHandler)
}
public func application(
_: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
pushHandler.registerToken(deviceToken)
}