I can specify the scheduler as RunLoop.main, but I could not find a native way to provide the associated RunLoop.Mode mode to receive elements from a publisher.
Why do I need this: I'm updating a tableView cell from my publisher but the UI does not update if the user is scrolling, it then updates as soon as the user interaction or scroll stops. This is a known behaviour for scrollViews but I want my content to be displayed as soon as possible, and being able to specify the run loop tracking mode would fix this.
Combine API: I do not think the receive(on:options:) method have any matching options to provide this. I think internally, if I call receive(on:RunLoop.main) then RunLoop.main.perform { } is called. This perform method can take the mode as parameter but this is not exposed to the Combine API.
Current Idea: To go around this I could do the perform action myself and not use the Combine API, so instead of doing this:
cancellable = stringFuture.receive(on: RunLoop.main) // I cannot specify the mode here
.sink { string in
cell.textLabel.text = string
}
I could do this:
cancellable = stringFuture.sink { string in
RunLoop.main.perform(inModes: [RunLoop.Mode.common]) { // I can specify it here
cell.textLabel.text = string
}
}
But this is not ideal.
Ideal Solution: I was wondering how could I wrap this into my own implementation of a publisher function to have something like this:
cancellable = stringFuture.receive(on: RunLoop.main, inMode: RunLoop.Mode.common)
.sink { string in
cell.textLabel.text = string
}
Were the API of this function could be something like this:
extension Publisher {
public func receive(on runLoop: RunLoop, inMode: RunLoop.Mode) -> AnyPublisher<Future.Output, Future.Failure> {
// How to implement this?
}
}
Actually what you've requested is custom
Scheduler, because RunLoop is aSchedulerand running it in specific mode, instead of.default, is just additional configuration of that scheduler.I think that Apple will add such possibility in their
RunLoopscheduler in some of next updates, but for now the following simple custom scheduler that wrapsRunLoopworks for me. Hope it would be helpful for you.Usage:
or
Scheduler code: