Search code examples
iosswiftreswift

Declaration 'subscribe' cannot override more than one superclass declaration (ReSwift)


I'm having a problem when overriding a function from the ReSwift Pod. I've got the following mock class:

import Foundation
import Quick
import Nimble
import RxSwift
@testable import MainProject
@testable import ReSwift

    class MockReSwiftStore: ReSwift.Store<MainState> {
    var dispatchDidRun: Bool = false
    var subscribeWasTriggered: Bool = false

    init() {
        let reducer: Reducer<MainState> = {_, _  in MainState() }
        super.init(reducer: reducer, state: nil)
    }

    required init(
        reducer: @escaping (Action, State?) -> State,
        state: State?,
        middleware: [(@escaping DispatchFunction, @escaping () -> State?) -> (@escaping DispatchFunction) -> DispatchFunction]) {
        super.init(reducer: reducer, state: state, middleware: middleware)
    }

    override func subscribe<SelectedState, S>(
        _ subscriber: S,
        transform: ((Subscription<MainState>) -> Subscription<SelectedState>)?)
        where S: StoreSubscriber,

        S.StoreSubscriberStateType == SelectedState {
            subscribeWasTriggered = true
        }
    }
}

And when overriding the subscribe method I'm getting following errors

enter image description here

Then when using autocomplete it also shows 2 occurences: enter image description here

However when looking for the original function there's only one which looks like this

open func subscribe<SelectedState, S: StoreSubscriber>(
    _ subscriber: S, transform: ((Subscription<State>) -> Subscription<SelectedState>)?
) where S.StoreSubscriberStateType == SelectedState
{
    // Create a subscription for the new subscriber.
    let originalSubscription = Subscription<State>()
    // Call the optional transformation closure. This allows callers to modify
    // the subscription, e.g. in order to subselect parts of the store's state.
    let transformedSubscription = transform?(originalSubscription)

    _subscribe(subscriber, originalSubscription: originalSubscription,
               transformedSubscription: transformedSubscription)
}

This is my compiler output enter image description here

I'm out of ideas so any help is greatly appreciated Thanks!


Solution

  • Here is your issue:

    class Some<T> {
    
        func echo() {
            print("A")
        }
    
    }
    
    extension Some where T: Equatable {
    
        func echo() {
            print("B")
        }
    
    }
    
    
    class AnotherSome: Some<String> {
    
        override func echo() {
            print("Doesn't compile")
        }
    
    }
    

    The problem is: ReSwift developers declare Store.subscribe behavior as a part of interface and as a part of extension (I am not sure why they chose to do it instead of introducing other objects). Swift can't figure out which part you are trying to override and thus it doesn't compile. Afaik there are no language instruments which allow you to resolve this issue.

    A possible solution is to implement MockStore as a StoreType and use Store object to implement behavior for StoreType interface.