diff --git a/README.md b/README.md index d622cdc3..f036116c 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ To do a simply search using the client, you can create a Swift script like this: semaphore.wait() ``` -With the `uid` of the task, you can check the status (`enqueued`, `processing`, `succeeded` or `failed`) of your documents addition using the [update endpoint](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status). +With the `uid` of the task, you can check the status (`enqueued`, `processing`, `succeeded` or `failed`) of your documents addition using the [update endpoint](https://docs.meilisearch.com/learn/advanced/asynchronous_operations.html#task-status). #### Basic Search diff --git a/Sources/MeiliSearch/Constants.swift b/Sources/MeiliSearch/Constants.swift index 48162d34..c4851d38 100644 --- a/Sources/MeiliSearch/Constants.swift +++ b/Sources/MeiliSearch/Constants.swift @@ -12,4 +12,19 @@ struct Constants { encoder.dateEncodingStrategy = JSONEncoder.DateEncodingStrategy.formatted(Formatter.iso8601) return encoder }() + + static func resultDecoder(data: Data?) throws -> Result { + guard let data: Data = data else { + return .failure(MeiliSearch.Error.dataNotFound) + } + do { + let task: T = try Constants.customJSONDecoder.decode( + T.self, + from: data) + return .success(task) + } catch { + return .failure(error) + } + } + } diff --git a/Sources/MeiliSearch/Indexes.swift b/Sources/MeiliSearch/Indexes.swift index 558e7b13..b06e2a02 100755 --- a/Sources/MeiliSearch/Indexes.swift +++ b/Sources/MeiliSearch/Indexes.swift @@ -68,8 +68,8 @@ public struct Indexes { Get the index. - parameter completion: The completion closure used to notify when the server - completes the query request, it returns a `Result` object that contains `Index` - value. If the request was sucessful or `Error` if a failure occured. + completes the query request. It returns a `Result` object that contains `Index` + value if the request was successful or `Error` if a failure occurred. */ public func get(_ completion: @escaping (Result) -> Void) { self.request.get(api: "/indexes/\(self.uid)") { result in @@ -98,8 +98,8 @@ public struct Indexes { List all indexes. - parameter completion: The completion closure used to notify when the server - completes the query request, it returns a `Result` object that contains `[Index]` - value. If the request was sucessful or `Error` if a failure occured. + completes the query request. It returns a `Result` object that contains `[Index]` + value if the request was successful or `Error` if a failure occurred. */ public static func getAll(config: Config, _ completion: @escaping (Result<[Index], Swift.Error>) -> Void) { Request(config).get(api: "/indexes") { result in diff --git a/Sources/MeiliSearch/Model/Task.swift b/Sources/MeiliSearch/Model/Task.swift index 5742bf30..80212bcc 100644 --- a/Sources/MeiliSearch/Model/Task.swift +++ b/Sources/MeiliSearch/Model/Task.swift @@ -8,32 +8,32 @@ public struct Task: Codable, Equatable { // MARK: Properties - /// Unique ID for the current `Update`. + /// Unique ID for the current `Task`. public let uid: Int - /// Unique ID for the current `Update`. + /// Unique ID for the current `Task`. public let indexUid: String - /// Returns if the update has been sucessful or not. + /// Returns if the task has been successful or not. public let status: Task.Status - /// Type of update. + /// Type of the task. public let type: String - /// Type of update. + /// Details of the task. public let details: Details? - /// Duration of the update process. + /// Duration of the task process. public let duration: String? - /// Date when the update has been enqueued. + /// Date when the task has been enqueued. public let enqueuedAt: String - /// Date when the update has been processed. + /// Date when the task has been processed. // TODO: should this become a Date type? public let processedAt: String? - /// Type of `Update`. + /// Type of `Task`. public struct Details: Codable, Equatable { // MARK: Properties @@ -68,7 +68,7 @@ public struct Task: Codable, Equatable { // Stop words on settings actions public let stopWords: [String]? - // Stop words on settings actions + // Synonyms on settings actions public let synonyms: [String: [String]]? // Distinct attribute on settings actions diff --git a/Sources/MeiliSearch/Tasks.swift b/Sources/MeiliSearch/Tasks.swift index 818628a0..f5a67026 100644 --- a/Sources/MeiliSearch/Tasks.swift +++ b/Sources/MeiliSearch/Tasks.swift @@ -18,27 +18,7 @@ struct Tasks { func get( taskUid: Int, _ completion: @escaping (Result) -> Void) { - self.request.get(api: "/tasks/\(taskUid)") { result in - switch result { - case .success(let data): - guard let data: Data = data else { - completion(.failure(MeiliSearch.Error.dataNotFound)) - return - } - do { - let task: Task = try Constants.customJSONDecoder.decode( - Task.self, - from: data) - completion(.success(task)) - } catch { - dump(error) - completion(.failure(error)) - } - - case .failure(let error): - completion(.failure(error)) - } - } + get(url: "/tasks/\(taskUid)", completion) } // Get on index @@ -46,64 +26,49 @@ struct Tasks { uid: String, taskUid: Int, _ completion: @escaping (Result) -> Void) { - self.request.get(api: "/indexes/\(uid)/tasks/\(taskUid)") { result in - switch result { - case .success(let data): - guard let data: Data = data else { - completion(.failure(MeiliSearch.Error.dataNotFound)) - return - } - do { - let task: Task = try Constants.customJSONDecoder.decode( - Task.self, - from: data) - completion(.success(task)) - } catch { + get(url: "/indexes/\(uid)/tasks/\(taskUid)", completion) + } + + func get ( + url: String, + _ completion: @escaping (Result) -> Void) { + self.request.get(api: url) { result in + switch result { + case .success(let data): + do { + let task: Result = try Constants.resultDecoder(data: data) + completion(task) + } catch { + completion(.failure(error)) + } + case .failure(let error): completion(.failure(error)) } - - case .failure(let error): - completion(.failure(error)) } } - } // get all on client func getAll( _ completion: @escaping (Result, Swift.Error>) -> Void) { - self.request.get(api: "/tasks") { result in - switch result { - case .success(let data): - guard let data: Data = data else { - completion(.failure(MeiliSearch.Error.dataNotFound)) - return - } - do { - let result: Results = try Constants.customJSONDecoder.decode(Results.self, from: data) - completion(.success(result)) - } catch { - completion(.failure(error)) - } - case .failure(let error): - completion(.failure(error)) - } - } + getAll(url: "/tasks", completion) } // get all on index func getAll( uid: String, _ completion: @escaping (Result, Swift.Error>) -> Void) { - self.request.get(api: "/indexes/\(uid)/tasks") { result in + getAll(url: "/indexes/\(uid)/tasks", completion) + } + + func getAll( + url: String, + _ completion: @escaping (Result, Swift.Error>) -> Void) { + self.request.get(api: url) { result in switch result { case .success(let data): - guard let data: Data = data else { - completion(.failure(MeiliSearch.Error.dataNotFound)) - return - } do { - let result: Results = try Constants.customJSONDecoder.decode(Results.self, from: data) - completion(.success(result)) + let task: Result, Swift.Error> = try Constants.resultDecoder(data: data) + completion(task) } catch { completion(.failure(error)) } @@ -136,36 +101,24 @@ struct Tasks { } } - // wait for task using taskUid + // wait for task using task structure func waitForTask( - taskUid: Int, + task: Task, options: WaitOptions? = nil, _ completion: @escaping (Result) -> Void) { - do { - let currentDate = Date() - let waitOptions: WaitOptions = options ?? WaitOptions() - - self.checkStatus(taskUid, waitOptions, currentDate) { result in - switch result { - case .success(let status): - completion(.success(status)) - case .failure(let error): - completion(.failure(error)) - } - } - } + waitForTask(taskUid: task.uid, options: options, completion) } - // wait for task using task structure + // wait for task using taskUid func waitForTask( - task: Task, + taskUid: Int, options: WaitOptions? = nil, _ completion: @escaping (Result) -> Void) { do { let currentDate = Date() let waitOptions: WaitOptions = options ?? WaitOptions() - self.checkStatus(task.uid, waitOptions, currentDate) { result in + self.checkStatus(taskUid, waitOptions, currentDate) { result in switch result { case .success(let status): completion(.success(status)) diff --git a/Tests/MeiliSearchIntegrationTests/SettingsTests.swift b/Tests/MeiliSearchIntegrationTests/SettingsTests.swift index 1df7cdf9..9c32b2b2 100644 --- a/Tests/MeiliSearchIntegrationTests/SettingsTests.swift +++ b/Tests/MeiliSearchIntegrationTests/SettingsTests.swift @@ -47,7 +47,7 @@ class SettingsTests: XCTestCase { createExpectation.fulfill() } } - self.wait(for: [createExpectation], timeout: 20.0) + self.wait(for: [createExpectation], timeout: 5.0) self.defaultGlobalSettings = Setting( rankingRules: self.defaultRankingRules, @@ -90,7 +90,7 @@ class SettingsTests: XCTestCase { } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } func testUpdateFilterableAttributes() { @@ -128,7 +128,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 2.0) } func testResetFilterableAttributes() { @@ -156,7 +156,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } // // MARK: Displayed attributes @@ -176,7 +176,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } func testUpdateDisplayedAttributes() { @@ -214,7 +214,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 10.0) } func testResetDisplayedAttributes() { @@ -242,7 +242,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } // MARK: Distinct attributes @@ -261,7 +261,7 @@ class SettingsTests: XCTestCase { expectation.fulfill() } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } func testUpdateDistinctAttribute() { @@ -298,7 +298,7 @@ class SettingsTests: XCTestCase { expectation.fulfill() } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 10.0) } func testResetDistinctAttributes() { @@ -326,7 +326,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } // // MARK: Ranking rules @@ -346,7 +346,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } func testUpdateRankingRules() { @@ -389,7 +389,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 2.0) } func testResetRankingRules() { @@ -417,7 +417,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } // MARK: Searchable attributes @@ -437,7 +437,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } func testUpdateSearchableAttributes() { @@ -479,7 +479,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 2.0) } func testResetSearchableAttributes() { @@ -507,7 +507,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } // MARK: Stop words @@ -527,7 +527,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } func testUpdateStopWords() { @@ -566,7 +566,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 10.0) } func testUpdateStopWordsWithEmptyArray() { @@ -605,7 +605,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 10.0) } func testUpdateStopWordsWithNullValue() { @@ -644,7 +644,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 10.0) } func testResetStopWords() { @@ -672,7 +672,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } // MARK: Synonyms @@ -692,7 +692,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } func testUpdateSynonyms() { @@ -736,7 +736,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 2.0) } func testUpdateSynonymsEmptyString() { @@ -774,7 +774,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 2.0) } func testUpdateSynonymsNil() { @@ -813,7 +813,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 2.0) } func testResetSynonyms() { @@ -841,7 +841,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } // MARK: Global Settings @@ -861,7 +861,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } func testupdateSettings() { @@ -915,7 +915,7 @@ class SettingsTests: XCTestCase { expectation.fulfill() } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 10.0) let overrideSettingsExpectation = XCTestExpectation(description: "Update settings") @@ -946,7 +946,7 @@ class SettingsTests: XCTestCase { overrideSettingsExpectation.fulfill() } } - self.wait(for: [overrideSettingsExpectation], timeout: 20.0) + self.wait(for: [overrideSettingsExpectation], timeout: 10.0) } func testupdateSettingssWithSynonymsAndStopWordsNil() { @@ -1004,7 +1004,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 10.0) } func testresetSettingss() { @@ -1031,7 +1031,7 @@ class SettingsTests: XCTestCase { } } - self.wait(for: [expectation], timeout: 20.0) + self.wait(for: [expectation], timeout: 5.0) } } // swiftlint:enable force_try diff --git a/Tests/MeiliSearchIntegrationTests/TaskTests.swift b/Tests/MeiliSearchIntegrationTests/TaskTests.swift index 85590f79..429279b9 100644 --- a/Tests/MeiliSearchIntegrationTests/TaskTests.swift +++ b/Tests/MeiliSearchIntegrationTests/TaskTests.swift @@ -15,7 +15,7 @@ private struct Movie: Codable, Equatable { } } -class UpdatesTests: XCTestCase { +class TasksTests: XCTestCase { private var client: MeiliSearch! private var index: Indexes! private var session: URLSessionProtocol!