Skip to content

Commit

Permalink
Merge #410
Browse files Browse the repository at this point in the history
410: Add async overload for search API r=curquiza a=Sherlouk

# Pull Request

⚠️ I've marked this as draft as it current works to provide an example of how we could add async/await support to the library. I am more than happy to expand this to **all** currently supported APIs.

## Related issue

Relates to #332 (doesn't close as only adds support for one API)

## What does this PR do?
- Adds an async/await override to an existing search API providing users with more choice.

## PR checklist
Please check if your PR fulfills the following requirements:
- [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
- [x] Have you read the contributing guidelines?
- [x] Have you made sure that the title is accurate and descriptive of the changes?

Thank you so much for contributing to Meilisearch!


Co-authored-by: James Sherlock <[email protected]>
  • Loading branch information
meili-bors[bot] and Sherlouk authored Sep 28, 2023
2 parents 33d66ff + 338faad commit 1d68308
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 18 deletions.
25 changes: 8 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,24 +149,13 @@ With the `uid` of the task, you can check the status (`enqueued`, `canceled`, `p
#### Basic Search <!-- omit in toc -->

```swift

let semaphore = DispatchSemaphore(value: 0)

// Typealias that represents the result from Meilisearch.
typealias MeiliResult = Result<SearchResult<Movie>, Swift.Error>

// Call the function search and wait for the closure result.
client.index("movies").search(SearchParameters( query: "philoudelphia" )) { (result: MeiliResult) in
switch result {
case .success(let searchResult):
dump(searchResult)
case .failure(let error):
print(error.localizedDescription)
}
semaphore.signal()
do {
// Call the search function and wait for the result.
let result: SearchResult<Movie> = try await client.index("movies").search(SearchParameters(query: "philoudelphia"))
dump(result)
} catch {
print(error.localizedDescription)
}
semaphore.wait()

```

Output:
Expand All @@ -191,6 +180,8 @@ Output:

Since Meilisearch is typo-tolerant, the movie `philadelphia` is a valid search response to `philoudelphia`.

> Note: All package APIs support closure-based results for backwards compatibility. Newer async/await variants are being added under [issue 332](https://github.com/meilisearch/meilisearch-swift/issues/332).
## 🤖 Compatibility with Meilisearch

This package guarantees compatibility with [version v1.x of Meilisearch](https://github.com/meilisearch/meilisearch/releases/latest), but some features may not be present. Please check the [issues](https://github.com/meilisearch/meilisearch-swift/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22+label%3Aenhancement) for more info.
Expand Down
19 changes: 19 additions & 0 deletions Sources/MeiliSearch/Async/Indexes+async.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Foundation

@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
extension Indexes {
/**
Search in the index.

- Parameter searchParameters: Options on search.
- Throws: Error if a failure occurred.
- Returns: On completion if the request was successful a `Searchable<T>` instance is returned containing the values.
*/
public func search<T: Codable & Equatable>(_ searchParameters: SearchParameters) async throws -> Searchable<T> {
try await withCheckedThrowingContinuation { continuation in
self.search.search(self.uid, searchParameters) { result in
continuation.resume(with: result)
}
}
}
}
2 changes: 1 addition & 1 deletion Sources/MeiliSearch/Indexes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public struct Indexes {
private let documents: Documents

// Search methods
private let search: Search
internal let search: Search

// Settings methods
private let settings: Settings
Expand Down
40 changes: 40 additions & 0 deletions Tests/MeiliSearchUnitTests/SearchTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,46 @@ class SearchTests: XCTestCase {

self.wait(for: [expectation], timeout: TESTS_TIME_OUT)
}

Check warning on line 83 in Tests/MeiliSearchUnitTests/SearchTests.swift

View workflow job for this annotation

GitHub Actions / linter-check

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)

Check warning on line 83 in Tests/MeiliSearchUnitTests/SearchTests.swift

View workflow job for this annotation

GitHub Actions / linter-check

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
func testSearchForBotmanMovieAsync() async throws {
let jsonString = """
{
"hits": [
{
"id": 29751,
"title": "Batman Unmasked: The Psychology of the Dark Knight",
"poster": "https://image.tmdb.org/t/p/w1280/jjHu128XLARc2k4cJrblAvZe0HE.jpg",
"overview": "Delve into the world of Batman and the vigilante justice tha",
"release_date": "2020-04-04T19:59:49.259572Z"
},
{
"id": 471474,
"title": "Batman: Gotham by Gaslight",
"poster": "https://image.tmdb.org/t/p/w1280/7souLi5zqQCnpZVghaXv0Wowi0y.jpg",
"overview": "ve Victorian Age Gotham City, Batman begins his war on crime",
"release_date": "2020-04-04T19:59:49.259572Z"
}
],
"offset": 0,
"limit": 20,
"processingTimeMs": 2,
"estimatedTotalHits": 2,
"query": "botman"
}
"""

Check warning on line 111 in Tests/MeiliSearchUnitTests/SearchTests.swift

View workflow job for this annotation

GitHub Actions / linter-check

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)

Check warning on line 111 in Tests/MeiliSearchUnitTests/SearchTests.swift

View workflow job for this annotation

GitHub Actions / linter-check

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
// Prepare the mock server
let data = jsonString.data(using: .utf8)!
let stubSearchResult: Searchable<Movie> = try! Constants.customJSONDecoder.decode(Searchable<Movie>.self, from: data)
session.pushData(jsonString)

Check warning on line 116 in Tests/MeiliSearchUnitTests/SearchTests.swift

View workflow job for this annotation

GitHub Actions / linter-check

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)

Check warning on line 116 in Tests/MeiliSearchUnitTests/SearchTests.swift

View workflow job for this annotation

GitHub Actions / linter-check

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
// Start the test with the mocked server
let searchParameters = SearchParameters.query("botman")

Check warning on line 119 in Tests/MeiliSearchUnitTests/SearchTests.swift

View workflow job for this annotation

GitHub Actions / linter-check

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)

Check warning on line 119 in Tests/MeiliSearchUnitTests/SearchTests.swift

View workflow job for this annotation

GitHub Actions / linter-check

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
let searchResult: Searchable<Movie> = try await self.index.search(searchParameters)
XCTAssertEqual(stubSearchResult, searchResult)
}

func testSearchForBotmanMovieFacets() {
let jsonString = """
Expand Down

0 comments on commit 1d68308

Please sign in to comment.