diff --git a/Linphone/Core/CoreContext.swift b/Linphone/Core/CoreContext.swift index d7b838985..df718cd9e 100644 --- a/Linphone/Core/CoreContext.swift +++ b/Linphone/Core/CoreContext.swift @@ -166,9 +166,6 @@ final class CoreContext: ObservableObject { if cbVal.state == .Ok { self.loggingInProgress = false self.loggedIn = true - if self.mCore.consolidatedPresence != ConsolidatedPresence.Online { - self.onForeground() - } } else if cbVal.state == .Progress { self.loggingInProgress = true } else { @@ -195,8 +192,11 @@ final class CoreContext: ObservableObject { }) self.mCoreSuscriptions.insert(self.mCore.publisher?.onAccountRegistrationStateChanged?.postOnCoreQueue { (cbVal: (core: Core, account: Account, state: RegistrationState, message: String)) in - // If registration failed, remove account from core - if cbVal.state != .Ok && cbVal.state != .Progress { + if cbVal.state == .Ok { + if self.mCore.consolidatedPresence != ConsolidatedPresence.Online { + self.updatePresence(core: self.mCore, presence: ConsolidatedPresence.Online) + } + } else if cbVal.state != .Ok && cbVal.state != .Progress { // If registration failed, remove account from core let params = cbVal.account.params let clonedParams = params?.clone() clonedParams?.registerEnabled = false @@ -263,27 +263,35 @@ final class CoreContext: ObservableObject { try? self.mCore.start() } } - func onForeground() { - coreQueue.async { - // We can't rely on defaultAccount?.params?.isPublishEnabled - // as it will be modified by the SDK when changing the presence status - if self.mCore.config!.getBool(section: "app", key: "publish_presence", defaultValue: true) { - Log.info("App is in foreground, PUBLISHING presence as Online") - self.mCore.consolidatedPresence = ConsolidatedPresence.Online - } + + func updatePresence(core : Core, presence : ConsolidatedPresence) { + if core.config!.getBool(section: "app", key: "publish_presence", defaultValue: true) { + core.consolidatedPresence = presence } } - func onBackground() { + func onEnterForeground() { coreQueue.async { // We can't rely on defaultAccount?.params?.isPublishEnabled // as it will be modified by the SDK when changing the presence status - if self.mCore.config!.getBool(section: "app", key: "publish_presence", defaultValue: true) { - Log.info("App is in background, un-PUBLISHING presence info") - // We don't use ConsolidatedPresence.Busy but Offline to do an unsubscribe, - // Flexisip will handle the Busy status depending on other devices - self.mCore.consolidatedPresence = ConsolidatedPresence.Offline - } + + Log.info("App is in foreground, PUBLISHING presence as Online") + self.updatePresence(core: self.mCore, presence: ConsolidatedPresence.Online) + try? self.mCore.start() + } + } + + func onEnterBackground() { + coreQueue.async { + // We can't rely on defaultAccount?.params?.isPublishEnabled + // as it will be modified by the SDK when changing the presence status + Log.info("App is in background, un-PUBLISHING presence info") + + // We don't use ConsolidatedPresence.Busy but Offline to do an unsubscribe, + // Flexisip will handle the Busy status depending on other devices + self.updatePresence(core: self.mCore, presence: ConsolidatedPresence.Offline) + // self.mCore.iterate() + self.mCore.stop() } } diff --git a/Linphone/LinphoneApp.swift b/Linphone/LinphoneApp.swift index dd68f6b7b..dcc46dea3 100644 --- a/Linphone/LinphoneApp.swift +++ b/Linphone/LinphoneApp.swift @@ -23,11 +23,6 @@ import linphonesw let accountTokenNotification = Notification.Name("AccountCreationTokenReceived") class AppDelegate: NSObject, UIApplicationDelegate { - func application(_ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { - - return true - } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let tokenStr = deviceToken.map { String(format: "%02.2hhx", $0) }.joined() @@ -43,7 +38,7 @@ class AppDelegate: NSObject, UIApplicationDelegate { } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { - Log.info("debugtrace -- Received background push notification, payload = \(userInfo.description)") + Log.info("Received background push notification, payload = \(userInfo.description)") let creationToken = (userInfo["customPayload"] as? NSDictionary)?["token"] as? String if let creationToken = creationToken { @@ -53,24 +48,14 @@ class AppDelegate: NSObject, UIApplicationDelegate { } func applicationWillTerminate(_ application: UIApplication) { - Log.info("debugtrace -- applicationWillTerminate") - CoreContext.shared.doOnCoreQueue { core in - Log.info("debugtrace COREQUEUE -- applicationWillTerminate") - core.stop() - } - } - - func applicationWillResignActive(_ application: UIApplication) { - Log.info("debugtrace -- applicationWillResignActive") - CoreContext.shared.doOnCoreQueue { core in - Log.info("debugtrace COREQUEUE -- applicationWillResignActive") - if let userDefaults = UserDefaults(suiteName: Config.appGroupName) { - userDefaults.set(false, forKey: "appactive") - } - try? Config.get().sync() - core.enterBackground() - if core.callsNb == 0 { + Log.info("IOS applicationWillTerminate") + CoreContext.shared.doOnCoreQueue(synchronous: true) { core in + Log.info("applicationWillTerminate - Stopping linphone core") + MagicSearchSingleton.shared.destroyMagicSearch() + if core.globalState != GlobalState.Off { core.stop() + } else { + Log.info("applicationWillTerminate - Core already stopped") } } } @@ -80,6 +65,7 @@ class AppDelegate: NSObject, UIApplicationDelegate { @main struct LinphoneApp: App { + @Environment(\.scenePhase) var scenePhase @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate @ObservedObject private var coreContext = CoreContext.shared @ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared @@ -133,6 +119,15 @@ struct LinphoneApp: App { callViewModel = CallViewModel() } } + }.onChange(of: scenePhase) { newPhase in + if newPhase == .active { + Log.info("Entering foreground") + coreContext.onEnterForeground() + } else if newPhase == .inactive { + } else if newPhase == .background { + Log.info("Entering background") + coreContext.onEnterBackground() + } } } } diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index aef8efb45..33529d2b3 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -710,25 +710,6 @@ struct ContentView: View { } orientation = newOrientation } - .onChange(of: scenePhase) { newPhase in - if newPhase == .active { - coreContext.onForeground() - /* - if !isShowStartCallFragment { - contactsManager.fetchContacts() - DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) { - historyListViewModel.computeCallLogsList() - } - } - */ - print("Active") - } else if newPhase == .inactive { - print("Inactive") - } else if newPhase == .background { - coreContext.onBackground() - print("Background") - } - } } func openMenu() { diff --git a/Linphone/Utils/MagicSearchSingleton.swift b/Linphone/Utils/MagicSearchSingleton.swift index b65c09bf5..3593e26a2 100644 --- a/Linphone/Utils/MagicSearchSingleton.swift +++ b/Linphone/Utils/MagicSearchSingleton.swift @@ -43,6 +43,10 @@ final class MagicSearchSingleton: ObservableObject { var searchSubscription: AnyCancellable? + func destroyMagicSearch() { + magicSearch = nil + } + private init() { coreContext.doOnCoreQueue { core in self.domainDefaultAccount = core.defaultAccount?.params?.domain ?? ""