Swift 6 migration for NSE (#5608)

* swift 6 support for NSE and concurrency safe implementations for it

* enforcing required Sendable conformance for swift 6 migration in NSE

* use Mutex to access the string builder cache

* use an async stream to update timeline items diffs

* fix for Sendable appHooks
This commit is contained in:
Mauro
2026-05-21 20:21:57 +02:00
committed by GitHub
parent 91ccff36fc
commit 2462ddea85
20 changed files with 226 additions and 150 deletions
@@ -10,6 +10,7 @@ import Compound
import LRUCache
import MatrixRustSDK
import SwiftSoup
import Synchronization
import UIKit
protocol MentionBuilderProtocol {
@@ -42,11 +43,10 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
private let mentionBuilder: MentionBuilderProtocol
private static let attributeMSC4286 = "msc4286-external-payment-details"
private static let cacheDispatchQueue = DispatchQueue(label: "io.element.elementx.attributed_string_builder_v2_cache")
private static var caches: [String: LRUCache<String, AttributedString>] = [:]
private static let caches = Mutex<[String: LRUCache<String, AttributedString>]>([:])
static func invalidateCaches() {
caches.removeAll()
caches.withLock { $0.removeAll() }
}
init(cacheKey: String = defaultKey, mentionBuilder: MentionBuilderProtocol) {
@@ -279,22 +279,17 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
}
private static func cacheValue(_ value: AttributedString?, forKey key: String, cacheKey: String) {
cacheDispatchQueue.sync {
caches.withLock { caches in
if caches[cacheKey] == nil {
caches[cacheKey] = LRUCache<String, AttributedString>(countLimit: 1000)
}
caches[cacheKey]?.setValue(value, forKey: key)
}
}
private static func cachedValue(forKey key: String, cacheKey: String) -> AttributedString? {
var result: AttributedString?
cacheDispatchQueue.sync {
result = caches[cacheKey]?.value(forKey: key)
}
return result
caches.withLock { $0[cacheKey]?.value(forKey: key) }
}
// swiftlint:disable:next cyclomatic_complexity