Add UserLocationServiceProvider that enables to automatically store UserLocationService per user id and retrieve existing UserLocationService.

This commit is contained in:
SBiOSoftWhare 2022-05-16 11:28:37 +02:00
parent 20a7ad9c6c
commit d7062bb154

View file

@ -0,0 +1,140 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
/// UserLocationServiceProvider enables to automatically store UserLocationService per user id and retrieve existing UserLocationService.
/// Note: UserLocationService management is not set inside UserSessionsService at the moment to avoid to expose user location management to extension targets.
class UserLocationServiceProvider {
// MARK: - Constants
static let shared = UserLocationServiceProvider()
// MARK: - Properties
private var locationServices: [String: UserLocationServiceProtocol] = [:]
// MARK: - Setup
private init() {
guard BuildSettings.liveLocationSharingEnabled else {
return
}
self.registerUserSessionsServiceNotifications()
}
// MARK: - Public
func locationService(for userId: String) -> UserLocationServiceProtocol? {
return self.locationServices[userId]
}
// MARK: - Private
// MARK: Store
private func addLocationService(_ userLocationService: UserLocationServiceProtocol, for userId: String) {
self.locationServices[userId] = userLocationService
}
private func removeLocationService(for userId: String) {
self.locationServices[userId] = nil
}
// MARK: UserLocationService setup
private func setupUserLocationService(for userSession: UserSession) {
self.tearDownUserLocationService(for: userSession.userId)
let userLocationService = UserLocationService(session: userSession.matrixSession)
self.addLocationService(userLocationService, for: userSession.userId)
userLocationService.start()
MXLog.debug("Start monitoring user live location sharing")
}
func setupUserLocationServiceIfNeeded(for userSession: UserSession) {
// Be sure Matrix session has is store setup to access beacon info summaries
guard userSession.matrixSession.state.rawValue >= MXSessionState.storeDataReady.rawValue else {
return
}
let locationService = self.locationService(for: userSession.userId)
guard locationService == nil else {
return
}
self.setupUserLocationService(for: userSession)
}
private func tearDownUserLocationService(for userId: String) {
guard let locationService = self.locationService(for: userId) else {
return
}
locationService.stop()
self.removeLocationService(for: userId)
MXLog.debug("Stop monitoring user live location sharing")
}
// MARK: UserSessions management
private func registerUserSessionsServiceNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(userSessionsServiceDidAddUserSession(_:)), name: UserSessionsService.didAddUserSession, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(userSessionsServiceDidUpdateUserSession(_:)), name: UserSessionsService.userSessionDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(userSessionsServiceDidRemoveUserSession(_:)), name: UserSessionsService.didRemoveUserSession, object: nil)
}
@objc private func userSessionsServiceDidAddUserSession(_ notification: Notification) {
guard let userInfo = notification.userInfo, let userSession = userInfo[UserSessionsService.NotificationUserInfoKey.userSession] as? UserSession else {
return
}
self.setupUserLocationServiceIfNeeded(for: userSession)
}
@objc private func userSessionsServiceDidUpdateUserSession(_ notification: Notification) {
guard let userInfo = notification.userInfo, let userSession = userInfo[UserSessionsService.NotificationUserInfoKey.userSession] as? UserSession else {
return
}
self.setupUserLocationServiceIfNeeded(for: userSession)
}
@objc private func userSessionsServiceDidRemoveUserSession(_ notification: Notification) {
guard let userInfo = notification.userInfo, let userId = userInfo[UserSessionsService.NotificationUserInfoKey.userId] as? String else {
return
}
self.tearDownUserLocationService(for: userId)
}
}