ViewFactory should be @MainActor constrained
What are you trying to achieve?
I have views that depend on MainActor isolated view models. In order to initialize my views I need to retrieve these MainActor isolated dependencies that are retrieved via "@Inject" in the viewfactory. Since the viewfactory methods are nonisolated, I'm not able to access these - and if I annotate the methods as @MainActor, they do not satisfy the protocol requirements.
If possible, how can you achieve this currently?
Maybe I could try injecting them directly into the views?
What would be the better way?
Since SwiftUI Views are MainActor isolated to begin with, and the ViewFactory is invoked from Views in a MainActor isolated context, it seems reasonable to constrain the ViewFactory to MainActor
GetStream Environment
GetStream Chat version: 4.61 GetStream Chat frameworks: StreamChat, StreamChatSwiftUI iOS version: any Swift version: 6 Xcode version: 16.2 Device: any
Additional context
n/a
Hi @swizzlr,
We'll review it internally and will get back to you. Adding a @MainActor requirement might cause a breaking change for SDK users, therefore it needs to be considered carefully.
Thank you, Toomas
We have a strong suspicion that using Swift 6 in the project and using the ViewFactory causes visible framerate issues. Using the predefined signleton implementation works without issues. Thank you!
as @andrej-jasso mentioned, using Swift 6 in the project and annotating functions with @MainActor is causing slight freezes in the app. The more functions marked with @MainActor, the more noticeable the glitches — especially during scrolling messages and when opening or closing the keyboard.
Below are the implemented functions we suspect to be contributing to the problem: `
@MainActor
func makeChannelHeaderViewModifier(for channel: ChatChannel) -> some ChatChannelHeaderViewModifier {
lastVisitedChannelId = channel.cid.id
return NonNavigableChatHeaderModifier(channel: channel)
}
@MainActor
func makeMessageContainerView(
channel: ChatChannel,
message: ChatMessage,
width: CGFloat?,
showsAllInfo: Bool,
isInThread: Bool,
scrolledId: Binding<String?>,
quotedMessage: Binding<ChatMessage?>,
onLongPress: @escaping (MessageDisplayInfo) -> Void,
isLast: Bool
) -> some View {
MessageContainerWrapperView(
factory: self,
channel: channel,
message: message,
width: width,
showsAllInfo: showsAllInfo,
isInThread: isInThread,
isLast: isLast,
scrolledId: scrolledId,
quotedMessage: quotedMessage,
onLongPress: onLongPress
)
}
@MainActor
func makeMessageAvatarView(for userDisplayInfo: UserDisplayInfo) -> some View {
CustomMessageAvatarView(avatarURL: userDisplayInfo.imageURL, name: userDisplayInfo.name, id: lastVisitedChannelId)
}