QuickBirdEng / XCoordinator

🎌 Powerful navigation library for iOS based on the coordinator pattern
MIT License
2.26k stars 177 forks source link

RxSwift 6 compatibility #197

Closed pzmudzinski closed 2 years ago

pzmudzinski commented 3 years ago

It seems XCoordinator/RxSwift extension is broken with latest release of RxSwift:

 XCoordinator/RxSwift (~> 2.0) was resolved to 2.0.7, which depends on
      RxSwift (~> 5.0)

Also code of extension doesn't seem to be compile with latest version of RxSwift (I've just tried to copy-paste it to my project):

extension Router {

    /// Use this to access the reactive extensions of `Router` objects.
    public var rx: Reactive<Self> {
        // swiftlint:disable:previous identifier_name
        Reactive(self)
    }
}

Error message: 'Reactive' requires that 'Self' be a class type

I am setting new project with RxSwift and wanted to try XCoordinator as API seem to be well designed but it kind of blocks me. Any idea how to fix it?

pauljohanneskraft commented 3 years ago

Hey @pzmudzinski, RxSwift 6 compatibility will come with one of the next releases of XCoordinator. Thanks for the notification! Now to the specific problem here at hand: What you could try is the following:

extension Router where Self: AnyObject {

    /// Use this to access the reactive extensions of `Router` objects.
    public var rx: Reactive<Self> {
        // swiftlint:disable:previous identifier_name
        Reactive(self)
    }
}

With this change, you ensure that the new requirement is met - However, I cannot say that everything will work the same as before, since I'm not familiar with all the source-breaking changes of RxSwift 6 and it might break the rx-extension for all the pure Router types, i.e. StrongRouter, WeakRouter and UnownedRouter, since they are structs not classes...

pzmudzinski commented 3 years ago

Yeah, it breaks with router subtypes. I have no idea how to add rx property to them. As a total workaround I used this code:

extension Router {

    public func rxTrigger(_ route: RouteType, with options: TransitionOptions) -> Observable<Void> {
        Observable.create { [self] observer -> Disposable in
            self.trigger(route, with: options) {
                observer.onNext(())
                observer.onCompleted()
            }
            return Disposables.create()
        }
    }

    public func rxTrigger(_ route: RouteType) -> Observable<Void> {
        rxTrigger(route, with: TransitionOptions(animated: true))
    }
}
pauljohanneskraft commented 3 years ago

An alternative solution that would keep the same API is recreating the existing Reactive type in XCoordinator without the constraint to AnyObject.

The code would be the following:

public struct Reactive<Base> {
    public private(set) var base: Base

    public init(_ base: Base) {
        self.base = base
    }
}

extension Router {
    public var rx: Reactive<Self> {
        Reactive(self)
    }
}

The extensions to Reactive would stay exactly the same and users would not need to change any code themselves.

Of course, we would break the existing consistency of reusing the Reactive type of RxSwift, but a user could still use module prefixes to access the different types RxSwift.Reactive or XCoordinatorRx.Reactive.

xxbic commented 3 years ago

Any news about RxSwift 6 compatibility?

pauljohanneskraft commented 3 years ago

Hey @xxbic - I'm working on it!

You can find the current development here: https://github.com/quickbirdstudios/XCoordinator/pull/203

Apparently, the above-mentioned issue has been fixed by RxSwift - or at least I have not yet run into it.

ab-zephyr commented 3 years ago

@pauljohanneskraft rxswift6 branch still has dependency on RxSwift 5 in podspec

pauljohanneskraft commented 3 years ago

@ab-zephyr Thanks for mentioning - I just adapted it.

vvit commented 3 years ago

@pauljohanneskraft thanks for your work, any plans to merge rxswift6 branch into master?

Wh1rlw1nd commented 3 years ago

@ab-zephyr @pauljohanneskraft Any info about when RxSwift 6 will be supported?

pauljohanneskraft commented 2 years ago

Yes, there is news! There will be a 2.1.0 release in the very near future!