迅速。公共协议中的内部类型

时间:2018-04-17 15:49:52

标签: ios swift generics swift-protocols associated-types

我正在尝试使用快速的仿制药,但我被卡住了...... 这样做可能是不可能的,但我希望有人会有一个很好的建议。

所以我有这个协议和一种我想要内部的类型:

internal protocol ATCoreInstrumentProtocol { // SOME STUFF }
internal typealias AT_1G_WaveInstrumentType = //Somethings that conforms to ATCoreInstrumentProtocol

然后我有这个我希望公开的InstrumentType。 这里的问题是ASSOCIATED_INSTRUMENT又名ATCoreInstrumentProtocol 需要internal,因此我无法以这种方式使用它。 没有选项让ATCoreInstrumentProtocol公开。

public protocol InstrumentType {
  static var instrumentType: SupportedInstrumentTypes { get }
  associatedtype ASSOCIATED_INSTRUMENT: ATCoreInstrumentProtocol
}

public final class InstrumentTypes {
  private init() {}

  public final class AT_1G_Wave : InstrumentType {
      public class var instrumentType: SupportedInstrumentTypes { get { return .wave_1G } }
      public typealias ASSOCIATED_INSTRUMENT = AT_1G_WaveInstrumentType
  }
}

这就是我想要的方式。

internal class ATCoreInteractor<IT: InstrumentType> {

  internal var instrumentObservable : Observable<IT.ASSOCIATED_INSTRUMENT> {
      return self.instrumentSubject.asObservable()
  }

  private var instrumentSubject = ReplaySubject<IT.ASSOCIATED_INSTRUMENT>.create(bufferSize: 1)

  internal init(withSerial serial: String){
      self.scanDisposable = manager
          .scanFor([IT.instrumentType])
          .get(withSerial: serial)
          .take(1)
          .do(onNext: { (inst) in
              self.instrumentSubject.onNext(inst)
          })
          .subscribe()
}

然后我有ATSyncInteractor public

public final class ATSyncInteractor<IT : InstrumentType> : ATCoreInteractor<IT> {
  public override init(withSerial serial: String) {
      super.init(withSerial: serial)
  }
}

public extension ATSyncInteractor where IT : InstrumentTypes.AT_1G_Wave {
  public func sync(opPriority: BLEOperationPriority = .normal, from: Date, to: Date, callback: @escaping (ATCoreReadyData<AT_1G_Wave_CurrentValues>?, [WaveTimeSeriesCoordinator], Error?) -> Void) {
    // DO SOMETHING
  }
}



let interactor = ATSyncInteractor<InstrumentTypes.AT_1G_Wave>(withSerial: "12345")

1 个答案:

答案 0 :(得分:0)

这最终成了我的解决方案..
InstrumentType仅包含SupportedInstrumentTypes
ATCoreInteractor不再是通用的,但观察者的类型为ATCoreInstrumentProtocol
ATSyncInteractor扩展程序会将工具转换为其关联类型。

我愿意接受改进和建议。

public protocol InstrumentType : class {
    static var instrumentType: SupportedInstrumentTypes { get }
}

public final class InstrumentTypes {
    private init() {}

    public final class AT_1G_Wave : InstrumentType {
        private init() {}
        public class var instrumentType: SupportedInstrumentTypes { get { return .wave_1G } }
    }
}
public class ATCoreInteractor {

    internal var instrumentSubject = ReplaySubject<ATCoreInstrumentProtocol>.create(bufferSize: 1)

    internal init(for type: SupportedInstrumentTypes, withSerial serial: String){

        self.scanDisposable = manager
            .scanFor([type])
            .get(withSerial: serial)
            .take(1)
            .do(onNext: { (inst) in
                self.instrumentSubject.onNext(inst)
            })
            .subscribe()
    }
}
public final class ATSyncInteractor<IT : InstrumentType> : ATCoreInteractor {

    public init(withSerial serial: String) {
        super.init(for: IT.instrumentType, withSerial: serial)

    }
} 

public extension ATSyncInteractor where IT : InstrumentTypes.AT_1G_Wave {

    private func instrument() -> Observable<AT_1G_WaveInstrumentType> {
        return self.instrumentSubject.map { $0 as! AT_1G_WaveInstrumentType }
    }

    public func sync(opPriority: BLEOperationPriority = .normal, from: Date, to: Date, callback: @escaping (ATCoreReadyData<AT_1G_Wave_CurrentValues>?, [WaveTimeSeriesCoordinator], Error?) -> Void) {

    }
}