10.3 C
New York
Friday, October 18, 2024

ios – Making use of Debounce in SwiftUI Search Bar


I wish to apply debounce or delay into search bar and permit person few milliseconds to sort the textual content and do the filtering knowledge based mostly on the search textual content person into search bar . I’ve tried under code into searchResults accomplished property however actually not permitting me to do it.

DispatchQueue.important.asyncAfter(deadline: .now() + 0.5)

What’s the various option to obtain it ?

Right here is my view mannequin code …

import Basis

enum ViewState {
  case loading
  case error
  case loaded
  case emptyView
}

protocol PeopleListViewModelAction: ObservableObject {
  func getPeopleList(urlStr: String) async
}

// MARK: - Individuals Listing ViewModel Implementation.
@MainActor
last class PeopleListViewModel {
  
  @Printed personal(set) var viewState: ViewState = .loaded
  @Printed  var searchText = ""
  personal(set)  var filteredPeople: [PeopleData] = []
  personal(set) var peopleLists: [PeopleData] = []
  personal let repository: PeopleCardsRepository
  
  init(repository: PeopleCardsRepository) {
    self.repository = repository
  }
}

extension PeopleListViewModel: PeopleListViewModelAction {
  
  func getPeopleList(urlStr: String) async {
    viewState = .loaded
    guard let url = URL(string: urlStr) else { return }
    do {
      let lists = attempt await repository.getPeopleList(for: url)
      peopleLists = lists
      viewState =  peopleLists.isEmpty ? .emptyView : .loaded
    } catch {
      viewState = .error
    }
  }
}

extension PeopleListViewModel {
  
  var searchResults: [PeopleData] {
      guard !searchText.isEmpty else { return peopleLists }
      return peopleLists.filter { $0.firstName.localizedStandardContains(searchText) }
  }
}

Right here is my view code …

import SwiftUI

struct PeopleListView: View {
  // MARK: - Utilizing State Object to ensure view mannequin object is not going to destroyed or recreate.
  @StateObject var viewModel: PeopleListViewModel
  @State personal var isErrorOccured = true
  
  var physique: some View {
    NavigationStack {
      VStack {
        swap viewModel.viewState {
        case .loading:
          ProgressView()
        case .loaded:
          showPeopleListView()
        case .error:
          showErrorView()
        case .emptyView:
          EmptyView()
        }
      }
      .navigationTitle(Textual content(LocalizedStringKey("Individuals Listing")))
      .searchable(textual content: $viewModel.searchText, immediate: "Please enter identify..")
    }.process {
      await viewModel.getPeopleList(urlStr: Endpoint.peopleListURL)
    }
  }
  
  @ViewBuilder
  func showPeopleListView() -> some View {
    Listing(viewModel.searchResults) { peopleList in
      NavigationLink {
        PeopleDetailsView(folks: peopleList)
      }label: {
        PeopleCellView(folks: peopleList)
      }
    }
  }
  
  @ViewBuilder
  func showErrorView() -> some View {
    ProgressView().alert(isPresented: $isErrorOccured) {
      Alert(title: Textual content("Error Occured"),message: Textual content("One thing went incorrect"),
            dismissButton: .default(Textual content("Okay")))
    }
  }
}

#Preview {
  PeopleListView(viewModel: PeopleListViewModel(repository: PeopleRepositoryImplementation(networkManager: NetworkManager())))
}

Right here is the screenshot of the error ..

enter picture description right here

Right here is the screenshot of the app ..

enter picture description right here

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles