|
@@ -11,7 +11,7 @@ let logger = SwiftyBeaver.self
|
|
|
|
|
|
@UIApplicationMain
|
|
|
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
|
|
|
- private let dcContext = DcContext()
|
|
|
+ private let dcAccounts = DcAccounts()
|
|
|
var appCoordinator: AppCoordinator!
|
|
|
var relayHelper: RelayHelper!
|
|
|
var locationManager: LocationManager!
|
|
@@ -55,7 +55,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
let console = ConsoleDestination()
|
|
|
console.format = "$DHH:mm:ss.SSS$d $C$L$c $M" // see https://docs.swiftybeaver.com/article/20-custom-format
|
|
|
logger.addDestination(console)
|
|
|
- dcContext.logger = DcLogger()
|
|
|
+
|
|
|
+ dcAccounts.openDatabase()
|
|
|
+ migrateToDcAccounts()
|
|
|
+ if dcAccounts.getAll().isEmpty, dcAccounts.add() == 0 {
|
|
|
+ fatalError("Could not initialize a new account.")
|
|
|
+ }
|
|
|
+ dcAccounts.getSelected().logger = DcLogger()
|
|
|
logger.info("➡️ didFinishLaunchingWithOptions")
|
|
|
|
|
|
window = UIWindow(frame: UIScreen.main.bounds)
|
|
@@ -68,14 +74,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
window.backgroundColor = UIColor.white
|
|
|
}
|
|
|
|
|
|
- openDatabase()
|
|
|
installEventHandler()
|
|
|
- RelayHelper.setup(dcContext)
|
|
|
- appCoordinator = AppCoordinator(window: window, dcContext: dcContext)
|
|
|
- locationManager = LocationManager(context: dcContext)
|
|
|
+ relayHelper = RelayHelper.setup(dcAccounts.getSelected())
|
|
|
+ appCoordinator = AppCoordinator(window: window, dcAccounts: dcAccounts)
|
|
|
+ locationManager = LocationManager(dcAccounts: dcAccounts)
|
|
|
UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)
|
|
|
- notificationManager = NotificationManager(dcContext: dcContext)
|
|
|
- dcContext.maybeStartIo()
|
|
|
+ notificationManager = NotificationManager(dcAccounts: dcAccounts)
|
|
|
+ dcAccounts.maybeStartIo()
|
|
|
setStockTranslations()
|
|
|
|
|
|
reachability.whenReachable = { reachability in
|
|
@@ -83,7 +88,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
// Reachability::reachabilityChanged uses DispatchQueue.main.async only
|
|
|
logger.info("network: reachable", reachability.connection.description)
|
|
|
DispatchQueue.global(qos: .background).async { [weak self] in
|
|
|
- self?.dcContext.maybeNetwork()
|
|
|
+ self?.dcAccounts.maybeNetwork()
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -102,7 +107,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
increaseDebugCounter("notify-remote-launch")
|
|
|
}
|
|
|
|
|
|
- if dcContext.isConfigured() && !UserDefaults.standard.bool(forKey: "notifications_disabled") {
|
|
|
+ if dcAccounts.getSelected().isConfigured() && !UserDefaults.standard.bool(forKey: "notifications_disabled") {
|
|
|
registerForNotifications()
|
|
|
}
|
|
|
|
|
@@ -138,12 +143,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
|
|
|
func applicationWillEnterForeground(_: UIApplication) {
|
|
|
logger.info("➡️ applicationWillEnterForeground")
|
|
|
- dcContext.maybeStartIo()
|
|
|
+ dcAccounts.maybeStartIo()
|
|
|
|
|
|
DispatchQueue.global(qos: .background).async { [weak self] in
|
|
|
guard let self = self else { return }
|
|
|
if self.reachability.connection != .none {
|
|
|
- self.dcContext.maybeNetwork()
|
|
|
+ self.dcAccounts.maybeNetwork()
|
|
|
}
|
|
|
|
|
|
if let userDefaults = UserDefaults.shared, userDefaults.bool(forKey: UserDefaults.hasExtensionAttemptedToSend) {
|
|
@@ -170,7 +175,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
|
|
|
func applicationWillTerminate(_: UIApplication) {
|
|
|
logger.info("⬅️ applicationWillTerminate")
|
|
|
- closeDatabase()
|
|
|
+ dcAccounts.closeDatabase()
|
|
|
reachability.stopNotifier()
|
|
|
}
|
|
|
|
|
@@ -206,7 +211,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
self.unregisterBackgroundTask()
|
|
|
} else if app.backgroundTimeRemaining < 10 {
|
|
|
logger.info("⬅️ few background time, \(app.backgroundTimeRemaining), stopping")
|
|
|
- self.dcContext.stopIo()
|
|
|
+ self.dcAccounts.stopIo()
|
|
|
|
|
|
// to avoid 0xdead10cc exceptions, scheduled jobs need to be done before we get suspended;
|
|
|
// we increase the probabilty that this happens by waiting a moment before calling unregisterBackgroundTask()
|
|
@@ -381,7 +386,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
|
|
|
// usually, this handler is not used as we are taking care of timings below.
|
|
|
logger.info("⬅️ finishing fetch by system urgency requests")
|
|
|
- self?.dcContext.stopIo()
|
|
|
+ self?.dcAccounts.stopIo()
|
|
|
completionHandler(.newData)
|
|
|
if backgroundTask != .invalid {
|
|
|
UIApplication.shared.endBackgroundTask(backgroundTask)
|
|
@@ -390,8 +395,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
}
|
|
|
|
|
|
// we're in background, run IO for a little time
|
|
|
- dcContext.maybeStartIo()
|
|
|
- dcContext.maybeNetwork()
|
|
|
+ dcAccounts.maybeStartIo()
|
|
|
+ dcAccounts.maybeNetwork()
|
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in
|
|
|
logger.info("⬅️ finishing fetch")
|
|
@@ -401,7 +406,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
return
|
|
|
}
|
|
|
if !self.appIsInForeground() {
|
|
|
- self.dcContext.stopIo()
|
|
|
+ self.dcAccounts.stopIo()
|
|
|
}
|
|
|
|
|
|
// to avoid 0xdead10cc exceptions, scheduled jobs need to be done before we get suspended;
|
|
@@ -445,24 +450,37 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
|
|
|
// MARK: - misc.
|
|
|
|
|
|
- func openDatabase() {
|
|
|
- guard let databaseLocation = DatabaseHelper(dcContext: dcContext).updateDatabaseLocation() else {
|
|
|
- fatalError("Database could not be opened")
|
|
|
+ func migrateToDcAccounts() {
|
|
|
+ let dbHelper = DatabaseHelper()
|
|
|
+ if let databaseLocation = dbHelper.unmanagedDatabaseLocation,
|
|
|
+ dcAccounts.migrate(dbLocation: databaseLocation) == 0 {
|
|
|
+ fatalError("Account could not be migrated")
|
|
|
+ // TODO: show error message in UI
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func reloadDcContext() {
|
|
|
+ locationManager.reloadDcContext()
|
|
|
+ notificationManager.reloadDcContext()
|
|
|
+ RelayHelper.sharedInstance.cancel()
|
|
|
+ _ = RelayHelper.setup(dcAccounts.getSelected())
|
|
|
+ if dcAccounts.getSelected().isConfigured() {
|
|
|
+ appCoordinator.resetTabBarRootViewControllers()
|
|
|
+ } else {
|
|
|
+ appCoordinator.presentWelcomeController()
|
|
|
}
|
|
|
- logger.info("open: \(databaseLocation)")
|
|
|
- dcContext.openDatabase(dbFile: databaseLocation)
|
|
|
}
|
|
|
|
|
|
- func closeDatabase() {
|
|
|
- dcContext.closeDatabase()
|
|
|
+ func deleteCurrentAccount() {
|
|
|
+ _ = dcAccounts.remove(id: dcAccounts.getSelected().id)
|
|
|
}
|
|
|
|
|
|
func installEventHandler() {
|
|
|
|
|
|
DispatchQueue.global(qos: .background).async { [weak self] in
|
|
|
guard let self = self else { return }
|
|
|
- let eventHandler = DcEventHandler(dcContext: self.dcContext)
|
|
|
- let eventEmitter = self.dcContext.getEventEmitter()
|
|
|
+ let eventHandler = DcEventHandler(dcAccounts: self.dcAccounts)
|
|
|
+ let eventEmitter = self.dcAccounts.getEventEmitter()
|
|
|
while true {
|
|
|
guard let event = eventEmitter.getNextEvent() else { break }
|
|
|
eventHandler.handleEvent(event: event)
|
|
@@ -488,6 +506,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|
|
}
|
|
|
|
|
|
private func setStockTranslations() {
|
|
|
+ let dcContext = dcAccounts.getSelected()
|
|
|
dcContext.setStockTranslation(id: DC_STR_NOMESSAGES, localizationKey: "chat_no_messages")
|
|
|
dcContext.setStockTranslation(id: DC_STR_SELF, localizationKey: "self")
|
|
|
dcContext.setStockTranslation(id: DC_STR_DRAFT, localizationKey: "draft")
|