From 86c36f53e47f3a7856909c23710492e2ed70b5f9 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Thu, 10 Feb 2022 15:52:11 +0000 Subject: [PATCH] simplify and fix background loading (#288) * simplify and fix background loading * start receive loop in the main chat --- apps/ios/Shared/Model/BGManager.swift | 75 ++++++++++---------------- apps/ios/Shared/Model/SimpleXAPI.swift | 17 +----- apps/ios/Shared/SimpleXApp.swift | 3 -- 3 files changed, 31 insertions(+), 64 deletions(-) diff --git a/apps/ios/Shared/Model/BGManager.swift b/apps/ios/Shared/Model/BGManager.swift index 9365d42777..8b66fb6e67 100644 --- a/apps/ios/Shared/Model/BGManager.swift +++ b/apps/ios/Shared/Model/BGManager.swift @@ -14,22 +14,25 @@ private let receiveTaskId = "chat.simplex.app.receive" // TCP timeout + 2 sec private let waitForMessages: TimeInterval = 6 -class BGManager { - private var bgTimer: Timer? +private let bgRefreshInterval: TimeInterval = 450 +class BGManager { static let shared = BGManager() + var chatReceiver: ChatReceiver? + var bgTimer: Timer? + var completed = false func register() { logger.debug("BGManager.register") BGTaskScheduler.shared.register(forTaskWithIdentifier: receiveTaskId, using: nil) { task in - self.handleRefresh(RefreshTask(task as! BGAppRefreshTask)) + self.handleRefresh(task as! BGAppRefreshTask) } } func schedule() { logger.debug("BGManager.schedule") let request = BGAppRefreshTaskRequest(identifier: receiveTaskId) - request.earliestBeginDate = Date(timeIntervalSinceNow: 10 * 60) + request.earliestBeginDate = Date(timeIntervalSinceNow: bgRefreshInterval) do { try BGTaskScheduler.shared.submit(request) } catch { @@ -37,61 +40,41 @@ class BGManager { } } - private func handleRefresh(_ task: RefreshTask) { + private func handleRefresh(_ task: BGAppRefreshTask) { logger.debug("BGManager.handleRefresh") schedule() - task.expirationHandler = { - logger.debug("BGManager.handleRefresh expirationHandler") - ChatReceiver.shared.stop() - task.setTaskCompleted(success: true) + self.completed = false + + let completeTask: (String) -> Void = { reason in + logger.debug("BGManager.handleRefresh completeTask: \(reason)") + if !self.completed { + self.completed = true + self.chatReceiver?.stop() + self.chatReceiver = nil + self.bgTimer?.invalidate() + self.bgTimer = nil + task.setTaskCompleted(success: true) + } } + + task.expirationHandler = { completeTask("expirationHandler") } DispatchQueue.main.async { initializeChat() if ChatModel.shared.currentUser == nil { - task.setTaskCompleted(success: true) + completeTask("no current user") return } logger.debug("BGManager.handleRefresh: starting chat") - ChatReceiver.shared.start(bgTask: task) + let cr = ChatReceiver() + self.chatReceiver = cr + cr.start() RunLoop.current.add(Timer(timeInterval: 2, repeats: true) { timer in - self.bgTimer = timer logger.debug("BGManager.handleRefresh: timer") - if ChatReceiver.shared.lastMsgTime.distance(to: Date.now) >= waitForMessages { - logger.debug("BGManager.handleRefresh: timer: stopping") - ChatReceiver.shared.stop() - task.setTaskCompleted(success: true) - timer.invalidate() - self.bgTimer = nil + self.bgTimer = timer + if cr.lastMsgTime.distance(to: Date.now) >= waitForMessages { + completeTask("timer (no messages after \(waitForMessages) seconds)") } }, forMode: .default) } } - - func invalidateStopTimer() { - logger.debug("BGManager.invalidateStopTimer?") - if let timer = bgTimer { - timer.invalidate() - bgTimer = nil - logger.debug("BGManager.invalidateStopTimer: done") - } - } - - class RefreshTask { - private let task: BGAppRefreshTask - var completed = false - - internal init(_ task: BGAppRefreshTask) { - self.task = task - } - - var expirationHandler: (() -> Void)? { - set { task.expirationHandler = newValue } - get { task.expirationHandler } - } - - func setTaskCompleted(success: Bool) { - if !completed { task.setTaskCompleted(success: success) } - completed = true - } - } } diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 00d604ccbf..60daa0871f 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -345,19 +345,15 @@ func initializeChat() { class ChatReceiver { private var receiveLoop: DispatchWorkItem? private var receiveMessages = true - private var wasStarted = false - private var _canStop = false private var _lastMsgTime = Date.now static let shared = ChatReceiver() var lastMsgTime: Date { get { _lastMsgTime } } - func start(bgTask: BGManager.RefreshTask? = nil) { + func start() { logger.debug("ChatReceiver.start") - wasStarted = true receiveMessages = true - _canStop = true _lastMsgTime = .now if receiveLoop != nil { return } let loop = DispatchWorkItem(qos: .default, flags: []) { @@ -369,25 +365,16 @@ class ChatReceiver { logger.error("ChatReceiver.start chatRecvMsg error: \(error.localizedDescription)") } } - if let task = bgTask { task.setTaskCompleted(success: true) } } receiveLoop = loop DispatchQueue.global().async(execute: loop) } func stop() { - logger.debug("ChatReceiver.stop?") - if !_canStop { return } + logger.debug("ChatReceiver.stop") receiveMessages = false receiveLoop?.cancel() receiveLoop = nil - logger.debug("ChatReceiver.stop: done") - } - - func restart() { - logger.debug("ChatReceiver.restart?") - if wasStarted && receiveLoop == nil { start() } - _canStop = false } } diff --git a/apps/ios/Shared/SimpleXApp.swift b/apps/ios/Shared/SimpleXApp.swift index 0c46429ef4..2334c70e76 100644 --- a/apps/ios/Shared/SimpleXApp.swift +++ b/apps/ios/Shared/SimpleXApp.swift @@ -36,9 +36,6 @@ struct SimpleXApp: App { .onChange(of: scenePhase) { phase in if phase == .background { BGManager.shared.schedule() - } else { - BGManager.shared.invalidateStopTimer() - ChatReceiver.shared.restart() } } }