[Swift project] ReactorKit 예제 : Github Search (ViewController 부분)

김영민·2022년 5월 12일
0

지난 게시물에 이어서 ReactorKit 예제 Github Search의 ViewController 부분에 대해 설명하겠습니다.

Bind

1. searchController -> reactor

        searchController.searchBar.rx.text
            .throttle(.milliseconds(300), scheduler: MainScheduler.instance)
            .map {Reactor.Action.updateQuery($0)}
            .bind(to: reactor.action)
            .disposed(by: disposeBag)
   
  • searchController의 searchBar에 적은 글자를 Reactor.Action.updateQuery() 로 바인딩.
  • throttle(for:scheduler:latest:) : 타이머를 지정해두고 이벤트가 처음 방출되면 타이머 동안 어떤 이벤트도 방출되지 않음.
    • 300 milliseconds마다 텍스트를 받아옴

2. tableView -> reactor

  
       tableView.rx.contentOffset
           .filter{ [weak self] offset in
               guard let self = self else { return false }
               guard self.tableView.frame.height > 0 else { return false }
               return offset.y + self.tableView.frame.height >= self.tableView.contentSize.height - 100
             } //사용자가 더 많은 정보를 원한다면
             .map { _ in Reactor.Action.loadNextPage }
             .bind(to: reactor.action)
             .disposed(by: disposeBag)
  • filter 내부의 코드 내용 : 사용자가 스크롤을 하며 위로 올렸을 때의 기준을 정해놓고, 그 기준을 넘어서면 다음 Operator인 map을 통해 loadNextPage로 바인딩.

3. reactor -> tableView

reactor.state.map { $0.repos }
          .bind(to: tableView.rx.items(cellIdentifier: "cell")) { indexPath, repo, cell in
              cell.textLabel?.text = repo.full_name 
          }
          .disposed(by: disposeBag)
  • reactor의 state를 tableView에 바인딩해주는 작업


    4. tableView cell item 선택 구현

       tableView.rx.itemSelected
               .subscribe(onNext: {[weak self, weak reactor] indexpath in
                   guard let self = self else { return }
                   self.view.endEditing(true)
                   self.tableView.deselectRow(at: indexpath, animated: false)
                   guard let repo = reactor?.currentState.repos[indexpath.row] else {return}
    
                   guard let url = URL(string: "https://github.com/\(repo.full_name)") else { return }
                   
                   let viewController = SFSafariViewController(url: url)
                   self.searchController.present(viewController, animated: true, completion: nil)
               })
               .disposed(by: disposeBag)
           
  • cell 선택 시 해당하는 github의 repository로 이동

  • SafariServices 라이브러리를 통해 웹 페이지 열기


마치며...

이렇게 간단하게 bind 부분을 요약해보았습니다.
확실히 정리해서 다시 보니 모르고 넘겼던 부분도 다시 보게 되고 한 눈에 코드들이 보여서
나중에 다시 공부할 때 보기 좋을 것 같습니다.

전체 코드

https://github.com/youngmin5068/GithubSearch_reactorkit

0개의 댓글