๐ด Let's Build UBER with SwiftUI | iOS 16 & Xcode 14
UberClone: Location Search Logic
๊ตฌํ ๋ชฉํ
- ์ฟผ๋ฆฌ ํ
์คํธ๋ฅผ ํตํด ์ง์ญ ๊ฒ์
๊ตฌํ ํ์คํฌ
- ๊ฒ์ ์ฟผ๋ฆฌ ํ
์คํธ๋ฅผ ๋ด๋นํ๋ ๋ทฐ ๋ชจ๋ธ
- ํ
์คํธ๋ฅผ ํตํด ์ค์๊ฐ์ผ๋ก ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ
ํต์ฌ ์ฝ๋
import Foundation
import MapKit
import Combine
class LocationSearchViewModel: NSObject, ObservableObject {
@Published var results = [MKLocalSearchCompletion]()
private let searchCompleter = MKLocalSearchCompleter()
@Published var queryFragment: String = ""
private var cancellables = Set<AnyCancellable>()
override init() {
super.init()
searchCompleter.delegate = self
bind()
}
private func bind() {
$queryFragment
.debounce(for: .seconds(0.5), scheduler: RunLoop.main)
.sink { [weak self] query in
self?.searchCompleter.queryFragment = query
}
.store(in: &cancellables)
}
}
extension LocationSearchViewModel: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
results = completer.results
}
}
ObseravleObject
๋ก ์ ์ธํ ๋ทฐ ๋ชจ๋ธ
- ํด๋น ๋ทฐ์์
@StateObject
๋ก ๋ฐ์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ ๋ณํ ํฌ์ฐฉ ๊ฐ๋ฅ
- ๋ทฐ ํ
์คํธ ํ๋์ ํ์ฌ ์ค์๊ฐ ํ
์คํธ๋ฅผ
queryFragment
์ ์ฐ๋ โ ์ปด๋ฐ์ธ์ debounce
๋ฅผ ํตํด 0.5 ์ด ๋์ ์ธํ์ด ์์ ๋ sink
ํ๋จ์ผ๋ก ๋ฐ์ดํฐ๊ฐ ํ๋ฌ๊ฐ๋๋ก ๊ตฌ์กฐํ
MKLocalSearchCompleter
์ ๋ธ๋ฆฌ๊ฒ์ดํธ ํจ์ completerDidUpdateResults
๋ฅผ ํตํด ์ฟผ๋ฆฌ ๊ฒ์์ ํตํ ๊ฒฐ๊ณผ๋ฅผ ๊ณง๋ฐ๋ก ์
๋ฐ์ดํธ ๊ฐ๋ฅ
@StateObject private var viewModel = LocationSearchViewModel()
...
TextField("Where to?", text: $viewModel.queryFragment, axis: .vertical)
.frame(minHeight: 32)
.background(Color(.systemGray4))
.padding(.trailing)
- ๋์ฐฉ์ง๋ฅผ ๋ฌผ์ด๋ณด๋ ๊ฒ์ ๊ฒฐ๊ณผ ๋ทฐ์ ํ
์คํธ ํ๋์ ๋ฐ์ดํฐ ์์ค๋ฅผ ํด๋น ๋ทฐ ๋ชจ๋ธ์ ์ฟผ๋ฆฌ ํ
์คํธ์ ๋ฐ์ธ๋ฉ
๊ตฌํ ํ๋ฉด