I am engaged on a SwiftUI software the place I’ve a SessionsView that ought to show an inventory of chat periods. The information for the periods is fetched from a distant service and saved in an ObservableObject known as SessionsViewModel. Regardless of the information being fetched accurately, the view doesn’t replace to mirror the adjustments.
Listed here are the related elements of my code:
AppDependencies.swift
class AppDependencies: ObservableObject {
static let sessionRepository = FirebaseSessionRepository(firebaseService: FirebaseDatabaseService())
static let userRepository = FirebaseUserRepository(firebaseDatabaseService: FirebaseDatabaseService(), firebaseAuthService: FirebaseAuthService())
let userManager = UserManager(userRepository: AppDependencies.userRepository)
@Printed var sessionsViewModel: SessionsViewModel
init() {
sessionsViewModel = AppDependencies.setupSessionsViewModel(userManager: userManager)
}
static func setupSessionsViewModel(userManager: UserManager) -> SessionsViewModel {
let fetchUserSessionsUseCase = FetchUserSessionsUseCase(repository: sessionRepository)
let getUserInfoUseCase = GetUserInfoUseCase(repository: userRepository)
return SessionsViewModel(fetchUserSessionsUseCase: fetchUserSessionsUseCase, getUserInfoUseCase: getUserInfoUseCase, userManager: userManager)
}
}
SessionsView
struct SessionsView: View {
@EnvironmentObject var dependencies: AppDependencies
var physique: some View {
NavigationStack {
let sortedSessions = dependencies.sessionsViewModel.sessionsDict.values.sorted { $0.lastUpdated < $1.lastUpdated }
Checklist(sortedSessions) { session in
if let person = dependencies.sessionsViewModel.usersDict[session.id] {
NavigationLink {
ChatView(partnerUser: person, session: session)
.environmentObject(dependencies)
} label: {
let lastUser = session.lastUserId == dependencies.sessionsViewModel.userManager.currentUser?.id ? "You" : person.displayName
VStack(alignment: .main) {
HStack {
Textual content("(person.displayName ?? "")")
.font(.headline)
Spacer()
Textual content("(formattedDate(timestamp: session.lastUpdated))")
.font(.footnote)
.foregroundColor(.grey)
}
Textual content("(lastUser ?? ""): (session.lastMessage)")
.font(.subheadline)
}
// .padding()
}
.swipeActions(edge: .main) {
Button("delete", systemImage: "message") {
print("Hi")
}
}
.swipeActions(edge: .trailing) {
Button("Ship message", systemImage: "message") {
print("Hi")
}
}
}
}
.navigationTitle("Periods")
.navigationBarTitleDisplayMode(.inline)
}.onAppear {
self.dependencies.sessionsViewModel.fetchUserSessions(userId: self.dependencies.sessionsViewModel.userManager.currentUser?.id ?? "")
}
}
non-public func formattedDate(timestamp: Int) -> String {
let date = Date(timeIntervalSince1970: TimeInterval(timestamp) / 1000)
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .none
dateFormatter.timeStyle = .quick
return dateFormatter.string(from: date)
}
}
SessionsViewModel
class SessionsViewModel: ObservableObject, ViewModel {
non-public let createChatSessionUseCase: CreateChatSessionUseCase?
non-public let fetchUserSessionsUseCase: FetchUserSessionsUseCase?
var userManager: UserManager
@Printed var sessionsDict = [String: Session]()
@Printed var usersDict = [String: User]()
init(createChatSessionUseCase: CreateChatSessionUseCase? = nil,
fetchUserSessionsUseCase: FetchUserSessionsUseCase? = nil,
userManager: UserManager) {
self.createChatSessionUseCase = createChatSessionUseCase
self.fetchUserSessionsUseCase = fetchUserSessionsUseCase
self.userManager = userManager
}
func createChatSession(partner1: String, partner2: String, completion: @escaping (CreateChatSessionError) -> Void) {
createChatSessionUseCase?.execute(request: (partner1, partner2)) { lead to
change outcome {
case .success(let session):
break
case .failure(let error):
if let error = error as? CreateChatSessionError {
completion(error)
}
}
}
}
func fetchUserSessions(userId: String) {
fetchUserSessionsUseCase?.execute(request: userId) { lead to
change outcome {
case .success(let sessionsDict):
self.sessionsDict.merge(sessionsDict) { previous, new in new }
for session in sessionsDict.values {
self.getUser(for: session)
}
case .failure(let error):
break
}
}
}
func getUser(for session: Session) {
let partnerId = session.partner1 == userManager.currentUser?.id ? session.partner2 : session.partner1
self.getUserInfoUseCase?.execute(request: partnerId) { lead to
change outcome {
case .success(let person):
self.usersDict[session.id] = person
case .failure(let error):
// one thing
break
}
}
}
}
What I’ve Tried:
- Verified that sessionsDict is up to date with the proper periods.
- Verified that SessionsViewModel and AppDependencies each implement ObservableObject.
- Ensured SessionsViewModel makes use of @Printed properties for sessionsDict and usersDict.