Skip to content

Commit

Permalink
Fixes /issues/5063 - Fixed retain cycles between the user suggestion …
Browse files Browse the repository at this point in the history
…coordinator and the suggestion service, and in the suggestion service currentTextTrigger subject sink.
  • Loading branch information
stefanceriu committed Oct 29, 2021
1 parent baef854 commit 825444d
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ final class UserSuggestionCoordinator: Coordinator {

private let parameters: UserSuggestionCoordinatorParameters

private var userSuggestionHostingController: UIViewController!
private var userSuggestionService: UserSuggestionServiceProtocol!
private var userSuggestionViewModel: UserSuggestionViewModelProtocol!

private var roomMembers: [MXRoomMember] = []
private var userSuggestionHostingController: UIViewController
private var userSuggestionService: UserSuggestionServiceProtocol
private var userSuggestionViewModel: UserSuggestionViewModelProtocol
private var roomMemberProvider: UserSuggestionCoordinatorRoomMemberProvider

// MARK: Public

Expand All @@ -54,9 +53,10 @@ final class UserSuggestionCoordinator: Coordinator {
init(parameters: UserSuggestionCoordinatorParameters) {
self.parameters = parameters

userSuggestionService = UserSuggestionService(roomMembersProvider: self)
roomMemberProvider = UserSuggestionCoordinatorRoomMemberProvider(room: parameters.room)
userSuggestionService = UserSuggestionService(roomMemberProvider: roomMemberProvider)
userSuggestionViewModel = UserSuggestionViewModel.makeUserSuggestionViewModel(userSuggestionService: userSuggestionService)

let view = UserSuggestionList(viewModel: userSuggestionViewModel.context)
.addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager))

Expand All @@ -69,7 +69,7 @@ final class UserSuggestionCoordinator: Coordinator {

switch result {
case .selectedItemWithIdentifier(let identifier):
guard let member = self.roomMembers.filter({ $0.userId == identifier }).first else {
guard let member = self.roomMemberProvider.roomMembers.filter({ $0.userId == identifier }).first else {
return
}

Expand All @@ -93,9 +93,18 @@ final class UserSuggestionCoordinator: Coordinator {
}

@available(iOS 14.0, *)
extension UserSuggestionCoordinator: RoomMembersProviderProtocol {
private class UserSuggestionCoordinatorRoomMemberProvider: RoomMembersProviderProtocol {

private let room: MXRoom

var roomMembers: [MXRoomMember] = []

init(room: MXRoom) {
self.room = room;
}

func fetchMembers(_ members: @escaping ([RoomMembersProviderMember]) -> Void) {
parameters.room.members({ [weak self] roomMembers in
room.members({ [weak self] roomMembers in
guard let self = self, let joinedMembers = roomMembers?.joinedMembers else {
return
}
Expand All @@ -108,7 +117,7 @@ extension UserSuggestionCoordinator: RoomMembersProviderProtocol {
self.roomMembers = joinedMembers
members(self.roomMembersToProviderMembers(joinedMembers))
}, failure: { error in
MXLog.error("[UserSuggestionCoordinator] Failed loading room with error: \(String(describing: error))")
MXLog.error("[UserSuggestionCoordinatorRoomMemberProvider] Failed loading room with error: \(String(describing: error))")
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ enum MockUserSuggestionScreenState: MockScreenState, CaseIterable {
}

var screenView: ([Any], AnyView) {
let service = UserSuggestionService(roomMembersProvider: self)
let service = UserSuggestionService(roomMemberProvider: self)
let listViewModel = UserSuggestionViewModel.makeUserSuggestionViewModel(userSuggestionService: service)

let viewModel = UserSuggestionListWithInputViewModel(listViewModel: listViewModel) { textMessage in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class UserSuggestionService: UserSuggestionServiceProtocol {

// MARK: Private

private let roomMembersProvider: RoomMembersProviderProtocol
private let roomMemberProvider: RoomMembersProviderProtocol

private var suggestionItems: [UserSuggestionItemProtocol] = []
private let currentTextTriggerSubject = CurrentValueSubject<String?, Never>(nil)
Expand All @@ -61,13 +61,13 @@ class UserSuggestionService: UserSuggestionServiceProtocol {

// MARK: - Setup

init(roomMembersProvider: RoomMembersProviderProtocol) {
self.roomMembersProvider = roomMembersProvider
init(roomMemberProvider: RoomMembersProviderProtocol) {
self.roomMemberProvider = roomMemberProvider

currentTextTriggerSubject
.debounce(for: 0.5, scheduler: RunLoop.main)
.removeDuplicates()
.sink { self.fetchAndFilterMembersForTextTrigger($0) }
.sink { [weak self] in self?.fetchAndFilterMembersForTextTrigger($0) }
.store(in: &cancellables)
}

Expand Down Expand Up @@ -96,7 +96,7 @@ class UserSuggestionService: UserSuggestionServiceProtocol {

partialName.removeFirst() // remove the '@' prefix

roomMembersProvider.fetchMembers { [weak self] members in
roomMemberProvider.fetchMembers { [weak self] members in
guard let self = self else {
return
}
Expand Down
1 change: 1 addition & 0 deletions changelog.d/5063.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed retain cycles between the user suggestion coordinator and the suggestion service, and in the suggestion service currentTextTrigger subject sink.

0 comments on commit 825444d

Please sign in to comment.