Merge pull request #4354 from vector-im/tabbarcoordinator_fix

TabBarCoordinator: Avoid to add Matrix session several times to MasterTabBarController
This commit is contained in:
SBiOSoftWhare 2021-05-28 16:45:28 +02:00 committed by GitHub
commit b4f8f4f5ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 32 deletions

View file

@ -31,6 +31,8 @@ class UserSession: NSObject, UserSessionProtocol {
// MARK: Public
let account: MXKAccount
// Keep strong reference to the MXSession because account.mxSession can become nil on logout or failure
let matrixSession: MXSession
var userId: String {
guard let userId = self.account.mxCredentials.userId else {
@ -39,14 +41,11 @@ class UserSession: NSObject, UserSessionProtocol {
return userId
}
var matrixSession: MXSession? {
return account.mxSession
}
// MARK: - Setup
init(account: MXKAccount) {
init(account: MXKAccount, matrixSession: MXSession) {
self.account = account
self.matrixSession = matrixSession
super.init()
}
}

View file

@ -84,21 +84,30 @@ class UserSessionsService: NSObject {
// MARK: - Private
private func addUserSession(fromAccount account: MXKAccount, postNotification: Bool) {
guard let userId = account.mxCredentials.userId, !self.isUserSessionExists(withUserId: userId) else {
return
@discardableResult
private func addUserSession(fromAccount account: MXKAccount, postNotification: Bool) -> Bool {
guard self.canAddAccount(account) else {
return false
}
let userSession = UserSession(account: account)
guard let matrixSession = account.mxSession else {
return false
}
let userSession = UserSession(account: account, matrixSession: matrixSession)
self.userSessions.append(userSession)
NSLog("[UserSessionsService] addUserSession from account with user id: \(userSession.userId)")
if postNotification {
NotificationCenter.default.post(name: UserSessionsService.didAddUserSession, object: self, userInfo: [NotificationUserInfoKey.userSession: userSession])
}
return true
}
private func removeUserSession(relatedToAccount account: MXKAccount, postNotification: Bool) {
guard let userId = account.mxCredentials.userId, !self.isUserSessionExists(withUserId: userId) else {
guard let userId = account.mxCredentials.userId, let userSession = self.userSession(withUserId: userId) else {
return
}
@ -110,11 +119,35 @@ class UserSessionsService: NSObject {
return userId == userSession.userId
}
NSLog("[UserSessionsService] removeUserSession related to account with user id: \(userId)")
if postNotification {
NotificationCenter.default.post(name: UserSessionsService.didRemoveUserSession, object: self, userInfo: [NotificationUserInfoKey.userId: userId])
}
}
private func canAddAccount(_ account: MXKAccount) -> Bool {
guard let userId = account.mxCredentials.userId, !self.isUserSessionExists(withUserId: userId) else {
return false
}
guard let mxSession = account.mxSession else {
NSLog("[UserSessionsService] Cannot add a UserSession from a MXKAccount with nil Matrix session")
return false
}
let isSessionStateValid: Bool
switch mxSession.state {
case MXSessionStateClosed, MXSessionStateUnknownToken:
isSessionStateValid = false
default:
isSessionStateValid = true
}
return isSessionStateValid
}
private func registerAccountNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(accountDidChange(_:)), name: .mxkAccountUserInfoDidChange, object: nil)
}
@ -124,7 +157,10 @@ class UserSessionsService: NSObject {
return
}
if let userSession = self.userSession(withUserId: userId) {
// Wait before MXKAccount.mxSession is set before adding a UserSession with the associated account
if let account = self.accountManager.account(forUserId: userId), self.canAddAccount(account) {
self.addUserSession(fromAccount: account)
} else if let userSession = self.userSession(withUserId: userId) {
NotificationCenter.default.post(name: UserSessionsService.userSessionDidChange, object: self, userInfo: [NotificationUserInfoKey.userSession: userSession])
}
}

View file

@ -47,7 +47,7 @@
@property (weak, nonatomic) id<MasterTabBarControllerDelegate> masterTabBarDelegate;
// Associated matrix sessions (empty by default).
@property (nonatomic, readonly) NSArray *mxSessions;
@property (nonatomic, readonly) NSArray<MXSession*> *mxSessions;
// Add a matrix session. This session is propagated to all view controllers handled by the tab bar controller.
- (void)addMatrixSession:(MXSession*)mxSession;

View file

@ -75,6 +75,11 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
self.masterTabBarController = masterTabBarController
self.navigationRouter.setRootModule(masterTabBarController)
// Add existing Matrix sessions if any
for userSession in self.parameters.userSessionsService.userSessions {
self.addMatrixSessionToMasterTabBarController(userSession.matrixSession)
}
self.registerUserSessionsServiceNotifications()
}
@ -212,9 +217,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
viewController.loadViewIfNeeded()
for userSession in self.parameters.userSessionsService.userSessions {
if let matrixSession = userSession.matrixSession {
viewController.addMatrixSession(matrixSession)
}
viewController.addMatrixSession(userSession.matrixSession)
}
return viewController
@ -268,8 +271,6 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
NotificationCenter.default.addObserver(self, selector: #selector(userSessionsServiceDidAddUserSession(_:)), name: UserSessionsService.didAddUserSession, object: userSessionService)
NotificationCenter.default.addObserver(self, selector: #selector(userSessionsServiceWillRemoveUserSession(_:)), name: UserSessionsService.willRemoveUserSession, object: userSessionService)
NotificationCenter.default.addObserver(self, selector: #selector(userSessionsServiceUserSessionDidChange(_:)), name: UserSessionsService.userSessionDidChange, object: userSessionService)
}
@objc private func userSessionsServiceDidAddUserSession(_ notification: Notification) {
@ -277,10 +278,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
return
}
// TODO: Remove Matrix session handling from the view controller
if let matrixSession = userSession.matrixSession {
self.masterTabBarController.addMatrixSession(matrixSession)
}
self.addMatrixSessionToMasterTabBarController(userSession.matrixSession)
}
@objc private func userSessionsServiceWillRemoveUserSession(_ notification: Notification) {
@ -288,22 +286,25 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
return
}
// TODO: Remove Matrix session handling from the view controller
if let matrixSession = userSession.matrixSession {
self.masterTabBarController.removeMatrixSession(matrixSession)
}
self.removeMatrixSessionFromMasterTabBarController(userSession.matrixSession)
}
@objc private func userSessionsServiceUserSessionDidChange(_ notification: Notification) {
guard let userSession = notification.userInfo?[UserSessionsService.NotificationUserInfoKey.userSession] as? UserSession else {
// TODO: Remove Matrix session handling from the view controller
private func addMatrixSessionToMasterTabBarController(_ matrixSession: MXSession) {
guard self.masterTabBarController.mxSessions.contains(matrixSession) == false else {
return
}
// TODO: Remove Matrix session handling from the view controller
// MXSession is opened before set to MXKAccount, wait for account change to be sure is set at a moment
if let matrixSession = userSession.matrixSession {
self.masterTabBarController.addMatrixSession(matrixSession)
NSLog("[TabBarCoordinator] masterTabBarController.addMatrixSession")
self.masterTabBarController.addMatrixSession(matrixSession)
}
// TODO: Remove Matrix session handling from the view controller
private func removeMatrixSessionFromMasterTabBarController(_ matrixSession: MXSession) {
guard self.masterTabBarController.mxSessions.contains(matrixSession) else {
return
}
NSLog("[TabBarCoordinator] masterTabBarController.removeMatrixSession")
self.masterTabBarController.removeMatrixSession(matrixSession)
}
}