mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
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:
@@ -16,7 +16,7 @@ enum MediaLoaderError: Error {
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol MediaLoaderProtocol {
|
||||
protocol MediaLoaderProtocol: Sendable {
|
||||
func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data
|
||||
|
||||
func loadMediaThumbnailForSource(_ source: MediaSourceProxy, width: UInt, height: UInt) async throws -> Data
|
||||
|
||||
@@ -159,7 +159,7 @@ final class NotificationManager: NSObject, NotificationManagerProtocol {
|
||||
}
|
||||
|
||||
private func removeReceivedWhileOfflineNotification() {
|
||||
notificationCenter.removeDeliveredNotifications(withIdentifiers: [NotificationServiceExtension.receivedWhileOfflineNotificationID])
|
||||
notificationCenter.removeDeliveredNotifications(withIdentifiers: [NotificationServiceExtensionActor.receivedWhileOfflineNotificationID])
|
||||
}
|
||||
|
||||
private func setPusher(with deviceToken: Data, clientProxy: ClientProxyProtocol) async -> Bool {
|
||||
|
||||
@@ -12,10 +12,14 @@ import MatrixRustSDK
|
||||
|
||||
class TimelineItemProvider: TimelineItemProviderProtocol {
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
private let serialDispatchQueue: DispatchQueue
|
||||
|
||||
|
||||
private var roomTimelineObservationToken: TaskHandle?
|
||||
|
||||
/// Bridge from the SDK's synchronous callback into Swift Concurrency. Yielding is safe from any
|
||||
/// thread; a single long-lived `for await` consumer (set up in `init`) applies the diffs on the
|
||||
/// main actor in FIFO order, guaranteeing one in-flight update at a time.
|
||||
private let diffContinuation: AsyncStream<[TimelineDiff]>.Continuation
|
||||
|
||||
private let paginationStateSubject = CurrentValueSubject<TimelinePaginationState, Never>(.initial)
|
||||
var paginationState: TimelinePaginationState {
|
||||
paginationStateSubject.value
|
||||
@@ -33,35 +37,44 @@ class TimelineItemProvider: TimelineItemProviderProtocol {
|
||||
.combineLatest(paginationStateSubject)
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
||||
let kind: TimelineKind
|
||||
|
||||
|
||||
private let membershipChangeSubject = PassthroughSubject<Void, Never>()
|
||||
var membershipChangePublisher: AnyPublisher<Void, Never> {
|
||||
membershipChangeSubject
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
||||
deinit {
|
||||
diffContinuation.finish()
|
||||
roomTimelineObservationToken?.cancel()
|
||||
}
|
||||
|
||||
init(timeline: Timeline, kind: TimelineKind, paginationStatePublisher: AnyPublisher<TimelinePaginationState, Never>) {
|
||||
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.timeline_item_provider", qos: .utility)
|
||||
itemProxiesSubject = CurrentValueSubject<[TimelineItemProxy], Never>([])
|
||||
self.kind = kind
|
||||
|
||||
|
||||
let (diffStream, diffContinuation) = AsyncStream<[TimelineDiff]>.makeStream()
|
||||
self.diffContinuation = diffContinuation
|
||||
|
||||
paginationStatePublisher
|
||||
.sink { [weak self] in
|
||||
self?.paginationStateSubject.send($0)
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
|
||||
// `for await` guarantees FIFO ordering and that only one diff is being applied at a time.
|
||||
// The stream also allows to handle the sendable items in the listener.
|
||||
Task { [weak self] in
|
||||
for await diffs in diffStream {
|
||||
self?.updateItemsWithDiffs(diffs)
|
||||
}
|
||||
}
|
||||
|
||||
Task {
|
||||
roomTimelineObservationToken = await timeline.addListener(listener: SDKListener { [weak self] timelineDiffs in
|
||||
self?.serialDispatchQueue.sync {
|
||||
self?.updateItemsWithDiffs(timelineDiffs)
|
||||
}
|
||||
roomTimelineObservationToken = await timeline.addListener(listener: SDKListener { diffs in
|
||||
diffContinuation.yield(diffs)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user