diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 2f52b6230..652062df5 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -7336,7 +7336,7 @@ repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift"; requirement = { kind = exactVersion; - version = 1.1.63; + version = 1.1.64; }; }; 821C67C9A7F8CC3FD41B28B4 /* XCRemoteSwiftPackageReference "emojibase-bindings" */ = { diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index a1c23e2f6..6a230d25b 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -139,8 +139,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/matrix-org/matrix-rust-components-swift", "state" : { - "revision" : "3d116223646fc7310b977e5116f96b834a9f57f6", - "version" : "1.1.63" + "revision" : "f1ea6a13202bb309d737f9f4f49a0ee94242126b", + "version" : "1.1.64" } }, { diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index 40e254da1..f8ffb82e7 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -1136,7 +1136,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } private func forward(eventID: String, toRoomID roomID: String) async { - guard let messageEventContent = roomProxy.timeline.messageEventContent(for: eventID) else { + guard let messageEventContent = await roomProxy.timeline.messageEventContent(for: eventID) else { MXLog.error("Failed retrieving forwarded message event content for eventID: \(eventID)") userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown)) return diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 55eca9031..ed4395194 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -10960,14 +10960,14 @@ class TimelineProxyMock: TimelineProxyProtocol { } } } - var messageEventContentForClosure: ((String) -> RoomMessageEventContentWithoutRelation?)? + var messageEventContentForClosure: ((String) async -> RoomMessageEventContentWithoutRelation?)? - func messageEventContent(for eventID: String) -> RoomMessageEventContentWithoutRelation? { + func messageEventContent(for eventID: String) async -> RoomMessageEventContentWithoutRelation? { messageEventContentForCallsCount += 1 messageEventContentForReceivedEventID = eventID messageEventContentForReceivedInvocations.append(eventID) if let messageEventContentForClosure = messageEventContentForClosure { - return messageEventContentForClosure(eventID) + return await messageEventContentForClosure(eventID) } else { return messageEventContentForReturnValue } diff --git a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift index b33b58eba..6e508301a 100644 --- a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift @@ -1,4 +1,4 @@ -// Generated using Sourcery 2.2.2 — https://github.com/krzysztofzablocki/Sourcery +// Generated using Sourcery 2.2.4 — https://github.com/krzysztofzablocki/Sourcery // DO NOT EDIT // swiftlint:disable all @@ -63,9 +63,9 @@ class SDKClientMock: SDKClientProtocol { } } } - public var accountDataEventTypeClosure: ((String) throws -> String?)? + public var accountDataEventTypeClosure: ((String) async throws -> String?)? - public func accountData(eventType: String) throws -> String? { + public func accountData(eventType: String) async throws -> String? { if let error = accountDataEventTypeThrowableError { throw error } @@ -73,7 +73,7 @@ class SDKClientMock: SDKClientProtocol { accountDataEventTypeReceivedEventType = eventType accountDataEventTypeReceivedInvocations.append(eventType) if let accountDataEventTypeClosure = accountDataEventTypeClosure { - return try accountDataEventTypeClosure(eventType) + return try await accountDataEventTypeClosure(eventType) } else { return accountDataEventTypeReturnValue } @@ -205,15 +205,15 @@ class SDKClientMock: SDKClientProtocol { } } } - public var avatarUrlClosure: (() throws -> String?)? + public var avatarUrlClosure: (() async throws -> String?)? - public func avatarUrl() throws -> String? { + public func avatarUrl() async throws -> String? { if let error = avatarUrlThrowableError { throw error } avatarUrlCallsCount += 1 if let avatarUrlClosure = avatarUrlClosure { - return try avatarUrlClosure() + return try await avatarUrlClosure() } else { return avatarUrlReturnValue } @@ -343,9 +343,9 @@ class SDKClientMock: SDKClientProtocol { } } } - public var createRoomRequestClosure: ((CreateRoomParameters) throws -> String)? + public var createRoomRequestClosure: ((CreateRoomParameters) async throws -> String)? - public func createRoom(request: CreateRoomParameters) throws -> String { + public func createRoom(request: CreateRoomParameters) async throws -> String { if let error = createRoomRequestThrowableError { throw error } @@ -353,7 +353,7 @@ class SDKClientMock: SDKClientProtocol { createRoomRequestReceivedRequest = request createRoomRequestReceivedInvocations.append(request) if let createRoomRequestClosure = createRoomRequestClosure { - return try createRoomRequestClosure(request) + return try await createRoomRequestClosure(request) } else { return createRoomRequestReturnValue } @@ -524,15 +524,15 @@ class SDKClientMock: SDKClientProtocol { } } } - public var displayNameClosure: (() throws -> String)? + public var displayNameClosure: (() async throws -> String)? - public func displayName() throws -> String { + public func displayName() async throws -> String { if let error = displayNameThrowableError { throw error } displayNameCallsCount += 1 if let displayNameClosure = displayNameClosure { - return try displayNameClosure() + return try await displayNameClosure() } else { return displayNameReturnValue } @@ -1010,9 +1010,9 @@ class SDKClientMock: SDKClientProtocol { } } } - public var getProfileUserIdClosure: ((String) throws -> UserProfile)? + public var getProfileUserIdClosure: ((String) async throws -> UserProfile)? - public func getProfile(userId: String) throws -> UserProfile { + public func getProfile(userId: String) async throws -> UserProfile { if let error = getProfileUserIdThrowableError { throw error } @@ -1020,7 +1020,7 @@ class SDKClientMock: SDKClientProtocol { getProfileUserIdReceivedUserId = userId getProfileUserIdReceivedInvocations.append(userId) if let getProfileUserIdClosure = getProfileUserIdClosure { - return try getProfileUserIdClosure(userId) + return try await getProfileUserIdClosure(userId) } else { return getProfileUserIdReturnValue } @@ -1220,15 +1220,15 @@ class SDKClientMock: SDKClientProtocol { } } } - public var getSessionVerificationControllerClosure: (() throws -> SessionVerificationController)? + public var getSessionVerificationControllerClosure: (() async throws -> SessionVerificationController)? - public func getSessionVerificationController() throws -> SessionVerificationController { + public func getSessionVerificationController() async throws -> SessionVerificationController { if let error = getSessionVerificationControllerThrowableError { throw error } getSessionVerificationControllerCallsCount += 1 if let getSessionVerificationControllerClosure = getSessionVerificationControllerClosure { - return try getSessionVerificationControllerClosure() + return try await getSessionVerificationControllerClosure() } else { return getSessionVerificationControllerReturnValue } @@ -1578,15 +1578,15 @@ class SDKClientMock: SDKClientProtocol { } } } - public var logoutClosure: (() throws -> String?)? + public var logoutClosure: (() async throws -> String?)? - public func logout() throws -> String? { + public func logout() async throws -> String? { if let error = logoutThrowableError { throw error } logoutCallsCount += 1 if let logoutClosure = logoutClosure { - return try logoutClosure() + return try await logoutClosure() } else { return logoutReturnValue } @@ -1624,13 +1624,13 @@ class SDKClientMock: SDKClientProtocol { public var notificationClientProcessSetupReceivedProcessSetup: NotificationProcessSetup? public var notificationClientProcessSetupReceivedInvocations: [NotificationProcessSetup] = [] - var notificationClientProcessSetupUnderlyingReturnValue: NotificationClientBuilder! - public var notificationClientProcessSetupReturnValue: NotificationClientBuilder! { + var notificationClientProcessSetupUnderlyingReturnValue: NotificationClient! + public var notificationClientProcessSetupReturnValue: NotificationClient! { get { if Thread.isMainThread { return notificationClientProcessSetupUnderlyingReturnValue } else { - var returnValue: NotificationClientBuilder? = nil + var returnValue: NotificationClient? = nil DispatchQueue.main.sync { returnValue = notificationClientProcessSetupUnderlyingReturnValue } @@ -1648,9 +1648,9 @@ class SDKClientMock: SDKClientProtocol { } } } - public var notificationClientProcessSetupClosure: ((NotificationProcessSetup) throws -> NotificationClientBuilder)? + public var notificationClientProcessSetupClosure: ((NotificationProcessSetup) async throws -> NotificationClient)? - public func notificationClient(processSetup: NotificationProcessSetup) throws -> NotificationClientBuilder { + public func notificationClient(processSetup: NotificationProcessSetup) async throws -> NotificationClient { if let error = notificationClientProcessSetupThrowableError { throw error } @@ -1658,7 +1658,7 @@ class SDKClientMock: SDKClientProtocol { notificationClientProcessSetupReceivedProcessSetup = processSetup notificationClientProcessSetupReceivedInvocations.append(processSetup) if let notificationClientProcessSetupClosure = notificationClientProcessSetupClosure { - return try notificationClientProcessSetupClosure(processSetup) + return try await notificationClientProcessSetupClosure(processSetup) } else { return notificationClientProcessSetupReturnValue } @@ -1693,14 +1693,14 @@ class SDKClientMock: SDKClientProtocol { public var removeAvatarCalled: Bool { return removeAvatarCallsCount > 0 } - public var removeAvatarClosure: (() throws -> Void)? + public var removeAvatarClosure: (() async throws -> Void)? - public func removeAvatar() throws { + public func removeAvatar() async throws { if let error = removeAvatarThrowableError { throw error } removeAvatarCallsCount += 1 - try removeAvatarClosure?() + try await removeAvatarClosure?() } //MARK: - resolveRoomAlias @@ -1806,16 +1806,16 @@ class SDKClientMock: SDKClientProtocol { } public var restoreSessionSessionReceivedSession: Session? public var restoreSessionSessionReceivedInvocations: [Session] = [] - public var restoreSessionSessionClosure: ((Session) throws -> Void)? + public var restoreSessionSessionClosure: ((Session) async throws -> Void)? - public func restoreSession(session: Session) throws { + public func restoreSession(session: Session) async throws { if let error = restoreSessionSessionThrowableError { throw error } restoreSessionSessionCallsCount += 1 restoreSessionSessionReceivedSession = session restoreSessionSessionReceivedInvocations.append(session) - try restoreSessionSessionClosure?(session) + try await restoreSessionSessionClosure?(session) } //MARK: - roomDirectorySearch @@ -2002,9 +2002,9 @@ class SDKClientMock: SDKClientProtocol { } } } - public var searchUsersSearchTermLimitClosure: ((String, UInt64) throws -> SearchUsersResults)? + public var searchUsersSearchTermLimitClosure: ((String, UInt64) async throws -> SearchUsersResults)? - public func searchUsers(searchTerm: String, limit: UInt64) throws -> SearchUsersResults { + public func searchUsers(searchTerm: String, limit: UInt64) async throws -> SearchUsersResults { if let error = searchUsersSearchTermLimitThrowableError { throw error } @@ -2012,7 +2012,7 @@ class SDKClientMock: SDKClientProtocol { searchUsersSearchTermLimitReceivedArguments = (searchTerm: searchTerm, limit: limit) searchUsersSearchTermLimitReceivedInvocations.append((searchTerm: searchTerm, limit: limit)) if let searchUsersSearchTermLimitClosure = searchUsersSearchTermLimitClosure { - return try searchUsersSearchTermLimitClosure(searchTerm, limit) + return try await searchUsersSearchTermLimitClosure(searchTerm, limit) } else { return searchUsersSearchTermLimitReturnValue } @@ -2072,15 +2072,15 @@ class SDKClientMock: SDKClientProtocol { } } } - public var sessionClosure: (() throws -> Session)? + public var sessionClosure: (() async throws -> Session)? - public func session() throws -> Session { + public func session() async throws -> Session { if let error = sessionThrowableError { throw error } sessionCallsCount += 1 if let sessionClosure = sessionClosure { - return try sessionClosure() + return try await sessionClosure() } else { return sessionReturnValue } @@ -2117,16 +2117,16 @@ class SDKClientMock: SDKClientProtocol { } public var setAccountDataEventTypeContentReceivedArguments: (eventType: String, content: String)? public var setAccountDataEventTypeContentReceivedInvocations: [(eventType: String, content: String)] = [] - public var setAccountDataEventTypeContentClosure: ((String, String) throws -> Void)? + public var setAccountDataEventTypeContentClosure: ((String, String) async throws -> Void)? - public func setAccountData(eventType: String, content: String) throws { + public func setAccountData(eventType: String, content: String) async throws { if let error = setAccountDataEventTypeContentThrowableError { throw error } setAccountDataEventTypeContentCallsCount += 1 setAccountDataEventTypeContentReceivedArguments = (eventType: eventType, content: content) setAccountDataEventTypeContentReceivedInvocations.append((eventType: eventType, content: content)) - try setAccountDataEventTypeContentClosure?(eventType, content) + try await setAccountDataEventTypeContentClosure?(eventType, content) } //MARK: - setDelegate @@ -2228,16 +2228,16 @@ class SDKClientMock: SDKClientProtocol { } public var setDisplayNameNameReceivedName: String? public var setDisplayNameNameReceivedInvocations: [String] = [] - public var setDisplayNameNameClosure: ((String) throws -> Void)? + public var setDisplayNameNameClosure: ((String) async throws -> Void)? - public func setDisplayName(name: String) throws { + public func setDisplayName(name: String) async throws { if let error = setDisplayNameNameThrowableError { throw error } setDisplayNameNameCallsCount += 1 setDisplayNameNameReceivedName = name setDisplayNameNameReceivedInvocations.append(name) - try setDisplayNameNameClosure?(name) + try await setDisplayNameNameClosure?(name) } //MARK: - setPusher @@ -2532,16 +2532,16 @@ class SDKClientMock: SDKClientProtocol { } public var uploadAvatarMimeTypeDataReceivedArguments: (mimeType: String, data: Data)? public var uploadAvatarMimeTypeDataReceivedInvocations: [(mimeType: String, data: Data)] = [] - public var uploadAvatarMimeTypeDataClosure: ((String, Data) throws -> Void)? + public var uploadAvatarMimeTypeDataClosure: ((String, Data) async throws -> Void)? - public func uploadAvatar(mimeType: String, data: Data) throws { + public func uploadAvatar(mimeType: String, data: Data) async throws { if let error = uploadAvatarMimeTypeDataThrowableError { throw error } uploadAvatarMimeTypeDataCallsCount += 1 uploadAvatarMimeTypeDataReceivedArguments = (mimeType: mimeType, data: data) uploadAvatarMimeTypeDataReceivedInvocations.append((mimeType: mimeType, data: data)) - try uploadAvatarMimeTypeDataClosure?(mimeType, data) + try await uploadAvatarMimeTypeDataClosure?(mimeType, data) } //MARK: - uploadMedia diff --git a/ElementX/Sources/Services/Authentication/AuthenticationServiceProxy.swift b/ElementX/Sources/Services/Authentication/AuthenticationServiceProxy.swift index d661b998e..37b38752a 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationServiceProxy.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationServiceProxy.swift @@ -114,15 +114,11 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol { initialDeviceName: initialDeviceName, deviceId: deviceID) - let refreshToken = try? await Task.dispatch(on: .global()) { - try client.session().refreshToken - } + let refreshToken = try? await client.session().refreshToken if refreshToken != nil { MXLog.warning("Refresh token found for a non oidc session, can't restore session, logging out") - _ = await Task.dispatch(on: .global()) { - try? client.logout() - } + _ = try? await client.logout() return .failure(.sessionTokenRefreshNotSupported) } diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index c9feef911..37a1215bb 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -315,49 +315,41 @@ class ClientProxy: ClientProxyProtocol { } func createDirectRoom(with userID: String, expectedRoomName: String?) async -> Result { - let result: Result = await Task.dispatch(on: clientQueue) { - do { - let parameters = CreateRoomParameters(name: nil, - topic: nil, - isEncrypted: true, - isDirect: true, - visibility: .private, - preset: .trustedPrivateChat, - invite: [userID], - avatar: nil, - powerLevelContentOverride: Self.roomCreationPowerLevelOverrides) - let result = try self.client.createRoom(request: parameters) - return .success(result) - } catch { - MXLog.error("Failed creating direct room for userID: \(userID) with error: \(error)") - return .failure(.sdkError(error)) - } + do { + let parameters = CreateRoomParameters(name: nil, + topic: nil, + isEncrypted: true, + isDirect: true, + visibility: .private, + preset: .trustedPrivateChat, + invite: [userID], + avatar: nil, + powerLevelContentOverride: Self.roomCreationPowerLevelOverrides) + let result = try await client.createRoom(request: parameters) + return await waitForRoomSummary(with: .success(result), name: expectedRoomName) + } catch { + MXLog.error("Failed creating direct room for userID: \(userID) with error: \(error)") + return .failure(.sdkError(error)) } - - return await waitForRoomSummary(with: result, name: expectedRoomName) } func createRoom(name: String, topic: String?, isRoomPrivate: Bool, userIDs: [String], avatarURL: URL?) async -> Result { - let result: Result = await Task.dispatch(on: clientQueue) { - do { - let parameters = CreateRoomParameters(name: name, - topic: topic, - isEncrypted: isRoomPrivate, - isDirect: false, - visibility: isRoomPrivate ? .private : .public, - preset: isRoomPrivate ? .privateChat : .publicChat, - invite: userIDs, - avatar: avatarURL?.absoluteString, - powerLevelContentOverride: Self.roomCreationPowerLevelOverrides) - let roomID = try self.client.createRoom(request: parameters) - return .success(roomID) - } catch { - MXLog.error("Failed creating room with error: \(error)") - return .failure(.sdkError(error)) - } + do { + let parameters = CreateRoomParameters(name: name, + topic: topic, + isEncrypted: isRoomPrivate, + isDirect: false, + visibility: isRoomPrivate ? .private : .public, + preset: isRoomPrivate ? .privateChat : .publicChat, + invite: userIDs, + avatar: avatarURL?.absoluteString, + powerLevelContentOverride: Self.roomCreationPowerLevelOverrides) + let roomID = try await client.createRoom(request: parameters) + return await waitForRoomSummary(with: .success(roomID), name: name) + } catch { + MXLog.error("Failed creating room with error: \(error)") + return .failure(.sdkError(error)) } - - return await waitForRoomSummary(with: result, name: name) } func joinRoom(_ roomID: String) async -> Result { @@ -462,103 +454,89 @@ class ClientProxy: ClientProxyProtocol { } func loadUserDisplayName() async -> Result { - await Task.dispatch(on: clientQueue) { - do { - let displayName = try self.client.displayName() - self.userDisplayNameSubject.send(displayName) - return .success(()) - } catch { - MXLog.error("Failed loading user display name with error: \(error)") - return .failure(.sdkError(error)) - } + do { + let displayName = try await client.displayName() + userDisplayNameSubject.send(displayName) + return .success(()) + } catch { + MXLog.error("Failed loading user display name with error: \(error)") + return .failure(.sdkError(error)) } } func setUserDisplayName(_ name: String) async -> Result { - await Task.dispatch(on: clientQueue) { - do { - try self.client.setDisplayName(name: name) - Task { - await self.loadUserDisplayName() - } - return .success(()) - } catch { - MXLog.error("Failed setting user display name with error: \(error)") - return .failure(.sdkError(error)) + do { + try await client.setDisplayName(name: name) + Task { + await self.loadUserDisplayName() } + return .success(()) + } catch { + MXLog.error("Failed setting user display name with error: \(error)") + return .failure(.sdkError(error)) } } func loadUserAvatarURL() async -> Result { - await Task.dispatch(on: clientQueue) { - do { - let urlString = try self.client.avatarUrl() - self.loadCachedAvatarURLTask?.cancel() - self.userAvatarURLSubject.send(urlString.flatMap(URL.init)) - return .success(()) - } catch { - MXLog.error("Failed loading user avatar URL with error: \(error)") - return .failure(.sdkError(error)) - } + do { + let urlString = try await client.avatarUrl() + loadCachedAvatarURLTask?.cancel() + userAvatarURLSubject.send(urlString.flatMap(URL.init)) + return .success(()) + } catch { + MXLog.error("Failed loading user avatar URL with error: \(error)") + return .failure(.sdkError(error)) } } func setUserAvatar(media: MediaInfo) async -> Result { - await Task.dispatch(on: .global()) { - guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else { - MXLog.error("Failed uploading, invalid media: \(media)") - return .failure(.invalidMedia) - } + guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else { + MXLog.error("Failed uploading, invalid media: \(media)") + return .failure(.invalidMedia) + } - do { - let data = try Data(contentsOf: imageURL) - try self.client.uploadAvatar(mimeType: mimeType, data: data) - Task { - await self.loadUserAvatarURL() - } - return .success(()) - } catch { - MXLog.error("Failed setting user avatar with error: \(error)") - return .failure(.sdkError(error)) + do { + let data = try Data(contentsOf: imageURL) + try await client.uploadAvatar(mimeType: mimeType, data: data) + Task { + await self.loadUserAvatarURL() } + return .success(()) + } catch { + MXLog.error("Failed setting user avatar with error: \(error)") + return .failure(.sdkError(error)) } } func removeUserAvatar() async -> Result { - await Task.dispatch(on: .global()) { - do { - try self.client.removeAvatar() - Task { - await self.loadUserAvatarURL() - } - return .success(()) - } catch { - MXLog.error("Failed removing user avatar with error: \(error)") - return .failure(.sdkError(error)) + do { + try await client.removeAvatar() + Task { + await self.loadUserAvatarURL() } + return .success(()) + } catch { + MXLog.error("Failed removing user avatar with error: \(error)") + return .failure(.sdkError(error)) } } func sessionVerificationControllerProxy() async -> Result { - await Task.dispatch(on: clientQueue) { - do { - let sessionVerificationController = try self.client.getSessionVerificationController() - return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController)) - } catch { - MXLog.error("Failed retrieving session verification controller proxy with error: \(error)") - return .failure(.sdkError(error)) - } + do { + let sessionVerificationController = try await client.getSessionVerificationController() + return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController)) + } catch { + MXLog.error("Failed retrieving session verification controller proxy with error: \(error)") + return .failure(.sdkError(error)) } } func logout() async -> URL? { - await Task.dispatch(on: clientQueue) { - do { - return try self.client.logout().flatMap(URL.init(string:)) - } catch { - MXLog.error("Failed logging out with error: \(error)") - return nil - } + do { + return try await client.logout().flatMap(URL.init(string:)) + } catch { + MXLog.error("Failed logging out with error: \(error)") + return nil } } @@ -572,24 +550,20 @@ class ClientProxy: ClientProxyProtocol { } func searchUsers(searchTerm: String, limit: UInt) async -> Result { - await Task.dispatch(on: clientQueue) { - do { - return try .success(.init(sdkResults: self.client.searchUsers(searchTerm: searchTerm, limit: UInt64(limit)))) - } catch { - MXLog.error("Failed searching users with error: \(error)") - return .failure(.sdkError(error)) - } + do { + return try await .success(.init(sdkResults: client.searchUsers(searchTerm: searchTerm, limit: UInt64(limit)))) + } catch { + MXLog.error("Failed searching users with error: \(error)") + return .failure(.sdkError(error)) } } func profile(for userID: String) async -> Result { - await Task.dispatch(on: clientQueue) { - do { - return try .success(.init(sdkUserProfile: self.client.getProfile(userId: userID))) - } catch { - MXLog.error("Failed retrieving profile for userID: \(userID) with error: \(error)") - return .failure(.sdkError(error)) - } + do { + return try await .success(.init(sdkUserProfile: client.getProfile(userId: userID))) + } catch { + MXLog.error("Failed retrieving profile for userID: \(userID) with error: \(error)") + return .failure(.sdkError(error)) } } @@ -815,7 +789,7 @@ class ClientProxy: ClientProxyProtocol { private func roomTupleForIdentifier(_ identifier: String) async -> (RoomListItem?, Room?) { do { - let roomListItem = try roomListService?.room(roomId: identifier) + let roomListItem = try await roomListService?.room(roomId: identifier) if roomListItem?.isTimelineInitialized() == false { try await roomListItem?.initTimeline(eventTypeFilter: eventFilters, internalIdPrefix: nil) } diff --git a/ElementX/Sources/Services/Room/RoomProxy.swift b/ElementX/Sources/Services/Room/RoomProxy.swift index cf95a7ac5..cf2eaec42 100644 --- a/ElementX/Sources/Services/Room/RoomProxy.swift +++ b/ElementX/Sources/Services/Room/RoomProxy.swift @@ -27,8 +27,6 @@ class RoomProxy: RoomProxyProtocol { private let room: RoomProtocol let timeline: TimelineProxyProtocol - private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated) - // periphery:ignore - required for instance retention in the rust codebase private var roomInfoObservationToken: TaskHandle? // periphery:ignore - required for instance retention in the rust codebase @@ -58,7 +56,7 @@ class RoomProxy: RoomProxyProtocol { } var name: String? { - roomListItem.name() + roomListItem.displayName() } var topic: String? { @@ -182,26 +180,22 @@ class RoomProxy: RoomProxyProtocol { } func redact(_ eventID: String) async -> Result { - await Task.dispatch(on: userInitiatedDispatchQueue) { - do { - try self.room.redact(eventId: eventID, reason: nil) - return .success(()) - } catch { - MXLog.error("Failed redacting eventID: \(eventID) with error: \(error)") - return .failure(.sdkError(error)) - } + do { + try await room.redact(eventId: eventID, reason: nil) + return .success(()) + } catch { + MXLog.error("Failed redacting eventID: \(eventID) with error: \(error)") + return .failure(.sdkError(error)) } } func reportContent(_ eventID: String, reason: String?) async -> Result { - await Task.dispatch(on: userInitiatedDispatchQueue) { - do { - try self.room.reportContent(eventId: eventID, score: nil, reason: reason) - return .success(()) - } catch { - MXLog.error("Failed reporting eventID: \(eventID) with error: \(error)") - return .failure(.sdkError(error)) - } + do { + try await room.reportContent(eventId: eventID, score: nil, reason: reason) + return .success(()) + } catch { + MXLog.error("Failed reporting eventID: \(eventID) with error: \(error)") + return .failure(.sdkError(error)) } } @@ -243,99 +237,83 @@ class RoomProxy: RoomProxyProtocol { } func leaveRoom() async -> Result { - await Task.dispatch(on: .global()) { - do { - try self.room.leave() - return .success(()) - } catch { - MXLog.error("Failed leaving room with error: \(error)") - return .failure(.sdkError(error)) - } + do { + try await room.leave() + return .success(()) + } catch { + MXLog.error("Failed leaving room with error: \(error)") + return .failure(.sdkError(error)) } } func rejectInvitation() async -> Result { - await Task.dispatch(on: .global()) { - do { - return try .success(self.room.leave()) - } catch { - MXLog.error("Failed rejecting invitiation with error: \(error)") - return .failure(.sdkError(error)) - } + do { + return try await .success(room.leave()) + } catch { + MXLog.error("Failed rejecting invitiation with error: \(error)") + return .failure(.sdkError(error)) } } func acceptInvitation() async -> Result { - await Task.dispatch(on: .global()) { - do { - try self.room.join() - return .success(()) - } catch { - MXLog.error("Failed accepting invitation with error: \(error)") - return .failure(.sdkError(error)) - } + do { + try await room.join() + return .success(()) + } catch { + MXLog.error("Failed accepting invitation with error: \(error)") + return .failure(.sdkError(error)) } } func invite(userID: String) async -> Result { - await Task.dispatch(on: .global()) { - do { - MXLog.info("Inviting user \(userID)") - return try .success(self.room.inviteUserById(userId: userID)) - } catch { - MXLog.error("Failed inviting user \(userID) with error: \(error)") - return .failure(.sdkError(error)) - } + do { + MXLog.info("Inviting user \(userID)") + return try await .success(room.inviteUserById(userId: userID)) + } catch { + MXLog.error("Failed inviting user \(userID) with error: \(error)") + return .failure(.sdkError(error)) } } func setName(_ name: String) async -> Result { - await Task.dispatch(on: .global()) { - do { - return try .success(self.room.setName(name: name)) - } catch { - MXLog.error("Failed setting name with error: \(error)") - return .failure(.sdkError(error)) - } + do { + return try await .success(room.setName(name: name)) + } catch { + MXLog.error("Failed setting name with error: \(error)") + return .failure(.sdkError(error)) } } func setTopic(_ topic: String) async -> Result { - await Task.dispatch(on: .global()) { - do { - return try .success(self.room.setTopic(topic: topic)) - } catch { - MXLog.error("Failed setting topic with error: \(error)") - return .failure(.sdkError(error)) - } + do { + return try await .success(room.setTopic(topic: topic)) + } catch { + MXLog.error("Failed setting topic with error: \(error)") + return .failure(.sdkError(error)) } } func removeAvatar() async -> Result { - await Task.dispatch(on: .global()) { - do { - return try .success(self.room.removeAvatar()) - } catch { - MXLog.error("Failed removing avatar with error: \(error)") - return .failure(.sdkError(error)) - } + do { + return try await .success(room.removeAvatar()) + } catch { + MXLog.error("Failed removing avatar with error: \(error)") + return .failure(.sdkError(error)) } } func uploadAvatar(media: MediaInfo) async -> Result { - await Task.dispatch(on: .global()) { - guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else { - MXLog.error("Failed uploading avatar, invalid media: \(media)") - return .failure(.invalidMedia) - } + guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else { + MXLog.error("Failed uploading avatar, invalid media: \(media)") + return .failure(.invalidMedia) + } - do { - let data = try Data(contentsOf: imageURL) - return try .success(self.room.uploadAvatar(mimeType: mimeType, data: data, mediaInfo: nil)) - } catch { - MXLog.error("Failed uploading avatar with error: \(error)") - return .failure(.sdkError(error)) - } + do { + let data = try Data(contentsOf: imageURL) + return try await .success(room.uploadAvatar(mimeType: mimeType, data: data, mediaInfo: nil)) + } catch { + MXLog.error("Failed uploading avatar with error: \(error)") + return .failure(.sdkError(error)) } } diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift index ef60774d3..d74542d97 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift @@ -193,7 +193,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { return updatedItems } - private func fetchRoomInfo(roomListItem: RoomListItemProtocol) -> RoomInfo? { + private func fetchRoomInfo(roomID: String) -> RoomInfo? { class FetchResult { var roomInfo: RoomInfo? } @@ -203,6 +203,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { Task { do { + let roomListItem = try await roomListService.room(roomId: roomID) result.roomInfo = try await roomListItem.roomInfo() } catch { MXLog.error("Failed fetching room info with error: \(error)") @@ -214,12 +215,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { } private func buildRoomSummaryForIdentifier(_ identifier: String, invalidated: Bool) -> RoomSummary { - guard let roomListItem = try? roomListService.room(roomId: identifier) else { - MXLog.error("\(name): Failed finding room with id: \(identifier)") - return .empty - } - - guard let roomInfo = fetchRoomInfo(roomListItem: roomListItem) else { + guard let roomInfo = fetchRoomInfo(roomID: identifier) else { return .empty } @@ -242,7 +238,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { let details = RoomSummaryDetails(id: roomInfo.id, isInvite: roomInfo.membership == .invited, inviter: inviterProxy, - name: roomInfo.name ?? roomInfo.id, + name: roomInfo.rawName ?? roomInfo.id, isDirect: roomInfo.isDirect, avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)), lastMessage: attributedLastMessage, diff --git a/ElementX/Sources/Services/Timeline/TimelineProxy.swift b/ElementX/Sources/Services/Timeline/TimelineProxy.swift index a1bdf5544..558211b60 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProxy.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProxy.swift @@ -21,9 +21,7 @@ import MatrixRustSDK final class TimelineProxy: TimelineProxyProtocol { private let timeline: Timeline - private let lowPriorityDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.low_priority", qos: .utility) private let messageSendingDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.message_sending", qos: .userInitiated) - private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated) private var backPaginationStatusObservationToken: TaskHandle? private var roomTimelineObservationToken: TaskHandle? @@ -104,40 +102,36 @@ final class TimelineProxy: TimelineProxyProtocol { html: html, intentionalMentions: intentionalMentions.toRustMentions()) - return await Task.dispatch(on: messageSendingDispatchQueue) { - do { - let originalEvent = try self.timeline.getEventTimelineItemByEventId(eventId: eventID) - try self.timeline.edit(newContent: messageContent, editItem: originalEvent) + do { + let originalEvent = try await timeline.getEventTimelineItemByEventId(eventId: eventID) + try await timeline.edit(newContent: messageContent, editItem: originalEvent) - MXLog.info("Finished editing message with original event ID: \(eventID)") + MXLog.info("Finished editing message with original event ID: \(eventID)") - return .success(()) - } catch { - MXLog.error("Failed editing message with original event ID: \(eventID) with error: \(error)") - return .failure(.failedEditingMessage) - } + return .success(()) + } catch { + MXLog.error("Failed editing message with original event ID: \(eventID) with error: \(error)") + return .failure(.failedEditingMessage) } } func fetchDetails(for eventID: String) { Task { - await Task.dispatch(on: .global()) { - do { - MXLog.info("Fetching event details for \(eventID)") - try self.timeline.fetchDetailsForEvent(eventId: eventID) - MXLog.info("Finished fetching event details for eventID: \(eventID)") - } catch { - MXLog.error("Failed fetching event details for eventID: \(eventID) with error: \(error)") - } + do { + MXLog.info("Fetching event details for \(eventID)") + try await self.timeline.fetchDetailsForEvent(eventId: eventID) + MXLog.info("Finished fetching event details for eventID: \(eventID)") + } catch { + MXLog.error("Failed fetching event details for eventID: \(eventID) with error: \(error)") } } } - func messageEventContent(for eventID: String) -> RoomMessageEventContentWithoutRelation? { + func messageEventContent(for eventID: String) async -> RoomMessageEventContentWithoutRelation? { MXLog.info("Fetching event content for \(eventID)") do { - let result = try timeline.getTimelineEventContentByEventId(eventId: eventID) + let result = try await timeline.getTimelineEventContentByEventId(eventId: eventID) MXLog.info("Finished fetching event content for eventID: \(eventID)") return result } catch { @@ -366,30 +360,28 @@ final class TimelineProxy: TimelineProxyProtocol { html: html, intentionalMentions: intentionalMentions.toRustMentions()) - return await Task.dispatch(on: messageSendingDispatchQueue) { - do { - if let eventID { - let replyItem = try self.timeline.getEventTimelineItemByEventId(eventId: eventID) - try self.timeline.sendReply(msg: messageContent, replyItem: replyItem) - MXLog.info("Finished sending reply to eventID: \(eventID)") - } else { - self.timeline.send(msg: messageContent) - MXLog.info("Finished sending message") - } - } catch { - if let eventID { - MXLog.error("Failed sending reply to eventID: \(eventID)") - } else { - MXLog.error("Failed sending message") - } - - return .failure(.failedSendingMessage) + do { + if let eventID { + let replyItem = try await timeline.getEventTimelineItemByEventId(eventId: eventID) + try await timeline.sendReply(msg: messageContent, replyItem: replyItem) + MXLog.info("Finished sending reply to eventID: \(eventID)") + } else { + timeline.send(msg: messageContent) + MXLog.info("Finished sending message") } - - self.actionsSubject.send(.sentMessage) - - return .success(()) + } catch { + if let eventID { + MXLog.error("Failed sending reply to eventID: \(eventID)") + } else { + MXLog.error("Failed sending message") + } + + return .failure(.failedSendingMessage) } + + actionsSubject.send(.sentMessage) + + return .success(()) } func sendMessageEventContent(_ messageContent: RoomMessageEventContentWithoutRelation) async -> Result { @@ -409,30 +401,26 @@ final class TimelineProxy: TimelineProxyProtocol { func sendReadReceipt(for eventID: String, type: ReceiptType) async -> Result { MXLog.verbose("Sending read receipt for eventID: \(eventID)") - return await Task.dispatch(on: lowPriorityDispatchQueue) { - do { - try self.timeline.sendReadReceipt(receiptType: type, eventId: eventID) - MXLog.info("Finished sending read receipt for eventID: \(eventID)") - return .success(()) - } catch { - MXLog.error("Failed sending read receipt for eventID: \(eventID) with error: \(error)") - return .failure(.failedSendingReadReceipt) - } + do { + try await timeline.sendReadReceipt(receiptType: type, eventId: eventID) + MXLog.info("Finished sending read receipt for eventID: \(eventID)") + return .success(()) + } catch { + MXLog.error("Failed sending read receipt for eventID: \(eventID) with error: \(error)") + return .failure(.failedSendingReadReceipt) } } func toggleReaction(_ reaction: String, to eventID: String) async -> Result { MXLog.info("Toggling reaction for eventID: \(eventID)") - return await Task.dispatch(on: userInitiatedDispatchQueue) { - do { - try self.timeline.toggleReaction(eventId: eventID, key: reaction) - MXLog.info("Finished toggling reaction for eventID: \(eventID)") - return .success(()) - } catch { - MXLog.error("Failed toggling reaction for eventID: \(eventID)") - return .failure(.failedSendingReaction) - } + do { + try await timeline.toggleReaction(eventId: eventID, key: reaction) + MXLog.info("Finished toggling reaction for eventID: \(eventID)") + return .success(()) + } catch { + MXLog.error("Failed toggling reaction for eventID: \(eventID)") + return .failure(.failedSendingReaction) } } @@ -464,9 +452,7 @@ final class TimelineProxy: TimelineProxyProtocol { MXLog.info("Editing poll with eventID: \(eventID)") do { - let originalEvent = try await Task.dispatch(on: .global()) { - try self.timeline.getEventTimelineItemByEventId(eventId: eventID) - } + let originalEvent = try await timeline.getEventTimelineItemByEventId(eventId: eventID) try await timeline.editPoll(question: question, answers: answers, maxSelections: 1, pollKind: .init(pollKind: pollKind), editItem: originalEvent) diff --git a/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift index 70866b363..c58dbeef3 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift @@ -57,7 +57,7 @@ protocol TimelineProxyProtocol { func fetchDetails(for eventID: String) - func messageEventContent(for eventID: String) -> RoomMessageEventContentWithoutRelation? + func messageEventContent(for eventID: String) async -> RoomMessageEventContentWithoutRelation? func retryDecryption(for sessionID: String) async diff --git a/ElementX/Sources/Services/UserSession/UserSessionStore.swift b/ElementX/Sources/Services/UserSession/UserSessionStore.swift index 96995ab74..09be87005 100644 --- a/ElementX/Sources/Services/UserSession/UserSessionStore.swift +++ b/ElementX/Sources/Services/UserSession/UserSessionStore.swift @@ -68,7 +68,7 @@ class UserSessionStore: UserSessionStoreProtocol { func userSession(for client: Client, passphrase: String?) async -> Result { do { - let session = try client.session() + let session = try await client.session() let userID = try client.userId() let clientProxy = await setupProxyForClient(client) @@ -133,9 +133,7 @@ class UserSessionStore: UserSessionStoreProtocol { do { let client = try await completeBuilder.build() - try await Task.dispatch(on: .global()) { - try client.restoreSession(session: credentials.restorationToken.session) - } + try await client.restoreSession(session: credentials.restorationToken.session) return await .success(setupProxyForClient(client)) } catch { diff --git a/NSE/Sources/Other/NSEUserSession.swift b/NSE/Sources/Other/NSEUserSession.swift index 4da12cdfb..cfde59f75 100644 --- a/NSE/Sources/Other/NSEUserSession.swift +++ b/NSE/Sources/Other/NSEUserSession.swift @@ -48,30 +48,25 @@ final class NSEUserSession { baseClient = try await clientBuilder.build() delegateHandle = baseClient.setDelegate(delegate: ClientDelegateWrapper()) - try baseClient.restoreSession(session: credentials.restorationToken.session) + try await baseClient.restoreSession(session: credentials.restorationToken.session) - notificationClient = try baseClient - .notificationClient(processSetup: .multipleProcesses) - .filterByPushRules() - .finish() + notificationClient = try await baseClient.notificationClient(processSetup: .multipleProcesses) } func notificationItemProxy(roomID: String, eventID: String) async -> NotificationItemProxyProtocol? { - await Task.dispatch(on: .global()) { - do { - let notification = try self.notificationClient.getNotification(roomId: roomID, eventId: eventID) + do { + let notification = try await notificationClient.getNotification(roomId: roomID, eventId: eventID) - guard let notification else { - return nil - } - return NotificationItemProxy(notificationItem: notification, - eventID: eventID, - receiverID: self.userID, - roomID: roomID) - } catch { - MXLog.error("NSE: Could not get notification's content creating an empty notification instead, error: \(error)") - return EmptyNotificationItemProxy(eventID: eventID, roomID: roomID, receiverID: self.userID) + guard let notification else { + return nil } + return NotificationItemProxy(notificationItem: notification, + eventID: eventID, + receiverID: userID, + roomID: roomID) + } catch { + MXLog.error("NSE: Could not get notification's content creating an empty notification instead, error: \(error)") + return EmptyNotificationItemProxy(eventID: eventID, roomID: roomID, receiverID: userID) } } diff --git a/UnitTests/Sources/RoomPollsHistoryScreenViewModelTests.swift b/UnitTests/Sources/RoomPollsHistoryScreenViewModelTests.swift index 2a29621e7..bcc1744bf 100644 --- a/UnitTests/Sources/RoomPollsHistoryScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomPollsHistoryScreenViewModelTests.swift @@ -139,7 +139,7 @@ class RoomPollsHistoryScreenViewModelTests: XCTestCase { } func testSendPollResponse() async throws { - let deferred = deferFulfillment(interactionHandler.publisher) { _ in true } + let deferred = deferFulfillment(interactionHandler.publisher.delay(for: 0.1, scheduler: DispatchQueue.main)) { _ in true } interactionHandler.sendPollResponsePollStartIDOptionIDReturnValue = .success(()) viewModel.context.send(viewAction: .sendPollResponse(pollStartID: "somePollID", optionID: "someOptionID")) diff --git a/project.yml b/project.yml index 3b3aa2a90..b439d9665 100644 --- a/project.yml +++ b/project.yml @@ -49,7 +49,7 @@ packages: # Element/Matrix dependencies MatrixRustSDK: url: https://github.com/matrix-org/matrix-rust-components-swift - exactVersion: 1.1.63 + exactVersion: 1.1.64 # path: ../matrix-rust-sdk Compound: url: https://github.com/element-hq/compound-ios