Swift/iOS의 MVVM 패턴 샘플
이 모든 애플리케이션 로직은 뷰가 무엇인지 또는 뷰가 무엇을 하는지 결코 알지 못하는 ViewModel 내에 있습니다. 이 아키텍처를 상당히 테스트 가능하게 만들고 보기에서 복잡성을 제거하여 가능한 한 멍청하게 만듭니다.
뷰는 ViewModel을 소유하고 UI 업데이트를 위한 변경 사항을 항상 "수신"합니다. 여기에 유명한 "양방향 데이터 바인딩"이 있습니다. 뷰에 변경 사항이 있으면 모델이 업데이트되고 모델에 변경 사항이 있으면 뷰가 업데이트되며 항상 ViewModel을 매개로 합니다.
글쎄, 우리가 이것을 실제로 본다면 어떨까요? 다음 시나리오를 상상해 보십시오. Github의 나머지 API와 연결하고 리포지토리를 검색하고 그 중 하나를 선택하고 가장 최근 커밋을 볼 수 있는 앱을 개발하려고 합니다. 시작하자!
검색 기능부터 시작하겠습니다. 간결함을 위해 많은 항목을 무시하지만 마지막에 모든 소스 코드를 볼 수 있습니다.
ViewModel을 충족하는 프로토콜을 코딩해 보겠습니다.
protocol SearchRepositoriesDelegate {
func searchResultsDidChanged()
}
protocol SearchViewModelType {
var results: [SearchResult] {get}
var query: String {get set}
var delegate: SearchRepositoriesDelegate? {get set }
}
결과에 대한 속성, 해당 결과를 검색하는 쿼리에 대한 속성 및 변경 사항이 있음을 뷰에 알리는 대리자. 간단하죠?
다른 시나리오에서 'SearchRepositoriesDelegate'는 일부 데이터 바인딩 메커니즘으로 대체되거나 관찰 가능 항목을 구현해야 하지만 이는 다른 게시물에 대한 것입니다.
그러면 ViewModel이 다음과 같은 방식으로 작동합니다.
1- 보기에는 ViewModel에 대한 참조가 있습니다.
2- 사용자가 검색창에 입력하는 동안 뷰는 쿼리를 기반으로 ViewModel의 '쿼리' 속성을 업데이트합니다.
3- 'query' 속성이 업데이트될 때마다 ViewModel은 Github API rest에 요청하고 결과를 업데이트합니다.
4- 서버 응답이 있으면 ViewModel은 결과에 변경 사항이 있음을 뷰에 알립니다(델리게이트를 통해).
5- 'searchResultsDidChanged' 함수가 호출될 때마다 뷰가 UI를 업데이트합니다.
구현 방법을 살펴보겠습니다.
모델 보기:
class SearchViewModel : SearchViewModelType {
var delegate: SearchRepositoriesDelegate?
var results : [SearchResult] = [] {//0 results by default
didSet{
delegate?.searchResultsDidChanged() //notify
}
}
var searchService: SearchService
var query: String = "" {
didSet {
if query == "" {
results = []
}else {
performSearch()
}
}
}
init(service: SearchService) {
self.searchService = service
}
private func performSearch() {
searchService.search(query: self.query)
.onSuccess { results in
self.results = results
}.onFailure { error in
//do nothing
}
}
}
보다:
class SearchViewController: UIViewController {
...
var searchViewModel: SearchViewModelType!
override func viewDidLoad() {
super.viewDidLoad()
searchViewModel.delegate = self
...
}
}
extension SearchViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchViewModel.query = searchText
}
}
extension SearchViewController: SearchRepositoriesDelegate {
func searchResultsDidChanged() {
self.tableView.reloadData()
}
}
...
사용자가 검색 창에 입력하는 동안 'query' 속성이 업데이트되고 ViewModel이 서버 측에 요청합니다. 요청이 완료되면 뷰에 알리고 UI의 변경 사항을 반영하기 위해 UITableView 'reloadData()' 함수를 호출합니다. 보시다시피, SearchViewModel 클래스는 제대로 작동하는지 확인하기 위해 모의 'SearchService' 객체를 생성하기만 하면 되므로 테스트하기가 매우 쉽습니다. ViewModel에는 뷰에 대한 참조가 없으며 뷰는 모든 비즈니스 로직에서 제외됩니다.
그게 다야! 두려워하지 말고 this link의 모든 소스 코드를 보고 질문에 대해 의견을 말하십시오.
Reference
이 문제에 관하여(Swift/iOS의 MVVM 패턴 샘플), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/eleazar0425/mvvm-pattern-sample-in-swiftios--58aj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)