} var output: OutputWrapper<SearchAPIStream.Output> { get } } class SearchAPIStream: UnioStream<SearchAPIStream.Logic>, SearchAPIStreamType { struct Input: InputType { let execute = PublishRelay<String>() } struct Output: OutputType { let response: Observable<[Repository]> let error: Observable<Error> } struct Extra: ExtraType { let session = URLSession.shared let decoder = JSONDecoder() } struct Logic: LogicType { func bind(from dependency: Dependency<Input, NoState, Extra>) -> Output { let extra = dependency.extra let result = dependency.inputObservable(for: \.execute) .flatMapLatest { query -> Observable<Event<[Repository]>> in let request = URLRequest(url: URL(string: "https://◦◦?q=\(query)")!) return extra.session.rx.data(request: request) .take(1) .map { try extra.decoder.decode([Repository].self, from:$0) } .materialize() } .share() return Output(response: result.flatMap { $0.element.map(Observable.just) ?? .empty() }, error: result.flatMap { $0.error.map(Observable.just) ?? .empty() }) } } } protocol SearchAPIActionType { var response: Observable<[Repository]> { get } var error: Observable<Error> { get } func execute(_ text: String) } *OQVUͱ0VUQVUͷΈΛఆٛ͠ .PDLԽͰ͖ΔΑ͏ʹ͢Δ