Files
letro-ios/NSE/Sources/NSEUserSession.swift
Stefan Ceriu 2c4a8b34a7 Bump the SDK to 25.05.21 and adopt the new way of dealing with timelines and delegates.
The room list items no longer hold any timeline instances and they can now be created through the normal `room.timelineWithConfiguration` mechanism.
This also means that we can move the UTD hook away from the sync service and into the client itself but setting it is now fallible as it can only be set once.
2025-05-22 18:14:55 +03:00

102 lines
4.2 KiB
Swift

//
// Copyright 2023, 2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
//
import Foundation
import MatrixRustSDK
final class NSEUserSession {
let sessionDirectories: SessionDirectories
private let baseClient: Client
private let notificationClient: NotificationClient
private let userID: String
private(set) lazy var mediaProvider: MediaProviderProtocol = MediaProvider(mediaLoader: MediaLoader(client: baseClient),
imageCache: .onlyOnDisk,
networkMonitor: nil)
private let delegateHandle: TaskHandle?
init(credentials: KeychainCredentials,
roomID: String,
clientSessionDelegate: ClientSessionDelegate,
appHooks: AppHooks,
appSettings: CommonSettingsProtocol) async throws {
sessionDirectories = credentials.restorationToken.sessionDirectories
userID = credentials.userID
if credentials.restorationToken.passphrase != nil {
MXLog.info("Restoring client with encrypted store.")
}
let homeserverURL = credentials.restorationToken.session.homeserverUrl
let clientBuilder = ClientBuilder
.baseBuilder(setupEncryption: false,
httpProxy: URL(string: homeserverURL)?.globalProxy,
slidingSync: .restored,
sessionDelegate: clientSessionDelegate,
appHooks: appHooks,
enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode,
requestTimeout: 15000,
maxRequestRetryTime: 5000)
.systemIsMemoryConstrained()
.sessionPaths(dataPath: credentials.restorationToken.sessionDirectories.dataPath,
cachePath: credentials.restorationToken.sessionDirectories.cachePath)
.username(username: credentials.userID)
.homeserverUrl(url: homeserverURL)
.sessionPassphrase(passphrase: credentials.restorationToken.passphrase)
baseClient = try await clientBuilder.build()
delegateHandle = try baseClient.setDelegate(delegate: ClientDelegateWrapper())
try await baseClient.restoreSessionWith(session: credentials.restorationToken.session,
roomLoadSettings: .one(roomId: roomID))
notificationClient = try await baseClient.notificationClient(processSetup: .multipleProcesses)
}
func notificationItemProxy(roomID: String, eventID: String) async -> NotificationItemProxyProtocol? {
do {
let notification = try await notificationClient.getNotification(roomId: roomID, eventId: eventID)
guard let notification else {
return nil
}
return NotificationItemProxy(notificationItem: notification,
eventID: eventID,
receiverID: userID,
roomID: roomID)
} catch {
MXLog.error("Could not get notification's content creating an empty notification instead, error: \(error)")
return EmptyNotificationItemProxy(eventID: eventID, roomID: roomID, receiverID: userID)
}
}
func roomForIdentifier(_ roomID: String) -> Room? {
do {
return try notificationClient.getRoom(roomId: roomID)
} catch {
MXLog.error("Failed retrieving room with error: \(error)")
return nil
}
}
deinit {
delegateHandle?.cancel()
}
}
private class ClientDelegateWrapper: ClientDelegate {
// MARK: - ClientDelegate
func didReceiveAuthError(isSoftLogout: Bool) {
MXLog.error("Received authentication error, the NSE can't handle this.")
}
func didRefreshTokens() {
MXLog.info("Delegating session updates to the ClientSessionDelegate.")
}
}