Forráskód Böngészése

Merge pull request #1068 from deltachat/prevent_background_crash

Prevent background crash
bjoern 4 éve
szülő
commit
c8e4eb8155
1 módosított fájl, 58 hozzáadás és 17 törlés
  1. 58 17
      deltachat-ios/Chat/ChatViewController.swift

+ 58 - 17
deltachat-ios/Chat/ChatViewController.swift

@@ -18,6 +18,9 @@ class ChatViewController: UITableViewController {
     var incomingMsgObserver: Any?
     var ephemeralTimerModifiedObserver: Any?
     var dismissCancelled = false
+    var foregroundObserver: Any?
+    var backgroundObserver: Any?
+    var keyboardObserver: Any?
 
     lazy var isGroupChat: Bool = {
         return dcContext.getChat(chatId: chatId).isGroup
@@ -264,13 +267,6 @@ class ChatViewController: UITableViewController {
             editingBar.delegate = self
             tableView.allowsMultipleSelectionDuringEditing = true
         }
-
-        let notificationCenter = NotificationCenter.default
-        notificationCenter.addObserver(self,
-                                       selector: #selector(saveDraft),
-                                       name: UIApplication.willResignActiveNotification,
-                                       object: nil)
-        notificationCenter.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
     }
 
     @objc func keyboardWillShow(_ notification: Notification) {
@@ -286,19 +282,24 @@ class ChatViewController: UITableViewController {
     }
 
     private func startTimer() {
-        timer?.invalidate()
-        timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { [weak self] _ in
-            //reload table
-            DispatchQueue.main.async {
-                guard let self = self else { return }
-                self.messageIds = self.getMessageIds()
-                self.reloadData()
+        // check if the timer is not yet started
+        if !(timer?.isValid ?? false) {
+            timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { [weak self] _ in
+                //reload table
+                DispatchQueue.main.async {
+                    guard let self = self else { return }
+                    self.messageIds = self.getMessageIds()
+                    self.reloadData()
+                }
             }
         }
     }
 
     private func stopTimer() {
-        timer?.invalidate()
+        // check if the timer is not already stopped
+        if timer?.isValid ?? false {
+            timer?.invalidate()
+        }
     }
 
     private func configureEmptyStateView() {
@@ -382,6 +383,22 @@ class ChatViewController: UITableViewController {
             self.updateTitle(chat: self.dcContext.getChat(chatId: self.chatId))
         }
 
+        foregroundObserver = nc.addObserver(self,
+                                            selector: #selector(applicationDidBecomeActive(_:)),
+                                            name: UIApplication.didBecomeActiveNotification,
+                                            object: nil)
+
+        backgroundObserver = nc.addObserver(self,
+                                            selector: #selector(applicationWillResignActive(_:)),
+                                            name: UIApplication.willResignActiveNotification,
+                                            object: nil)
+
+        keyboardObserver = nc.addObserver(self,
+                                          selector: #selector(keyboardWillShow(_:)),
+                                          name: UIResponder.keyboardWillShowNotification,
+                                          object: nil)
+
+
         // things that do not affect the chatview
         // and are delayed after the view is displayed
         DispatchQueue.global(qos: .background).async { [weak self] in
@@ -403,7 +420,8 @@ class ChatViewController: UITableViewController {
         super.viewDidDisappear(animated)
         dismissCancelled = false
         AppStateRestorer.shared.resetLastActiveChat()
-        saveDraft()
+        draft.save(context: dcContext)
+        stopTimer()
         let nc = NotificationCenter.default
         if let msgChangedObserver = self.msgChangedObserver {
             nc.removeObserver(msgChangedObserver)
@@ -414,8 +432,17 @@ class ChatViewController: UITableViewController {
         if let ephemeralTimerModifiedObserver = self.ephemeralTimerModifiedObserver {
             nc.removeObserver(ephemeralTimerModifiedObserver)
         }
+        if let foregroundObserver = self.foregroundObserver {
+            nc.removeObserver(foregroundObserver)
+        }
+        if let backgroundObserver = self.backgroundObserver {
+            nc.removeObserver(backgroundObserver)
+        }
+        if let keyboardObserver = keyboardObserver {
+            nc.removeObserver(keyboardObserver)
+        }
         audioController.stopAnyOngoingPlaying()
-        stopTimer()
+
     }
 
     override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
@@ -444,6 +471,20 @@ class ChatViewController: UITableViewController {
         super.viewWillTransition(to: size, with: coordinator)
     }
 
+
+    @objc func applicationDidBecomeActive(_ notification: NSNotification) {
+        if navigationController?.visibleViewController == self {
+            startTimer()
+        }
+    }
+
+    @objc func applicationWillResignActive(_ notification: NSNotification) {
+        if navigationController?.visibleViewController == self {
+            stopTimer()
+            draft.save(context: dcContext)
+        }
+    }
+
     /// UITableView methods
 
     override func numberOfSections(in tableView: UITableView) -> Int {