Home > Enterprise >  Understanding generics and how
Understanding generics and how

Time:11-26

I'm new to a company and trying to understand the used generics. The setup of a model contains

var selectedChannel: Driver<Channel> { get }

@available(*, deprecated, message: "Use driver selectedChannel")
var selectedChannelValue: Channel { get }

At some point in the code selectedChannelValue.id is used, but it shows up the warning message Use driver selectedChannel. I understand this. Okay it still does the job but one of the previous programmers deprecated this for a reason.

How to rewrite the code-line so that I get selectedChannel.id as the deprecation message suggests? When I use selectedChannel.id the error message Value of type 'Driver<Channel>' (aka 'SharedSequence<DriverSharingStrategy, Channel>') has no member 'id' appears. How to unwrap the SharedSequence?

EDIT: The channel struct looks like this:

public struct Channel: Codable {
    public let id: String    // e.g. "1111111"

The driver is setup in RxCocoa as:

public typealias Driver<Element> = SharedSequence<DriverSharingStrategy, Element>

public struct DriverSharingStrategy: SharingStrategyProtocol {
    public static var scheduler: SchedulerType { return SharingScheduler.make() }
    public static func share<Element>(_ source: Observable<Element>) -> Observable<Element> {
        return source.share(replay: 1, scope: .whileConnected)
    }
}
extension SharedSequenceConvertibleType where SharingStrategy == DriverSharingStrategy {
    /// Adds `asDriver` to `SharingSequence` with `DriverSharingStrategy`.
    public func asDriver() -> Driver<Element> {
        return self.asSharedSequence()
    }
}

CodePudding user response:

By wrapping the Channel in a Driver, the code is telling you that it is asynchronous. So it might not yet exist when you query it, and it might change while you are observing it. You observe it with the drive method:

selectedChannel
    .drive(onNext: { channel in
        // you can use channel.id here.
    })
    .disposed(by: disposeBag)

But you can't just save that id in some var outside of the closure and expect everything to be okay. The code that needs the id will have to also been that closure (or in a function that is called from that closure.)

Note that you will likely need to create a dispose bag in the class that this code is in as well.

The Driver is a kind of Observable. You should read up on how to use these constructs, but for these purposes, you can think of it kind of like a callback closure encapsulated in an object.

  • Related