2017-09-26 13 views
0

다음 코드로 RxSwift에 완료 이벤트를 점점 여부를 작동 :이 RxMoya

let provider = RxMoyaProvider<MyAPI>(stubClosure: MoyaProvider.delayedStub(3)) 

    provider 
     .request(.studentSearch(query: "")) 
     .retry(3) 
     .observeOn(MainScheduler.instance) 
     .asObservable() 
     .mapJSON() 
     .map { respJSON in 
      guard let studentsJsonArray = JSON(respJSON)["students"].array else { 
       throw APIError.wrongJSONParsing 
      } 
      return studentsJsonArray.map { 
       guard let students = Student.fromJSON($0) else { 
        fatalError("Invalid Student Object") 
       } 
       return students 
       } as [Student] 
     } 
     .subscribe(onNext: { 
      print($0) 
     }, onCompleted: { 
      print($0) // This one is being called. 
     }) 
     .disposed(by: rx.disposeBag) 

onCompleted이 아닌 다음과 같은 일에 위의 코드에서 호출되는 방법.

콘텐츠 새로 고침을 위해 UITableView에서 새로 고침 트리거를 사용하여이 작업을 수행하려고합니다. 나는 내 ViewModel에

let results: Driver<[Student]> 
var refreshTrigger = PublishSubject<Void>() 
results = refreshTrigger 
     .startWith(()) 
     .do(onNext: { 
      execute.value = true 
     }) 
     .flatMapLatest { 
      provider 
       .request(.studentSearch(query: "")) 
       .retry(3) 
       .observeOn(MainScheduler.instance) 
       .asObservable() 
     } 
     .mapJSON() 
     .map { respJSON in 
      guard let studentsJsonArray = JSON(respJSON)["students"].array else { 
       throw APIError.wrongJSONParsing 
      } 
      return studentsJsonArray.map { 
       guard let students = Student.fromJSON($0) else { 
        fatalError("Invalid Student Object") 
       } 
       return students 
      } 
     } 
     .do(onNext: { 
      items.value = $0 
      execute.value = false 
      noResults.value = items.value.isEmpty 
     }, onCompleted: { 
      print($0) 
     }) 
     .asDriver(onErrorJustReturn: []) 

에 내가있는 viewDidLoad에서 다음 호출 컨트롤러에 다음 코드 startWith(())을 사용할 수 있도록 시작에 내용을로드 할.

viewModel 
     .results 
     .asObservable() 
     .map { StudentGroup(header: "Follower", items: $0) } 
     .subscribe(onNext: { 
      print($0) 
     }, onCompleted: { 
      print($0) // This is not being called. 
     }) 
     .disposed(by: rx.disposeBag) 

여기에 onCompleted가 호출되지 않습니다. 왜 그런지 모르겠다 고? 제발 도와주세요.

답변

0

flatMapLatest는 입력 (사용자의 경우 PublishSubject)이 완료되지 않으면 onCompleted 이벤트를 보내지 않습니다. Moya 요청은 자체적으로 onCompleted 이벤트를 전송하지만 flatMapLatest가 결과를 병합하면 필터링됩니다. 즉, 완료되지 않은 PublishSubject에서 데이터 소스에 대한 장기 가입이 있고 그 중 하나이기도합니다. (그렇지 않으면 첫 번째로드 이후 새로 고침 기능이 손실됩니다.)

나는 RxSwift Slack 채널에서 Zsolt Varadi의 도움을 받았다. 여기

솔루션

results = refreshTrigger 
     .startWith(()) 
     .do(onNext: { 
      execute.value = true 
     }) 
     .flatMapLatest { 
      provider 
       .request(.studentSearch(query: "")) 
       .retry(3) 
       .observeOn(MainScheduler.instance) 
       .asObservable() 
       .mapJSON() 
       .map { respJSON in 
        guard let studentsJsonArray = JSON(respJSON)["students"].array else { 
         throw APIError.wrongJSONParsing 
        } 
        return studentsJsonArray.map { 
         guard let students = Student.fromJSON($0) else { 
          fatalError("Invalid Student Object") 
         } 
         return students 
         } as [Student] 
       } 
       .map { StudentGroup(header: "Follower", items: $0) } 
       .toArray() 
       .catchErrorJustReturn([]) 
       .do(onNext: { 
        studentGroups.value = $0 
        execute.value = false 
        guard let isEmpty = studentGroups.value.first?.items.isEmpty else { 
         return 
        } 
        noResults.value = isEmpty 
       }) 
     } 
     .asDriver(onErrorJustReturn: []) 
입니다