Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix updating channel's preview message when coming back to online #3574

Merged
merged 4 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

# Upcoming

### 🔄 Changed
## StreamChat
### 🐞 Fixed
- Update channel's preview message when coming back to online [#3574](https://github.com/GetStream/stream-chat-swift/pull/3574)

# [4.71.0](https://github.com/GetStream/stream-chat-swift/releases/tag/4.71.0)
_January 28, 2025_
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,15 @@ class FetchCache {

extension NSManagedObjectContext {
func fetch<T>(_ request: NSFetchRequest<T>, using cache: FetchCache) throws -> [T] where T: NSFetchRequestResult {
if let objectIds = cache.get(request), !objectIds.contains(where: { $0.isTemporaryID }) {
func canUseCachedIds(_ objectIds: [NSManagedObjectID]) -> Bool {
// Ignore cache when inserted (but not yet saved) object id is present
guard !objectIds.contains(where: { $0.isTemporaryID }) else { return false }
// Context has pending inserted or deleted objects of this type (can affect ids returned by the fetch request)
guard !insertedObjects.contains(where: { $0 is T }) && !deletedObjects.contains(where: { $0 is T }) else { return false }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theoretically speaking even updatedObjects could change results, but this will take away the benefit of the cache. Based on the history, it was added for speeding up channel list payload writes.

return true
}

if let objectIds = cache.get(request), canUseCachedIds(objectIds) {
return try objectIds.compactMap { try existingObject(with: $0) as? T }
}

Expand Down
21 changes: 21 additions & 0 deletions Tests/StreamChatTests/Database/FetchCache_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,27 @@ final class FetchCache_Tests: XCTestCase {

XCTAssertEqual(cache.cacheEntriesCount, 3)
}

func test_ignoringCacheIfContextHasInsertedOrDeletedObjectsOfThatType() async throws {
let database = DatabaseContainer(kind: .inMemory, chatClientConfig: .init(apiKeyString: .unique))
let cid = ChannelId.unique
try database.createCurrentUser(id: .unique, name: "")
try database.createChannel(cid: cid, withMessages: true)
try await database.write { session in
// FetchCache caches the response
guard let firstPreviewMessage = session.preview(for: cid) else { throw ClientError.Unknown("Preview message missing") }

// Insert a new message what is newer than the current preview message
let newMessagePayload = MessagePayload.dummy(createdAt: firstPreviewMessage.createdAt.bridgeDate.addingTimeInterval(1.0))
try session.saveMessage(payload: newMessagePayload, for: cid, syncOwnReactions: false, cache: nil)

guard let secondPreviewMessage = session.preview(for: cid) else { throw ClientError.Unknown("Preview message missing") }
XCTAssertEqual(newMessagePayload.id, secondPreviewMessage.id)
XCTAssertNotEqual(firstPreviewMessage.id, secondPreviewMessage.id)
}
}

// MARK: - Test Data

private var tenIds: [TestId] {
(1...10).map { _ in TestId() }
Expand Down
Loading