How to search through a publication? #34
-
Any documentation on how to use search? |
Beta Was this translation helpful? Give feedback.
Replies: 0 comments 1 reply
-
You can read a specification of how the search feature works in Readium with this proposal: https://readium.org/architecture/proposals/007-search-service For the Swift implementation, first know that this feature is currently experimental, so any API starting with an underscore may change a bit in the future.
Note that you can provide advanced search options to More infos in this issue: https://github.com/readium/r2-testapp-swift/issues/386 Here's an implementation of a view model to get you started: final class SearchViewModel {
enum State {
// Empty state / waiting for a search query
case empty
// Starting a new search, after calling `cancellable = publication.search(...)`
case starting(Cancellable)
// Waiting state after receiving a SearchIterator and waiting for a next() call
case idle(SearchIterator)
// Loading the next page of result
case loadingNext(SearchIterator, Cancellable)
// We reached the end of the search results
case end
// An error occurred, we need to show it to the user
case failure(LocalizedError)
}
@Published private(set) var state: State = .empty
@Published private(set) var results: [Locator] = []
private var publication: Publication
init(publication: Publication) {
self.publication = publication
}
/// Starts a new search with the given query.
func search(with query: String) {
cancelSearch()
let cancellable = publication._search(query: query) { result in
switch result {
case .success(let iterator):
self.state = .idle(iterator)
self.loadNextPage()
case .failure(let error):
self.state = .failure(error)
}
}
state = .starting(cancellable)
}
/// Loads the next page of search results.
/// Typically, this would be called when the user scrolls towards the end of the results table view.
func loadNextPage() {
guard case .idle(let iterator) = state else {
return
}
let cancellable = iterator.next { result in
switch result {
case .success(let collection):
if let collection = collection {
self.results.append(contentsOf: collection.locators)
self.state = .idle(iterator)
} else {
self.state = .end
}
case .failure(let error):
self.state = .failure(error)
}
}
state = .loadingNext(iterator, cancellable)
}
/// Cancels any on-going search and clears the results.
func cancelSearch() {
switch state {
case .idle(let iterator):
iterator.close()
case .loadingNext(let iterator, let cancellable):
iterator.close()
cancellable.cancel()
default:
break
}
results.removeAll()
state = .empty
}
} |
Beta Was this translation helpful? Give feedback.
You can read a specification of how the search feature works in Readium with this proposal: https://readium.org/architecture/proposals/007-search-service
For the Swift implementation, first know that this feature is currently experimental, so any API starting with an underscore may change a bit in the future.
Publication
supports search withpublication._isSearchable
publication._search(query: "banana") { result in ... }
SearchIterator
object you can use to iterate over the pages of results._search()
returns aCancellable
…