Firestore를 통한 비동기적 사용자 데이터 로딩
Firestore 데이터베이스에서 사용자 데이터를 비동기적으로 가져오는 역할을 한다. 이 메서드는 완료 핸들러를 파라미터로 받아 데이터베이스에서 데이터를 성공적으로 로드한 후 필요한 동작을 실행할 수 있게 해준다.
// UserService.swift
static func fetchUsers(completion: @escaping([User]) -> Void) {
COLLECTION_USERS.getDocuments { snapshot, error in
guard let snapshot = snapshot else { return }
let users = snapshot.documents.map({ User(dictionary: $0.data()) })
completion(users)
}
}
Swift
복사
•
타입 메서드(static)로 정의함으로써 UserService의 인스턴스를 생성하지 않고도 호출할 수 있다.
•
COLLECTION_USERS.getDocuments는 Firestore에서 ‘users’ 컬렉션의 모든 문서를 가져오는 비동기적으로 가져온다.
•
guard let 구문을 사용하여 snapshot 객체가 nil인 경우 함수를 더 이상 진행하지 않고 종료한다. 이는 데이터가 없거나 조회에 실패했을 때의 안전한 처리를 위함이다.
•
snapshot.documents.map을 사용하여 각 문서를 User 모델 객체로 변환한다. 여기서 User(dictionary: $0.data())는 Firestore 문서의 데이터를 이용하여 User 객체를 초기화한다.
•
completion(users)는 변환된 사용자 배열을 완료 핸들러를 통해 반환한다. 이를 통해 함수를 호출한 곳에서 사용자 데이터를 사용할 수 있게 된다.
다음 코드는 UserService를 통해 사용자 데이터를 가져오고 UI를 업데이트한다.
// SearchController.swift
func fetchUsers() {
UserService.fetchUsers { users in
self.users = users
self.tableView.reloadData()
}
}
Swift
복사
fetchUsers 메서드는 UserService를 통해 사용자 데이터를 비동기적으로 가져온다. 이 과정에서 몇 가지 주요 단계를 거친다.
•
데이터 로딩 시작: fetchUsers는 네트워크를 통해 사용자 데이터를 요청한다. 이때 users 배열은 초기 상태에서 빈 배열로 시작된다.
•
데이터 로딩 완료: 비동기적으로 데이터가 로딩 완료되면 이 데이터는 users 배열에 저장된다. 배열은 비어 있던 상태에서 새로운 사용자 정보로 채워진다.
•
UI 업데이트: 데이터가 users 배열에 성공적으로 저장되면 reloadData를 통해 UI를 최신 상태로 갱신해야 한다.
◦
reloadData 메서드는 UITableView에게 데이터 소스를 다시 읽고 테이블 뷰를 전체적으로 새로 그리라고 지시한다. 이 호출이 없으면 테이블 뷰는 여전히 이전 상태를 유지하거나 빈 상태가 될 수 있다.
다음 코드는 가져온 데이터를 UI에 표시한다.
extension SearchController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: reuseIdentifier,
for: indexPath
) as! UserCell
cell.viewModel = UserCellViewModel(user: users[indexPath.row])
return cell
}
}
Swift
복사
fetchUsers를 통해 가져온 데이터를 users 배열에 저장하면 이 users 배열의 길이를 반환함으로써 테이블 뷰에 표시할 셀의 수를 결정한다. 그리고 UserCell을 재사용 큐에서 가져온 후 해당 인덱스의 사용자 데이터를 뷰 모델을 통해 셀에 바인딩한다.
var viewModel: UserCellViewModel? {
didSet {
configure()
}
}
Swift
복사
didSet 옵저버를 통해 viewModel의 값이 설정될 때마다 configure 메서드가 호출된다. 이는 셀의 뷰가 뷰 모델의 최신 상태를 반영하도록 보장한다.
func configure() {
guard let viewModel = viewModel else { return }
profileImageView.sd_setImage(with: viewModel.profileImageURL)
usernameLabel.text = viewModel.username
fullnameLabel.text = viewModel.fullname
}
Swift
복사
viewModel에서 사용자 데이터를 가져와 셀의 각 UI 컴포넌트에 적용한다. 프로필 이미지는 SDWebImage 라이브러리를 통해 비동기적으로 로드된다.