From 554ad9fc523763d55ba4372da35f39cba9d5053a Mon Sep 17 00:00:00 2001 From: Angelo Paparazzi Date: Fri, 30 Oct 2020 19:10:32 -0400 Subject: [PATCH] STT V1, TTS V1, Vis Rec V3/V4 changes --- .../Models/CreateAcousticModel.swift | 122 ---- .../Models/CreateLanguageModel.swift | 154 ------ .../SpeechToTextV1/Models/CustomWords.swift | 50 -- .../Models/SpeechRecognitionAlternative.swift | 6 +- Sources/SpeechToTextV1/SpeechToText.swift | 519 ++++++++++-------- Sources/SupportingFiles/Shared.swift | 2 - .../Models/CreateVoiceModel.swift | 92 ---- .../{VoiceModel.swift => CustomModel.swift} | 36 +- .../{VoiceModels.swift => CustomModels.swift} | 14 +- .../Models/UpdateVoiceModel.swift | 68 --- Sources/TextToSpeechV1/Models/Voice.swift | 10 +- Sources/TextToSpeechV1/TextToSpeech.swift | 452 +++++++-------- .../ToneAnalyzerV3/Models/ToneChatInput.swift | 49 -- .../ToneAnalyzerV3/Models/ToneContent.swift | 8 +- Sources/ToneAnalyzerV3/ToneAnalyzer.swift | 95 ++-- .../VisualRecognition.swift | 172 +++--- .../Models/BaseCollection.swift | 105 ---- .../Models/Collection.swift | 4 +- ...s.swift => CollectionTrainingStatus.swift} | 24 +- .../Models/ObjectDetail.swift | 4 +- .../Models/ObjectDetailLocation.swift} | 41 +- .../Models/UpdateObjectMetadata.swift | 5 +- .../VisualRecognition.swift | 345 +++++++----- 23 files changed, 940 insertions(+), 1437 deletions(-) delete mode 100644 Sources/SpeechToTextV1/Models/CreateAcousticModel.swift delete mode 100644 Sources/SpeechToTextV1/Models/CreateLanguageModel.swift delete mode 100644 Sources/SpeechToTextV1/Models/CustomWords.swift delete mode 100644 Sources/TextToSpeechV1/Models/CreateVoiceModel.swift rename Sources/TextToSpeechV1/Models/{VoiceModel.swift => CustomModel.swift} (57%) rename Sources/TextToSpeechV1/Models/{VoiceModels.swift => CustomModels.swift} (63%) delete mode 100644 Sources/TextToSpeechV1/Models/UpdateVoiceModel.swift delete mode 100644 Sources/ToneAnalyzerV3/Models/ToneChatInput.swift delete mode 100644 Sources/VisualRecognitionV4/Models/BaseCollection.swift rename Sources/VisualRecognitionV4/Models/{BaseTrainingDataObjects.swift => CollectionTrainingStatus.swift} (59%) rename Sources/{TextToSpeechV1/Models/Text.swift => VisualRecognitionV4/Models/ObjectDetailLocation.swift} (56%) diff --git a/Sources/SpeechToTextV1/Models/CreateAcousticModel.swift b/Sources/SpeechToTextV1/Models/CreateAcousticModel.swift deleted file mode 100644 index 01c142764..000000000 --- a/Sources/SpeechToTextV1/Models/CreateAcousticModel.swift +++ /dev/null @@ -1,122 +0,0 @@ -/** - * (C) Copyright IBM Corp. 2018, 2020. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -import Foundation - -/** - Information about the new custom acoustic model. - */ -internal struct CreateAcousticModel: Codable, Equatable { - - /** - The name of the base language model that is to be customized by the new custom acoustic model. The new custom model - can be used only with the base model that it customizes. - To determine whether a base model supports acoustic model customization, refer to [Language support for - customization](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-customization#languageSupport). - */ - public enum BaseModelName: String { - case arArBroadbandmodel = "ar-AR_BroadbandModel" - case deDeBroadbandmodel = "de-DE_BroadbandModel" - case deDeNarrowbandmodel = "de-DE_NarrowbandModel" - case enGbBroadbandmodel = "en-GB_BroadbandModel" - case enGbNarrowbandmodel = "en-GB_NarrowbandModel" - case enUsBroadbandmodel = "en-US_BroadbandModel" - case enUsNarrowbandmodel = "en-US_NarrowbandModel" - case enUsShortformNarrowbandmodel = "en-US_ShortForm_NarrowbandModel" - case esArBroadbandmodel = "es-AR_BroadbandModel" - case esArNarrowbandmodel = "es-AR_NarrowbandModel" - case esClBroadbandmodel = "es-CL_BroadbandModel" - case esClNarrowbandmodel = "es-CL_NarrowbandModel" - case esCoBroadbandmodel = "es-CO_BroadbandModel" - case esCoNarrowbandmodel = "es-CO_NarrowbandModel" - case esEsBroadbandmodel = "es-ES_BroadbandModel" - case esEsNarrowbandmodel = "es-ES_NarrowbandModel" - case esMxBroadbandmodel = "es-MX_BroadbandModel" - case esMxNarrowbandmodel = "es-MX_NarrowbandModel" - case esPeBroadbandmodel = "es-PE_BroadbandModel" - case esPeNarrowbandmodel = "es-PE_NarrowbandModel" - case frFrBroadbandmodel = "fr-FR_BroadbandModel" - case frFrNarrowbandmodel = "fr-FR_NarrowbandModel" - case itItBroadbandmodel = "it-IT_BroadbandModel" - case itItNarrowbandmodel = "it-IT_NarrowbandModel" - case jaJpBroadbandmodel = "ja-JP_BroadbandModel" - case jaJpNarrowbandmodel = "ja-JP_NarrowbandModel" - case koKrBroadbandmodel = "ko-KR_BroadbandModel" - case koKrNarrowbandmodel = "ko-KR_NarrowbandModel" - case nlNlBroadbandmodel = "nl-NL_BroadbandModel" - case nlNlNarrowbandmodel = "nl-NL_NarrowbandModel" - case ptBrBroadbandmodel = "pt-BR_BroadbandModel" - case ptBrNarrowbandmodel = "pt-BR_NarrowbandModel" - case zhCnBroadbandmodel = "zh-CN_BroadbandModel" - case zhCnNarrowbandmodel = "zh-CN_NarrowbandModel" - } - - /** - A user-defined name for the new custom acoustic model. Use a name that is unique among all custom acoustic models - that you own. Use a localized name that matches the language of the custom model. Use a name that describes the - acoustic environment of the custom model, such as `Mobile custom model` or `Noisy car custom model`. - */ - public var name: String - - /** - The name of the base language model that is to be customized by the new custom acoustic model. The new custom model - can be used only with the base model that it customizes. - To determine whether a base model supports acoustic model customization, refer to [Language support for - customization](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-customization#languageSupport). - */ - public var baseModelName: String - - /** - A description of the new custom acoustic model. Use a localized description that matches the language of the custom - model. - */ - public var description: String? - - // Map each property name to the key that shall be used for encoding/decoding. - private enum CodingKeys: String, CodingKey { - case name = "name" - case baseModelName = "base_model_name" - case description = "description" - } - - /** - Initialize a `CreateAcousticModel` with member variables. - - - parameter name: A user-defined name for the new custom acoustic model. Use a name that is unique among all - custom acoustic models that you own. Use a localized name that matches the language of the custom model. Use a - name that describes the acoustic environment of the custom model, such as `Mobile custom model` or `Noisy car - custom model`. - - parameter baseModelName: The name of the base language model that is to be customized by the new custom - acoustic model. The new custom model can be used only with the base model that it customizes. - To determine whether a base model supports acoustic model customization, refer to [Language support for - customization](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-customization#languageSupport). - - parameter description: A description of the new custom acoustic model. Use a localized description that - matches the language of the custom model. - - - returns: An initialized `CreateAcousticModel`. - */ - public init( - name: String, - baseModelName: String, - description: String? = nil - ) - { - self.name = name - self.baseModelName = baseModelName - self.description = description - } - -} diff --git a/Sources/SpeechToTextV1/Models/CreateLanguageModel.swift b/Sources/SpeechToTextV1/Models/CreateLanguageModel.swift deleted file mode 100644 index 19f4a1459..000000000 --- a/Sources/SpeechToTextV1/Models/CreateLanguageModel.swift +++ /dev/null @@ -1,154 +0,0 @@ -/** - * (C) Copyright IBM Corp. 2018, 2020. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -import Foundation - -/** - Information about the new custom language model. - */ -internal struct CreateLanguageModel: Codable, Equatable { - - /** - The name of the base language model that is to be customized by the new custom language model. The new custom model - can be used only with the base model that it customizes. - To determine whether a base model supports language model customization, use the **Get a model** method and check - that the attribute `custom_language_model` is set to `true`. You can also refer to [Language support for - customization](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-customization#languageSupport). - */ - public enum BaseModelName: String { - case deDeBroadbandmodel = "de-DE_BroadbandModel" - case deDeNarrowbandmodel = "de-DE_NarrowbandModel" - case enGbBroadbandmodel = "en-GB_BroadbandModel" - case enGbNarrowbandmodel = "en-GB_NarrowbandModel" - case enUsBroadbandmodel = "en-US_BroadbandModel" - case enUsNarrowbandmodel = "en-US_NarrowbandModel" - case enUsShortformNarrowbandmodel = "en-US_ShortForm_NarrowbandModel" - case esArBroadbandmodel = "es-AR_BroadbandModel" - case esArNarrowbandmodel = "es-AR_NarrowbandModel" - case esClBroadbandmodel = "es-CL_BroadbandModel" - case esClNarrowbandmodel = "es-CL_NarrowbandModel" - case esCoBroadbandmodel = "es-CO_BroadbandModel" - case esCoNarrowbandmodel = "es-CO_NarrowbandModel" - case esEsBroadbandmodel = "es-ES_BroadbandModel" - case esEsNarrowbandmodel = "es-ES_NarrowbandModel" - case esMxBroadbandmodel = "es-MX_BroadbandModel" - case esMxNarrowbandmodel = "es-MX_NarrowbandModel" - case esPeBroadbandmodel = "es-PE_BroadbandModel" - case esPeNarrowbandmodel = "es-PE_NarrowbandModel" - case frFrBroadbandmodel = "fr-FR_BroadbandModel" - case frFrNarrowbandmodel = "fr-FR_NarrowbandModel" - case itItBroadbandmodel = "it-IT_BroadbandModel" - case itItNarrowbandmodel = "it-IT_NarrowbandModel" - case jaJpBroadbandmodel = "ja-JP_BroadbandModel" - case jaJpNarrowbandmodel = "ja-JP_NarrowbandModel" - case koKrBroadbandmodel = "ko-KR_BroadbandModel" - case koKrNarrowbandmodel = "ko-KR_NarrowbandModel" - case nlNlBroadbandmodel = "nl-NL_BroadbandModel" - case nlNlNarrowbandmodel = "nl-NL_NarrowbandModel" - case ptBrBroadbandmodel = "pt-BR_BroadbandModel" - case ptBrNarrowbandmodel = "pt-BR_NarrowbandModel" - } - - /** - A user-defined name for the new custom language model. Use a name that is unique among all custom language models - that you own. Use a localized name that matches the language of the custom model. Use a name that describes the - domain of the custom model, such as `Medical custom model` or `Legal custom model`. - */ - public var name: String - - /** - The name of the base language model that is to be customized by the new custom language model. The new custom model - can be used only with the base model that it customizes. - To determine whether a base model supports language model customization, use the **Get a model** method and check - that the attribute `custom_language_model` is set to `true`. You can also refer to [Language support for - customization](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-customization#languageSupport). - */ - public var baseModelName: String - - /** - The dialect of the specified language that is to be used with the custom language model. For most languages, the - dialect matches the language of the base model by default. For example, `en-US` is used for either of the US - English language models. - For a Spanish language, the service creates a custom language model that is suited for speech in one of the - following dialects: - * `es-ES` for Castilian Spanish (`es-ES` models) - * `es-LA` for Latin American Spanish (`es-AR`, `es-CL`, `es-CO`, and `es-PE` models) - * `es-US` for Mexican (North American) Spanish (`es-MX` models) - The parameter is meaningful only for Spanish models, for which you can always safely omit the parameter to have the - service create the correct mapping. - If you specify the `dialect` parameter for non-Spanish language models, its value must match the language of the - base model. If you specify the `dialect` for Spanish language models, its value must match one of the defined - mappings as indicated (`es-ES`, `es-LA`, or `es-MX`). All dialect values are case-insensitive. - */ - public var dialect: String? - - /** - A description of the new custom language model. Use a localized description that matches the language of the custom - model. - */ - public var description: String? - - // Map each property name to the key that shall be used for encoding/decoding. - private enum CodingKeys: String, CodingKey { - case name = "name" - case baseModelName = "base_model_name" - case dialect = "dialect" - case description = "description" - } - - /** - Initialize a `CreateLanguageModel` with member variables. - - - parameter name: A user-defined name for the new custom language model. Use a name that is unique among all - custom language models that you own. Use a localized name that matches the language of the custom model. Use a - name that describes the domain of the custom model, such as `Medical custom model` or `Legal custom model`. - - parameter baseModelName: The name of the base language model that is to be customized by the new custom - language model. The new custom model can be used only with the base model that it customizes. - To determine whether a base model supports language model customization, use the **Get a model** method and check - that the attribute `custom_language_model` is set to `true`. You can also refer to [Language support for - customization](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-customization#languageSupport). - - parameter dialect: The dialect of the specified language that is to be used with the custom language model. - For most languages, the dialect matches the language of the base model by default. For example, `en-US` is used - for either of the US English language models. - For a Spanish language, the service creates a custom language model that is suited for speech in one of the - following dialects: - * `es-ES` for Castilian Spanish (`es-ES` models) - * `es-LA` for Latin American Spanish (`es-AR`, `es-CL`, `es-CO`, and `es-PE` models) - * `es-US` for Mexican (North American) Spanish (`es-MX` models) - The parameter is meaningful only for Spanish models, for which you can always safely omit the parameter to have - the service create the correct mapping. - If you specify the `dialect` parameter for non-Spanish language models, its value must match the language of the - base model. If you specify the `dialect` for Spanish language models, its value must match one of the defined - mappings as indicated (`es-ES`, `es-LA`, or `es-MX`). All dialect values are case-insensitive. - - parameter description: A description of the new custom language model. Use a localized description that - matches the language of the custom model. - - - returns: An initialized `CreateLanguageModel`. - */ - public init( - name: String, - baseModelName: String, - dialect: String? = nil, - description: String? = nil - ) - { - self.name = name - self.baseModelName = baseModelName - self.dialect = dialect - self.description = description - } - -} diff --git a/Sources/SpeechToTextV1/Models/CustomWords.swift b/Sources/SpeechToTextV1/Models/CustomWords.swift deleted file mode 100644 index 0febeb8e2..000000000 --- a/Sources/SpeechToTextV1/Models/CustomWords.swift +++ /dev/null @@ -1,50 +0,0 @@ -/** - * (C) Copyright IBM Corp. 2018, 2019. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -import Foundation - -/** - Information about the words that are to be added to a custom language model. - */ -internal struct CustomWords: Codable, Equatable { - - /** - An array of `CustomWord` objects that provides information about each custom word that is to be added to or updated - in the custom language model. - */ - public var words: [CustomWord] - - // Map each property name to the key that shall be used for encoding/decoding. - private enum CodingKeys: String, CodingKey { - case words = "words" - } - - /** - Initialize a `CustomWords` with member variables. - - - parameter words: An array of `CustomWord` objects that provides information about each custom word that is to - be added to or updated in the custom language model. - - - returns: An initialized `CustomWords`. - */ - public init( - words: [CustomWord] - ) - { - self.words = words - } - -} diff --git a/Sources/SpeechToTextV1/Models/SpeechRecognitionAlternative.swift b/Sources/SpeechToTextV1/Models/SpeechRecognitionAlternative.swift index 6802419fa..7ae4bea11 100644 --- a/Sources/SpeechToTextV1/Models/SpeechRecognitionAlternative.swift +++ b/Sources/SpeechToTextV1/Models/SpeechRecognitionAlternative.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2016, 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,14 +37,14 @@ public struct SpeechRecognitionAlternative: Codable, Equatable { the word followed by its start and end time in seconds, for example: `[["hello",0.0,1.2],["world",1.2,2.5]]`. Timestamps are returned only for the best alternative. */ - public var timestamps: [WordTimestamp]? + public var timestamps: [String]? /** A confidence score for each word of the transcript as a list of lists. Each inner list consists of two elements: the word and its confidence score in the range of 0.0 to 1.0, for example: `[["hello",0.95],["world",0.866]]`. Confidence scores are returned only for the best alternative and only with results marked as final. */ - public var wordConfidence: [WordConfidence]? + public var wordConfidence: [String]? // Map each property name to the key that shall be used for encoding/decoding. private enum CodingKeys: String, CodingKey { diff --git a/Sources/SpeechToTextV1/SpeechToText.swift b/Sources/SpeechToTextV1/SpeechToText.swift index 519aae41e..ecf87e7d2 100644 --- a/Sources/SpeechToTextV1/SpeechToText.swift +++ b/Sources/SpeechToTextV1/SpeechToText.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2016, 2020. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + +/** + * IBM OpenAPI SDK Code Generator Version: 99-SNAPSHOT-36b26b63-20201028-122900 + **/ + // swiftlint:disable file_length import Foundation +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif import IBMSwiftSDKCore +public typealias WatsonError = RestError +public typealias WatsonResponse = RestResponse /** The IBM Watson™ Speech to Text service provides APIs that use IBM's speech-recognition capabilities to produce transcripts of spoken audio. The service can transcribe speech from various languages and audio formats. In addition to @@ -41,7 +51,9 @@ public class SpeechToText { public var serviceURL: String? = "https://api.us-south.speech-to-text.watson.cloud.ibm.com" /// Service identifiers - internal let serviceName = "SpeechToText" + public static let defaultServiceName = "speech_to_text" + // Service info for SDK headers + internal let serviceName = defaultServiceName internal let serviceVersion = "v1" internal let serviceSdkName = "speech_to_text" @@ -55,26 +67,26 @@ public class SpeechToText { /** Create a `SpeechToText` object. - This initializer will retrieve credentials from the environment or a local credentials file. + If an authenticator is not supplied, the initializer will retrieve credentials from the environment or + a local credentials file and construct an appropriate authenticator using these credentials. The credentials file can be downloaded from your service instance on IBM Cloud as ibm-credentials.env. Make sure to add the credentials file to your project so that it can be loaded at runtime. - If credentials are not available in the environment or a local credentials file, initialization will fail. + If an authenticator is not supplied and credentials are not available in the environment or a local + credentials file, initialization will fail by throwing an exception. In that case, try another initializer that directly passes in the credentials. + - parameter authenticator: The Authenticator object used to authenticate requests to the service + - serviceName: String = defaultServiceName */ - public init() throws { - let authenticator = try ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceSdkName) - self.authenticator = authenticator - - if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceSdkName) { + public init(authenticator: Authenticator? = nil, serviceName: String = defaultServiceName) throws { + self.authenticator = try authenticator ?? ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceName) + if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceName) { self.serviceURL = serviceURL } - RestRequest.userAgent = Shared.userAgent } - #endif - + #else /** Create a `SpeechToText` object. @@ -84,6 +96,7 @@ public class SpeechToText { self.authenticator = authenticator RestRequest.userAgent = Shared.userAgent } + #endif #if !os(Linux) /** @@ -102,7 +115,7 @@ public class SpeechToText { - parameter data: Raw data returned by the service that may represent an error. - parameter response: the URL response returned by the service. */ - func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> WatsonError { + func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> RestError { let statusCode = response.statusCode var errorMessage: String? @@ -127,7 +140,7 @@ public class SpeechToText { errorMessage = HTTPURLResponse.localizedString(forStatusCode: response.statusCode) } - return WatsonError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) + return RestError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) } /** @@ -147,18 +160,18 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listModels") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -194,23 +207,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/models/\(modelID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -460,20 +473,19 @@ public class SpeechToText { headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { - // construct body let body = audio // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "recognize") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" if let contentType = contentType { headerParameters["Content-Type"] = contentType } + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -574,7 +586,7 @@ public class SpeechToText { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -638,12 +650,12 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "registerCallback") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -657,7 +669,7 @@ public class SpeechToText { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -694,11 +706,11 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "unregisterCallback") + headerParameters.merge(sdkHeaders) { (_, new) in new } if let headers = headers { headerParameters.merge(headers) { (_, new) in new } } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "unregisterCallback") - headerParameters.merge(sdkHeaders) { (_, new) in new } // construct query parameters var queryParameters = [URLQueryItem]() @@ -708,7 +720,7 @@ public class SpeechToText { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1014,20 +1026,19 @@ public class SpeechToText { headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { - // construct body let body = audio // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "createJob") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" if let contentType = contentType { headerParameters["Content-Type"] = contentType } + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1152,7 +1163,7 @@ public class SpeechToText { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1192,18 +1203,18 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "checkJobs") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1245,23 +1256,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "checkJob") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/recognitions/\(id)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1298,22 +1309,22 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteJob") + headerParameters.merge(sdkHeaders) { (_, new) in new } if let headers = headers { headerParameters.merge(headers) { (_, new) in new } } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteJob") - headerParameters.merge(sdkHeaders) { (_, new) in new } // construct REST request let path = "/v1/recognitions/\(id)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1377,31 +1388,31 @@ public class SpeechToText { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let createLanguageModelRequest = CreateLanguageModel( + let createLanguageModelRequest = CreateLanguageModelRequest( name: name, - baseModelName: baseModelName, + base_model_name: baseModelName, dialect: dialect, description: description) guard let body = try? JSON.encoder.encode(createLanguageModelRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "createLanguageModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1419,6 +1430,16 @@ public class SpeechToText { request.responseObject(completionHandler: completionHandler) } + // Private struct for the createLanguageModel request body + private struct CreateLanguageModelRequest: Encodable { + // swiftlint:disable identifier_name + let name: String + let base_model_name: String + let dialect: String? + let description: String? + // swiftlint:enable identifier_name + } + /** List custom language models. @@ -1431,8 +1452,9 @@ public class SpeechToText { - parameter language: The identifier of the language for which custom language or custom acoustic models are to be returned. Omit the parameter to see all custom language or custom acoustic models that are owned by the - requesting credentials. **Note:** The `ar-AR` (Modern Standard Arabic) and `zh-CN` (Mandarin Chinese) languages - are not available for language model customization. + requesting credentials. + To determine the languages for which customization is available, see [Language support for + customization](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-customization#languageSupport). - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -1443,12 +1465,12 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listLanguageModels") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1461,7 +1483,7 @@ public class SpeechToText { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1499,23 +1521,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getLanguageModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1553,23 +1575,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteLanguageModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1638,16 +1660,16 @@ public class SpeechToText { wordTypeToAdd: String? = nil, customizationWeight: Double? = nil, headers: [String: String]? = nil, - completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) + completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "trainLanguageModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1663,13 +1685,13 @@ public class SpeechToText { // construct REST request let path = "/v1/customizations/\(customizationID)/train" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1684,7 +1706,7 @@ public class SpeechToText { ) // execute REST request - request.response(completionHandler: completionHandler) + request.responseObject(completionHandler: completionHandler) } /** @@ -1709,23 +1731,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "resetLanguageModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/reset" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1770,23 +1792,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "upgradeLanguageModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/upgrade_model" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1824,23 +1846,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listCorpora") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/corpora" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1932,19 +1954,19 @@ public class SpeechToText { let multipartFormData = MultipartFormData() multipartFormData.append(corpusFile, withName: "corpus_file", fileName: "filename") guard let body = try? multipartFormData.toData() else { - completionHandler(nil, WatsonError.serialization(values: "request multipart form data")) + completionHandler(nil, RestError.serialization(values: "request multipart form data")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addCorpus") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = multipartFormData.contentType + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1956,13 +1978,13 @@ public class SpeechToText { // construct REST request let path = "/v1/customizations/\(customizationID)/corpora/\(corpusName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2004,23 +2026,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getCorpus") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/corpora/\(corpusName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2062,23 +2084,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteCorpus") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/corpora/\(corpusName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2131,12 +2153,12 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listWords") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -2152,13 +2174,13 @@ public class SpeechToText { // construct REST request let path = "/v1/customizations/\(customizationID)/words" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2234,33 +2256,33 @@ public class SpeechToText { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let addWordsRequest = CustomWords( + let addWordsRequest = AddWordsRequest( words: words) guard let body = try? JSON.encoder.encode(addWordsRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addWords") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/words" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2278,6 +2300,13 @@ public class SpeechToText { request.response(completionHandler: completionHandler) } + // Private struct for the addWords request body + private struct AddWordsRequest: Encodable { + // swiftlint:disable identifier_name + let words: [CustomWord] + // swiftlint:enable identifier_name + } + /** Add a custom word. @@ -2346,35 +2375,35 @@ public class SpeechToText { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let addWordRequest = CustomWord( + let addWordRequest = AddWordRequest( word: word, - soundsLike: soundsLike, - displayAs: displayAs) + sounds_like: soundsLike, + display_as: displayAs) guard let body = try? JSON.encoder.encode(addWordRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addWord") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/words/\(wordName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2392,6 +2421,15 @@ public class SpeechToText { request.response(completionHandler: completionHandler) } + // Private struct for the addWord request body + private struct AddWordRequest: Encodable { + // swiftlint:disable identifier_name + let word: String? + let sounds_like: [String]? + let display_as: String? + // swiftlint:enable identifier_name + } + /** Get a custom word. @@ -2416,23 +2454,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getWord") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/words/\(wordName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2476,23 +2514,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteWord") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/words/\(wordName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2530,23 +2568,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listGrammars") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/grammars" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2631,23 +2669,22 @@ public class SpeechToText { headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { - // construct body // convert body parameter to Data with UTF-8 encoding guard let body = grammarFile.data(using: .utf8) else { - let error = WatsonError.serialization(values: "grammarFile could not be encoded with UTF8.") + let error = RestError.serialization(values: "grammarFile could not be encoded with UTF8.") completionHandler(nil, error) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addGrammar") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = contentType + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -2659,13 +2696,13 @@ public class SpeechToText { // construct REST request let path = "/v1/customizations/\(customizationID)/grammars/\(grammarName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2707,23 +2744,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getGrammar") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/grammars/\(grammarName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2765,23 +2802,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteGrammar") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/grammars/\(grammarName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2831,30 +2868,30 @@ public class SpeechToText { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let createAcousticModelRequest = CreateAcousticModel( + let createAcousticModelRequest = CreateAcousticModelRequest( name: name, - baseModelName: baseModelName, + base_model_name: baseModelName, description: description) guard let body = try? JSON.encoder.encode(createAcousticModelRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "createAcousticModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2872,6 +2909,15 @@ public class SpeechToText { request.responseObject(completionHandler: completionHandler) } + // Private struct for the createAcousticModel request body + private struct CreateAcousticModelRequest: Encodable { + // swiftlint:disable identifier_name + let name: String + let base_model_name: String + let description: String? + // swiftlint:enable identifier_name + } + /** List custom acoustic models. @@ -2884,8 +2930,9 @@ public class SpeechToText { - parameter language: The identifier of the language for which custom language or custom acoustic models are to be returned. Omit the parameter to see all custom language or custom acoustic models that are owned by the - requesting credentials. **Note:** The `ar-AR` (Modern Standard Arabic) and `zh-CN` (Mandarin Chinese) languages - are not available for language model customization. + requesting credentials. + To determine the languages for which customization is available, see [Language support for + customization](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-customization#languageSupport). - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -2896,12 +2943,12 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listAcousticModels") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -2914,7 +2961,7 @@ public class SpeechToText { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -2952,23 +2999,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getAcousticModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3006,23 +3053,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteAcousticModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3046,11 +3093,12 @@ public class SpeechToText { audio resources for a custom acoustic model, use this method to begin the actual training of the model on the latest audio data. The custom acoustic model does not reflect its changed data until you train it. You must use credentials for the instance of the service that owns a model to train it. - The training method is asynchronous. It can take on the order of minutes or hours to complete depending on the - total amount of audio data on which the custom acoustic model is being trained and the current load on the service. - Typically, training a custom acoustic model takes approximately two to four times the length of its audio data. The - actual time depends on the model being trained and the nature of the audio, such as whether the audio is clean or - noisy. The method returns an HTTP 200 response code to indicate that the training process has begun. + The training method is asynchronous. Training time depends on the cumulative amount of audio data that the custom + acoustic model contains and the current load on the service. When you train or retrain a model, the service uses + all of the model's audio data in the training. Training a custom acoustic model takes approximately as long as the + length of its cumulative audio data. For example, it takes approximately 2 hours to train a model that contains a + total of 2 hours of audio. The method returns an HTTP 200 response code to indicate that the training process has + begun. You can monitor the status of the training by using the **Get a custom acoustic model** method to poll the model's status. Use a loop to check the status once a minute. The method returns an `AcousticModel` object that includes `status` and `progress` fields. A status of `available` indicates that the custom model is trained and ready to @@ -3097,16 +3145,16 @@ public class SpeechToText { customizationID: String, customLanguageModelID: String? = nil, headers: [String: String]? = nil, - completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) + completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "trainAcousticModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -3118,13 +3166,13 @@ public class SpeechToText { // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)/train" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3139,7 +3187,7 @@ public class SpeechToText { ) // execute REST request - request.response(completionHandler: completionHandler) + request.responseObject(completionHandler: completionHandler) } /** @@ -3166,23 +3214,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "resetAcousticModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)/reset" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3244,12 +3292,12 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "upgradeAcousticModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -3265,13 +3313,13 @@ public class SpeechToText { // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)/upgrade_model" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3312,23 +3360,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listAudio") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)/audio" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3461,14 +3509,10 @@ public class SpeechToText { headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { - // construct body let body = audioResource // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addAudio") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" @@ -3478,6 +3522,9 @@ public class SpeechToText { if let containedContentType = containedContentType { headerParameters["Contained-Content-Type"] = containedContentType } + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -3489,13 +3536,13 @@ public class SpeechToText { // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)/audio/\(audioName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3547,23 +3594,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getAudio") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)/audio/\(audioName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3606,23 +3653,23 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteAudio") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/acoustic_customizations/\(customizationID)/audio/\(audioName)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -3665,11 +3712,11 @@ public class SpeechToText { { // construct header parameters var headerParameters = defaultHeaders + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteUserData") + headerParameters.merge(sdkHeaders) { (_, new) in new } if let headers = headers { headerParameters.merge(headers) { (_, new) in new } } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteUserData") - headerParameters.merge(sdkHeaders) { (_, new) in new } // construct query parameters var queryParameters = [URLQueryItem]() @@ -3679,7 +3726,7 @@ public class SpeechToText { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } diff --git a/Sources/SupportingFiles/Shared.swift b/Sources/SupportingFiles/Shared.swift index a0731e4d3..e48c0f600 100644 --- a/Sources/SupportingFiles/Shared.swift +++ b/Sources/SupportingFiles/Shared.swift @@ -18,8 +18,6 @@ import Foundation import IBMSwiftSDKCore // Typealias rest types -public typealias WatsonResponse = RestResponse -public typealias WatsonError = RestError public typealias WatsonJSON = JSON // Typealias Authenticators provided by the core diff --git a/Sources/TextToSpeechV1/Models/CreateVoiceModel.swift b/Sources/TextToSpeechV1/Models/CreateVoiceModel.swift deleted file mode 100644 index 9e8c14967..000000000 --- a/Sources/TextToSpeechV1/Models/CreateVoiceModel.swift +++ /dev/null @@ -1,92 +0,0 @@ -/** - * (C) Copyright IBM Corp. 2018, 2020. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -import Foundation - -/** - Information about the new custom voice model. - */ -internal struct CreateVoiceModel: Codable, Equatable { - - /** - The language of the new custom voice model. You create a custom voice model for a specific language, not for a - specific voice. A custom model can be used with any voice, standard or neural, for its specified language. Omit the - parameter to use the the default language, `en-US`. - */ - public enum Language: String { - case arAr = "ar-AR" - case deDe = "de-DE" - case enGb = "en-GB" - case enUs = "en-US" - case esEs = "es-ES" - case esLa = "es-LA" - case esUs = "es-US" - case frFr = "fr-FR" - case itIt = "it-IT" - case jaJp = "ja-JP" - case koKr = "ko-KR" - case nlNl = "nl-NL" - case ptBr = "pt-BR" - case zhCn = "zh-CN" - } - - /** - The name of the new custom voice model. - */ - public var name: String - - /** - The language of the new custom voice model. You create a custom voice model for a specific language, not for a - specific voice. A custom model can be used with any voice, standard or neural, for its specified language. Omit the - parameter to use the the default language, `en-US`. - */ - public var language: String? - - /** - A description of the new custom voice model. Specifying a description is recommended. - */ - public var description: String? - - // Map each property name to the key that shall be used for encoding/decoding. - private enum CodingKeys: String, CodingKey { - case name = "name" - case language = "language" - case description = "description" - } - - /** - Initialize a `CreateVoiceModel` with member variables. - - - parameter name: The name of the new custom voice model. - - parameter language: The language of the new custom voice model. You create a custom voice model for a specific - language, not for a specific voice. A custom model can be used with any voice, standard or neural, for its - specified language. Omit the parameter to use the the default language, `en-US`. - - parameter description: A description of the new custom voice model. Specifying a description is recommended. - - - returns: An initialized `CreateVoiceModel`. - */ - public init( - name: String, - language: String? = nil, - description: String? = nil - ) - { - self.name = name - self.language = language - self.description = description - } - -} diff --git a/Sources/TextToSpeechV1/Models/VoiceModel.swift b/Sources/TextToSpeechV1/Models/CustomModel.swift similarity index 57% rename from Sources/TextToSpeechV1/Models/VoiceModel.swift rename to Sources/TextToSpeechV1/Models/CustomModel.swift index 5d5da5360..f35e30e1f 100644 --- a/Sources/TextToSpeechV1/Models/VoiceModel.swift +++ b/Sources/TextToSpeechV1/Models/CustomModel.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2018, 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,54 +17,54 @@ import Foundation /** - Information about an existing custom voice model. + Information about an existing custom model. */ -public struct VoiceModel: Codable, Equatable { +public struct CustomModel: Codable, Equatable { /** - The customization ID (GUID) of the custom voice model. The **Create a custom model** method returns only this - field. It does not not return the other fields of this object. + The customization ID (GUID) of the custom model. The **Create a custom model** method returns only this field. It + does not not return the other fields of this object. */ public var customizationID: String /** - The name of the custom voice model. + The name of the custom model. */ public var name: String? /** - The language identifier of the custom voice model (for example, `en-US`). + The language identifier of the custom model (for example, `en-US`). */ public var language: String? /** - The GUID of the credentials for the instance of the service that owns the custom voice model. + The GUID of the credentials for the instance of the service that owns the custom model. */ public var owner: String? /** - The date and time in Coordinated Universal Time (UTC) at which the custom voice model was created. The value is - provided in full ISO 8601 format (`YYYY-MM-DDThh:mm:ss.sTZD`). + The date and time in Coordinated Universal Time (UTC) at which the custom model was created. The value is provided + in full ISO 8601 format (`YYYY-MM-DDThh:mm:ss.sTZD`). */ public var created: String? /** - The date and time in Coordinated Universal Time (UTC) at which the custom voice model was last modified. The - `created` and `updated` fields are equal when a voice model is first added but has yet to be updated. The value is - provided in full ISO 8601 format (`YYYY-MM-DDThh:mm:ss.sTZD`). + The date and time in Coordinated Universal Time (UTC) at which the custom model was last modified. The `created` + and `updated` fields are equal when a model is first added but has yet to be updated. The value is provided in full + ISO 8601 format (`YYYY-MM-DDThh:mm:ss.sTZD`). */ public var lastModified: String? /** - The description of the custom voice model. + The description of the custom model. */ public var description: String? /** - An array of `Word` objects that lists the words and their translations from the custom voice model. The words are - listed in alphabetical order, with uppercase letters listed before lowercase letters. The array is empty if the - custom model contains no words. This field is returned only by the **Get a voice** method and only when you specify - the customization ID of a custom voice model. + An array of `Word` objects that lists the words and their translations from the custom model. The words are listed + in alphabetical order, with uppercase letters listed before lowercase letters. The array is empty if the custom + model contains no words. This field is returned only by the **Get a voice** method and only when you specify the + customization ID of a custom model. */ public var words: [Word]? diff --git a/Sources/TextToSpeechV1/Models/VoiceModels.swift b/Sources/TextToSpeechV1/Models/CustomModels.swift similarity index 63% rename from Sources/TextToSpeechV1/Models/VoiceModels.swift rename to Sources/TextToSpeechV1/Models/CustomModels.swift index c88f55666..7c6850e6b 100644 --- a/Sources/TextToSpeechV1/Models/VoiceModels.swift +++ b/Sources/TextToSpeechV1/Models/CustomModels.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2018, 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,16 @@ import Foundation /** - Information about existing custom voice models. + Information about existing custom models. */ -public struct VoiceModels: Codable, Equatable { +public struct CustomModels: Codable, Equatable { /** - An array of `VoiceModel` objects that provides information about each available custom voice model. The array is - empty if the requesting credentials own no custom voice models (if no language is specified) or own no custom voice - models for the specified language. + An array of `CustomModel` objects that provides information about each available custom model. The array is empty + if the requesting credentials own no custom models (if no language is specified) or own no custom models for the + specified language. */ - public var customizations: [VoiceModel] + public var customizations: [CustomModel] // Map each property name to the key that shall be used for encoding/decoding. private enum CodingKeys: String, CodingKey { diff --git a/Sources/TextToSpeechV1/Models/UpdateVoiceModel.swift b/Sources/TextToSpeechV1/Models/UpdateVoiceModel.swift deleted file mode 100644 index 2b3d15191..000000000 --- a/Sources/TextToSpeechV1/Models/UpdateVoiceModel.swift +++ /dev/null @@ -1,68 +0,0 @@ -/** - * (C) Copyright IBM Corp. 2018, 2019. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -import Foundation - -/** - Information about the updated custom voice model. - */ -internal struct UpdateVoiceModel: Codable, Equatable { - - /** - A new name for the custom voice model. - */ - public var name: String? - - /** - A new description for the custom voice model. - */ - public var description: String? - - /** - An array of `Word` objects that provides the words and their translations that are to be added or updated for the - custom voice model. Pass an empty array to make no additions or updates. - */ - public var words: [Word]? - - // Map each property name to the key that shall be used for encoding/decoding. - private enum CodingKeys: String, CodingKey { - case name = "name" - case description = "description" - case words = "words" - } - - /** - Initialize a `UpdateVoiceModel` with member variables. - - - parameter name: A new name for the custom voice model. - - parameter description: A new description for the custom voice model. - - parameter words: An array of `Word` objects that provides the words and their translations that are to be - added or updated for the custom voice model. Pass an empty array to make no additions or updates. - - - returns: An initialized `UpdateVoiceModel`. - */ - public init( - name: String? = nil, - description: String? = nil, - words: [Word]? = nil - ) - { - self.name = name - self.description = description - self.words = words - } - -} diff --git a/Sources/TextToSpeechV1/Models/Voice.swift b/Sources/TextToSpeechV1/Models/Voice.swift index 28d94ce0a..f1a20f971 100644 --- a/Sources/TextToSpeechV1/Models/Voice.swift +++ b/Sources/TextToSpeechV1/Models/Voice.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2016, 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ import Foundation /** - Information about an available voice model. + Information about an available voice. */ public struct Voice: Codable, Equatable { @@ -58,10 +58,10 @@ public struct Voice: Codable, Equatable { public var supportedFeatures: SupportedFeatures /** - Returns information about a specified custom voice model. This field is returned only by the **Get a voice** method - and only when you specify the customization ID of a custom voice model. + Returns information about a specified custom model. This field is returned only by the **Get a voice** method and + only when you specify the customization ID of a custom model. */ - public var customization: VoiceModel? + public var customization: CustomModel? // Map each property name to the key that shall be used for encoding/decoding. private enum CodingKeys: String, CodingKey { diff --git a/Sources/TextToSpeechV1/TextToSpeech.swift b/Sources/TextToSpeechV1/TextToSpeech.swift index fd6068b0b..0bf62993d 100644 --- a/Sources/TextToSpeechV1/TextToSpeech.swift +++ b/Sources/TextToSpeechV1/TextToSpeech.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2016, 2020. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + +/** + * IBM OpenAPI SDK Code Generator Version: 99-SNAPSHOT-36b26b63-20201028-122900 + **/ + // swiftlint:disable file_length import Foundation +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif import IBMSwiftSDKCore +public typealias WatsonError = RestError +public typealias WatsonResponse = RestResponse /** The IBM Watson™ Text to Speech service provides APIs that use IBM's speech-synthesis capabilities to synthesize text into natural-sounding speech in a variety of languages, dialects, and voices. The service supports at least one @@ -38,7 +48,9 @@ public class TextToSpeech { public var serviceURL: String? = "https://api.us-south.text-to-speech.watson.cloud.ibm.com" /// Service identifiers - internal let serviceName = "TextToSpeech" + public static let defaultServiceName = "text_to_speech" + // Service info for SDK headers + internal let serviceName = defaultServiceName internal let serviceVersion = "v1" internal let serviceSdkName = "text_to_speech" @@ -52,26 +64,26 @@ public class TextToSpeech { /** Create a `TextToSpeech` object. - This initializer will retrieve credentials from the environment or a local credentials file. + If an authenticator is not supplied, the initializer will retrieve credentials from the environment or + a local credentials file and construct an appropriate authenticator using these credentials. The credentials file can be downloaded from your service instance on IBM Cloud as ibm-credentials.env. Make sure to add the credentials file to your project so that it can be loaded at runtime. - If credentials are not available in the environment or a local credentials file, initialization will fail. + If an authenticator is not supplied and credentials are not available in the environment or a local + credentials file, initialization will fail by throwing an exception. In that case, try another initializer that directly passes in the credentials. + - parameter authenticator: The Authenticator object used to authenticate requests to the service + - serviceName: String = defaultServiceName */ - public init() throws { - let authenticator = try ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceSdkName) - self.authenticator = authenticator - - if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceSdkName) { + public init(authenticator: Authenticator? = nil, serviceName: String = defaultServiceName) throws { + self.authenticator = try authenticator ?? ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceName) + if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceName) { self.serviceURL = serviceURL } - RestRequest.userAgent = Shared.userAgent } - #endif - + #else /** Create a `TextToSpeech` object. @@ -81,6 +93,7 @@ public class TextToSpeech { self.authenticator = authenticator RestRequest.userAgent = Shared.userAgent } + #endif #if !os(Linux) /** @@ -99,7 +112,7 @@ public class TextToSpeech { - parameter data: Raw data returned by the service that may represent an error. - parameter response: the URL response returned by the service. */ - func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> WatsonError { + func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> RestError { let statusCode = response.statusCode var errorMessage: String? @@ -124,7 +137,7 @@ public class TextToSpeech { errorMessage = HTTPURLResponse.localizedString(forStatusCode: response.statusCode) } - return WatsonError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) + return RestError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) } /** @@ -145,18 +158,18 @@ public class TextToSpeech { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listVoices") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -177,13 +190,13 @@ public class TextToSpeech { Get a voice. Gets information about the specified voice. The information includes the name, language, gender, and other details - about the voice. Specify a customization ID to obtain information for a custom voice model that is defined for the + about the voice. Specify a customization ID to obtain information for a custom model that is defined for the language of the specified voice. To list information about all available voices, use the **List voices** method. **See also:** [Listing a specific voice](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-voices#listVoice). - parameter voice: The voice for which information is to be returned. - - parameter customizationID: The customization ID (GUID) of a custom voice model for which information is to be + - parameter customizationID: The customization ID (GUID) of a custom model for which information is to be returned. You must make the request with credentials for the instance of the service that owns the custom model. Omit the parameter to see information about the specified voice with no customization. - parameter headers: A dictionary of request headers to be sent with this request. @@ -197,12 +210,12 @@ public class TextToSpeech { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getVoice") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -214,13 +227,13 @@ public class TextToSpeech { // construct REST request let path = "/v1/voices/\(voice)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -291,10 +304,10 @@ public class TextToSpeech { `accept` parameter to specify the audio format. For more information about specifying an audio format, see **Audio formats (accept types)** in the method description. - parameter voice: The voice to use for synthesis. - - parameter customizationID: The customization ID (GUID) of a custom voice model to use for the synthesis. If a - custom voice model is specified, it works only if it matches the language of the indicated voice. You must make - the request with credentials for the instance of the service that owns the custom model. Omit the parameter to - use the specified voice with no customization. + - parameter customizationID: The customization ID (GUID) of a custom model to use for the synthesis. If a custom + model is specified, it works only if it matches the language of the indicated voice. You must make the request + with credentials for the instance of the service that owns the custom model. Omit the parameter to use the + specified voice with no customization. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -307,24 +320,24 @@ public class TextToSpeech { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let synthesizeRequest = Text( + let synthesizeRequest = SynthesizeRequest( text: text) guard let body = try? JSON.encoder.encode(synthesizeRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "synthesize") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Content-Type"] = "application/json" if let accept = accept { headerParameters["Accept"] = accept } + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -341,7 +354,7 @@ public class TextToSpeech { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -357,38 +370,14 @@ public class TextToSpeech { ) // execute REST request - request.response { (response: WatsonResponse?, error: WatsonError?) in - var response = response - guard let data = response?.result else { - completionHandler(response, error) - return - } - if accept?.lowercased().contains("audio/wav") == true { - // repair the WAV header - var wav = data - guard WAVRepair.isWAVFile(data: wav) else { - let error = WatsonError.other(message: "Expected returned audio to be in WAV format", metadata: nil) - completionHandler(nil, error) - return - } - WAVRepair.repairWAVHeader(data: &wav) - response?.result = wav - completionHandler(response, nil) - } else if accept?.lowercased().contains("ogg") == true && accept?.lowercased().contains("opus") == true { - do { - let decodedAudio = try TextToSpeechDecoder(audioData: data) - response?.result = decodedAudio.pcmDataWithHeaders - completionHandler(response, nil) - } catch { - let error = WatsonError.serialization(values: "returned audio") - completionHandler(nil, error) - return - } - } else { - completionHandler(response, nil) - } - } + request.response(completionHandler: completionHandler) + } + // Private struct for the synthesize request body + private struct SynthesizeRequest: Encodable { + // swiftlint:disable identifier_name + let text: String + // swiftlint:enable identifier_name } /** @@ -396,8 +385,7 @@ public class TextToSpeech { Gets the phonetic pronunciation for the specified word. You can request the pronunciation for a specific format. You can also request the pronunciation for a specific voice to see the default translation for the language of that - voice or for a specific custom voice model to see the translation for that voice model. - **Note:** This method is currently a beta release. + voice or for a specific custom model to see the translation for that model. **See also:** [Querying a word from a language](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customWords#cuWordsQueryLanguage). @@ -406,11 +394,11 @@ public class TextToSpeech { for the same language (for example, `en-US`) return the same translation. - parameter format: The phoneme format in which to return the pronunciation. The Arabic, Chinese, Dutch, and Korean languages support only IPA. Omit the parameter to obtain the pronunciation in the default format. - - parameter customizationID: The customization ID (GUID) of a custom voice model for which the pronunciation is - to be returned. The language of a specified custom model must match the language of the specified voice. If the - word is not defined in the specified custom model, the service returns the default translation for the custom - model's language. You must make the request with credentials for the instance of the service that owns the custom - model. Omit the parameter to see the translation for the specified voice with no customization. + - parameter customizationID: The customization ID (GUID) of a custom model for which the pronunciation is to be + returned. The language of a specified custom model must match the language of the specified voice. If the word is + not defined in the specified custom model, the service returns the default translation for the custom model's + language. You must make the request with credentials for the instance of the service that owns the custom model. + Omit the parameter to see the translation for the specified voice with no customization. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -424,12 +412,12 @@ public class TextToSpeech { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getPronunciation") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -451,7 +439,7 @@ public class TextToSpeech { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -472,53 +460,52 @@ public class TextToSpeech { /** Create a custom model. - Creates a new empty custom voice model. You must specify a name for the new custom model. You can optionally - specify the language and a description for the new model. The model is owned by the instance of the service whose - credentials are used to create it. - **Note:** This method is currently a beta release. + Creates a new empty custom model. You must specify a name for the new custom model. You can optionally specify the + language and a description for the new model. The model is owned by the instance of the service whose credentials + are used to create it. **See also:** [Creating a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customModels#cuModelsCreate). - - parameter name: The name of the new custom voice model. - - parameter language: The language of the new custom voice model. You create a custom voice model for a specific - language, not for a specific voice. A custom model can be used with any voice, standard or neural, for its - specified language. Omit the parameter to use the the default language, `en-US`. - - parameter description: A description of the new custom voice model. Specifying a description is recommended. + - parameter name: The name of the new custom model. + - parameter language: The language of the new custom model. You create a custom model for a specific language, + not for a specific voice. A custom model can be used with any voice, standard or neural, for its specified + language. Omit the parameter to use the the default language, `en-US`. + - parameter description: A description of the new custom model. Specifying a description is recommended. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ - public func createVoiceModel( + public func createCustomModel( name: String, language: String? = nil, description: String? = nil, headers: [String: String]? = nil, - completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) + completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let createVoiceModelRequest = CreateVoiceModel( + let createCustomModelRequest = CreateCustomModelRequest( name: name, language: language, description: description) - guard let body = try? JSON.encoder.encode(createVoiceModelRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + guard let body = try? JSON.encoder.encode(createCustomModelRequest) else { + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "createVoiceModel") + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "createCustomModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -536,35 +523,43 @@ public class TextToSpeech { request.responseObject(completionHandler: completionHandler) } + // Private struct for the createCustomModel request body + private struct CreateCustomModelRequest: Encodable { + // swiftlint:disable identifier_name + let name: String + let language: String? + let description: String? + // swiftlint:enable identifier_name + } + /** List custom models. - Lists metadata such as the name and description for all custom voice models that are owned by an instance of the - service. Specify a language to list the voice models for that language only. To see the words in addition to the - metadata for a specific voice model, use the **List a custom model** method. You must use credentials for the - instance of the service that owns a model to list information about it. - **Note:** This method is currently a beta release. + Lists metadata such as the name and description for all custom models that are owned by an instance of the service. + Specify a language to list the custom models for that language only. To see the words in addition to the metadata + for a specific custom model, use the **List a custom model** method. You must use credentials for the instance of + the service that owns a model to list information about it. **See also:** [Querying all custom models](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customModels#cuModelsQueryAll). - - parameter language: The language for which custom voice models that are owned by the requesting credentials are - to be returned. Omit the parameter to see all custom voice models that are owned by the requester. + - parameter language: The language for which custom models that are owned by the requesting credentials are to be + returned. Omit the parameter to see all custom models that are owned by the requester. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ - public func listVoiceModels( + public func listCustomModels( language: String? = nil, headers: [String: String]? = nil, - completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) + completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct header parameters var headerParameters = defaultHeaders + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listCustomModels") + headerParameters.merge(sdkHeaders) { (_, new) in new } + headerParameters["Accept"] = "application/json" if let headers = headers { headerParameters.merge(headers) { (_, new) in new } } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listVoiceModels") - headerParameters.merge(sdkHeaders) { (_, new) in new } - headerParameters["Accept"] = "application/json" // construct query parameters var queryParameters = [URLQueryItem]() @@ -577,7 +572,7 @@ public class TextToSpeech { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -598,18 +593,16 @@ public class TextToSpeech { /** Update a custom model. - Updates information for the specified custom voice model. You can update metadata such as the name and description - of the voice model. You can also update the words in the model and their translations. Adding a new translation for - a word that already exists in a custom model overwrites the word's existing translation. A custom model can contain - no more than 20,000 entries. You must use credentials for the instance of the service that owns a model to update - it. + Updates information for the specified custom model. You can update metadata such as the name and description of the + model. You can also update the words in the model and their translations. Adding a new translation for a word that + already exists in a custom model overwrites the word's existing translation. A custom model can contain no more + than 20,000 entries. You must use credentials for the instance of the service that owns a model to update it. You can define sounds-like or phonetic translations for words. A sounds-like translation consists of one or more words that, when combined, sound like the word. Phonetic translations are based on the SSML phoneme format for representing a word. You can specify them in standard International Phonetic Alphabet (IPA) representation <phoneme alphabet="ipa" ph="təmˈɑto"></phoneme> or in the proprietary IBM Symbolic Phonetic Representation (SPR) <phoneme alphabet="ibm" ph="1gAstroEntxrYFXs"></phoneme> - **Note:** This method is currently a beta release. **See also:** * [Updating a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customModels#cuModelsUpdate) @@ -618,16 +611,16 @@ public class TextToSpeech { * [Understanding customization](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customIntro#customIntro). - - parameter customizationID: The customization ID (GUID) of the custom voice model. You must make the request - with credentials for the instance of the service that owns the custom model. - - parameter name: A new name for the custom voice model. - - parameter description: A new description for the custom voice model. + - parameter customizationID: The customization ID (GUID) of the custom model. You must make the request with + credentials for the instance of the service that owns the custom model. + - parameter name: A new name for the custom model. + - parameter description: A new description for the custom model. - parameter words: An array of `Word` objects that provides the words and their translations that are to be added - or updated for the custom voice model. Pass an empty array to make no additions or updates. + or updated for the custom model. Pass an empty array to make no additions or updates. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ - public func updateVoiceModel( + public func updateCustomModel( customizationID: String, name: String? = nil, description: String? = nil, @@ -636,35 +629,35 @@ public class TextToSpeech { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let updateVoiceModelRequest = UpdateVoiceModel( + let updateCustomModelRequest = UpdateCustomModelRequest( name: name, description: description, words: words) - guard let body = try? JSON.encoder.encode(updateVoiceModelRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + guard let body = try? JSON.encoder.encode(updateCustomModelRequest) else { + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "updateVoiceModel") + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "updateCustomModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -682,45 +675,53 @@ public class TextToSpeech { request.response(completionHandler: completionHandler) } + // Private struct for the updateCustomModel request body + private struct UpdateCustomModelRequest: Encodable { + // swiftlint:disable identifier_name + let name: String? + let description: String? + let words: [Word]? + // swiftlint:enable identifier_name + } + /** Get a custom model. - Gets all information about a specified custom voice model. In addition to metadata such as the name and description - of the voice model, the output includes the words and their translations as defined in the model. To see just the - metadata for a voice model, use the **List custom models** method. - **Note:** This method is currently a beta release. + Gets all information about a specified custom model. In addition to metadata such as the name and description of + the custom model, the output includes the words and their translations as defined in the model. To see just the + metadata for a model, use the **List custom models** method. **See also:** [Querying a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customModels#cuModelsQuery). - - parameter customizationID: The customization ID (GUID) of the custom voice model. You must make the request - with credentials for the instance of the service that owns the custom model. + - parameter customizationID: The customization ID (GUID) of the custom model. You must make the request with + credentials for the instance of the service that owns the custom model. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ - public func getVoiceModel( + public func getCustomModel( customizationID: String, headers: [String: String]? = nil, - completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) + completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct header parameters var headerParameters = defaultHeaders + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getCustomModel") + headerParameters.merge(sdkHeaders) { (_, new) in new } + headerParameters["Accept"] = "application/json" if let headers = headers { headerParameters.merge(headers) { (_, new) in new } } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getVoiceModel") - headerParameters.merge(sdkHeaders) { (_, new) in new } - headerParameters["Accept"] = "application/json" // construct REST request let path = "/v1/customizations/\(customizationID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -740,40 +741,39 @@ public class TextToSpeech { /** Delete a custom model. - Deletes the specified custom voice model. You must use credentials for the instance of the service that owns a - model to delete it. - **Note:** This method is currently a beta release. + Deletes the specified custom model. You must use credentials for the instance of the service that owns a model to + delete it. **See also:** [Deleting a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customModels#cuModelsDelete). - - parameter customizationID: The customization ID (GUID) of the custom voice model. You must make the request - with credentials for the instance of the service that owns the custom model. + - parameter customizationID: The customization ID (GUID) of the custom model. You must make the request with + credentials for the instance of the service that owns the custom model. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ - public func deleteVoiceModel( + public func deleteCustomModel( customizationID: String, headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct header parameters var headerParameters = defaultHeaders + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteCustomModel") + headerParameters.merge(sdkHeaders) { (_, new) in new } if let headers = headers { headerParameters.merge(headers) { (_, new) in new } } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteVoiceModel") - headerParameters.merge(sdkHeaders) { (_, new) in new } // construct REST request let path = "/v1/customizations/\(customizationID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -793,17 +793,16 @@ public class TextToSpeech { /** Add custom words. - Adds one or more words and their translations to the specified custom voice model. Adding a new translation for a - word that already exists in a custom model overwrites the word's existing translation. A custom model can contain - no more than 20,000 entries. You must use credentials for the instance of the service that owns a model to add - words to it. + Adds one or more words and their translations to the specified custom model. Adding a new translation for a word + that already exists in a custom model overwrites the word's existing translation. A custom model can contain no + more than 20,000 entries. You must use credentials for the instance of the service that owns a model to add words + to it. You can define sounds-like or phonetic translations for words. A sounds-like translation consists of one or more words that, when combined, sound like the word. Phonetic translations are based on the SSML phoneme format for representing a word. You can specify them in standard International Phonetic Alphabet (IPA) representation <phoneme alphabet="ipa" ph="təmˈɑto"></phoneme> or in the proprietary IBM Symbolic Phonetic Representation (SPR) <phoneme alphabet="ibm" ph="1gAstroEntxrYFXs"></phoneme> - **Note:** This method is currently a beta release. **See also:** * [Adding multiple words to a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customWords#cuWordsAdd) @@ -812,13 +811,13 @@ public class TextToSpeech { * [Understanding customization](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customIntro#customIntro). - - parameter customizationID: The customization ID (GUID) of the custom voice model. You must make the request - with credentials for the instance of the service that owns the custom model. + - parameter customizationID: The customization ID (GUID) of the custom model. You must make the request with + credentials for the instance of the service that owns the custom model. - parameter words: The **Add custom words** method accepts an array of `Word` objects. Each object provides a - word that is to be added or updated for the custom voice model and the word's translation. + word that is to be added or updated for the custom model and the word's translation. The **List custom words** method returns an array of `Word` objects. Each object shows a word and its translation - from the custom voice model. The words are listed in alphabetical order, with uppercase letters listed before - lowercase letters. The array is empty if the custom model contains no words. + from the custom model. The words are listed in alphabetical order, with uppercase letters listed before lowercase + letters. The array is empty if the custom model contains no words. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -829,33 +828,33 @@ public class TextToSpeech { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let addWordsRequest = Words( + let addWordsRequest = AddWordsRequest( words: words) guard let body = try? JSON.encoder.encode(addWordsRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addWords") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/words" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -873,18 +872,24 @@ public class TextToSpeech { request.response(completionHandler: completionHandler) } + // Private struct for the addWords request body + private struct AddWordsRequest: Encodable { + // swiftlint:disable identifier_name + let words: [Word] + // swiftlint:enable identifier_name + } + /** List custom words. - Lists all of the words and their translations for the specified custom voice model. The output shows the - translations as they are defined in the model. You must use credentials for the instance of the service that owns a - model to list its words. - **Note:** This method is currently a beta release. + Lists all of the words and their translations for the specified custom model. The output shows the translations as + they are defined in the model. You must use credentials for the instance of the service that owns a model to list + its words. **See also:** [Querying all words from a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customWords#cuWordsQueryModel). - - parameter customizationID: The customization ID (GUID) of the custom voice model. You must make the request - with credentials for the instance of the service that owns the custom model. + - parameter customizationID: The customization ID (GUID) of the custom model. You must make the request with + credentials for the instance of the service that owns the custom model. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -895,23 +900,23 @@ public class TextToSpeech { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listWords") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/words" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -931,17 +936,16 @@ public class TextToSpeech { /** Add a custom word. - Adds a single word and its translation to the specified custom voice model. Adding a new translation for a word - that already exists in a custom model overwrites the word's existing translation. A custom model can contain no - more than 20,000 entries. You must use credentials for the instance of the service that owns a model to add a word - to it. + Adds a single word and its translation to the specified custom model. Adding a new translation for a word that + already exists in a custom model overwrites the word's existing translation. A custom model can contain no more + than 20,000 entries. You must use credentials for the instance of the service that owns a model to add a word to + it. You can define sounds-like or phonetic translations for words. A sounds-like translation consists of one or more words that, when combined, sound like the word. Phonetic translations are based on the SSML phoneme format for representing a word. You can specify them in standard International Phonetic Alphabet (IPA) representation <phoneme alphabet="ipa" ph="təmˈɑto"></phoneme> or in the proprietary IBM Symbolic Phonetic Representation (SPR) <phoneme alphabet="ibm" ph="1gAstroEntxrYFXs"></phoneme> - **Note:** This method is currently a beta release. **See also:** * [Adding a single word to a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customWords#cuWordAdd) @@ -950,9 +954,9 @@ public class TextToSpeech { * [Understanding customization](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customIntro#customIntro). - - parameter customizationID: The customization ID (GUID) of the custom voice model. You must make the request - with credentials for the instance of the service that owns the custom model. - - parameter word: The word that is to be added or updated for the custom voice model. + - parameter customizationID: The customization ID (GUID) of the custom model. You must make the request with + credentials for the instance of the service that owns the custom model. + - parameter word: The word that is to be added or updated for the custom model. - parameter translation: The phonetic or sounds-like translation for the word. A phonetic translation is based on the SSML format for representing the phonetic string of a word either as an IPA translation or as an IBM SPR translation. The Arabic, Chinese, Dutch, and Korean languages support only IPA. A sounds-like is one or more @@ -974,33 +978,33 @@ public class TextToSpeech { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let addWordRequest = Translation( + let addWordRequest = AddWordRequest( translation: translation, - partOfSpeech: partOfSpeech) + part_of_speech: partOfSpeech) guard let body = try? JSON.encoder.encode(addWordRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addWord") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/words/\(word)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1018,18 +1022,25 @@ public class TextToSpeech { request.response(completionHandler: completionHandler) } + // Private struct for the addWord request body + private struct AddWordRequest: Encodable { + // swiftlint:disable identifier_name + let translation: String + let part_of_speech: String? + // swiftlint:enable identifier_name + } + /** Get a custom word. Gets the translation for a single word from the specified custom model. The output shows the translation as it is defined in the model. You must use credentials for the instance of the service that owns a model to list its words. - **Note:** This method is currently a beta release. **See also:** [Querying a single word from a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customWords#cuWordQueryModel). - - parameter customizationID: The customization ID (GUID) of the custom voice model. You must make the request - with credentials for the instance of the service that owns the custom model. - - parameter word: The word that is to be queried from the custom voice model. + - parameter customizationID: The customization ID (GUID) of the custom model. You must make the request with + credentials for the instance of the service that owns the custom model. + - parameter word: The word that is to be queried from the custom model. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -1041,23 +1052,23 @@ public class TextToSpeech { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getWord") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct REST request let path = "/v1/customizations/\(customizationID)/words/\(word)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1077,15 +1088,14 @@ public class TextToSpeech { /** Delete a custom word. - Deletes a single word from the specified custom voice model. You must use credentials for the instance of the - service that owns a model to delete its words. - **Note:** This method is currently a beta release. + Deletes a single word from the specified custom model. You must use credentials for the instance of the service + that owns a model to delete its words. **See also:** [Deleting a word from a custom model](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-customWords#cuWordDelete). - - parameter customizationID: The customization ID (GUID) of the custom voice model. You must make the request - with credentials for the instance of the service that owns the custom model. - - parameter word: The word that is to be deleted from the custom voice model. + - parameter customizationID: The customization ID (GUID) of the custom model. You must make the request with + credentials for the instance of the service that owns the custom model. + - parameter word: The word that is to be deleted from the custom model. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -1097,22 +1107,22 @@ public class TextToSpeech { { // construct header parameters var headerParameters = defaultHeaders + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteWord") + headerParameters.merge(sdkHeaders) { (_, new) in new } if let headers = headers { headerParameters.merge(headers) { (_, new) in new } } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteWord") - headerParameters.merge(sdkHeaders) { (_, new) in new } // construct REST request let path = "/v1/customizations/\(customizationID)/words/\(word)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1138,8 +1148,8 @@ public class TextToSpeech { associate the customer ID with the data. You associate a customer ID with data by passing the `X-Watson-Metadata` header with a request that passes the data. **Note:** If you delete an instance of the service from the service console, all data associated with that service - instance is automatically deleted. This includes all custom voice models and word/translation pairs, and all data - related to speech synthesis requests. + instance is automatically deleted. This includes all custom models and word/translation pairs, and all data related + to speech synthesis requests. **See also:** [Information security](https://cloud.ibm.com/docs/text-to-speech?topic=text-to-speech-information-security#information-security). @@ -1154,11 +1164,11 @@ public class TextToSpeech { { // construct header parameters var headerParameters = defaultHeaders + let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteUserData") + headerParameters.merge(sdkHeaders) { (_, new) in new } if let headers = headers { headerParameters.merge(headers) { (_, new) in new } } - let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteUserData") - headerParameters.merge(sdkHeaders) { (_, new) in new } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1168,7 +1178,7 @@ public class TextToSpeech { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } diff --git a/Sources/ToneAnalyzerV3/Models/ToneChatInput.swift b/Sources/ToneAnalyzerV3/Models/ToneChatInput.swift deleted file mode 100644 index 9b1f59b49..000000000 --- a/Sources/ToneAnalyzerV3/Models/ToneChatInput.swift +++ /dev/null @@ -1,49 +0,0 @@ -/** - * (C) Copyright IBM Corp. 2018, 2019. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -import Foundation - -/** - Input for the customer-engagement endpoint. - */ -internal struct ToneChatInput: Codable, Equatable { - - /** - An array of `Utterance` objects that provides the input content that the service is to analyze. - */ - public var utterances: [Utterance] - - // Map each property name to the key that shall be used for encoding/decoding. - private enum CodingKeys: String, CodingKey { - case utterances = "utterances" - } - - /** - Initialize a `ToneChatInput` with member variables. - - - parameter utterances: An array of `Utterance` objects that provides the input content that the service is to - analyze. - - - returns: An initialized `ToneChatInput`. - */ - public init( - utterances: [Utterance] - ) - { - self.utterances = utterances - } - -} diff --git a/Sources/ToneAnalyzerV3/Models/ToneContent.swift b/Sources/ToneAnalyzerV3/Models/ToneContent.swift index 63f1bee1b..b41d0d431 100644 --- a/Sources/ToneAnalyzerV3/Models/ToneContent.swift +++ b/Sources/ToneAnalyzerV3/Models/ToneContent.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2018, 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,22 +24,22 @@ import IBMSwiftSDKCore public enum ToneContent { case toneInput(ToneInput) - case text(String) case html(String) + case text(String) internal var contentType: String { switch self { case .toneInput: return "application/json" - case .text: return "text/plain" case .html: return "text/html" + case .text: return "text/plain" } } internal var content: Data? { switch self { case .toneInput(let toneInput): return try? JSON.encoder.encode(toneInput) - case .text(let text): return text.data(using: .utf8) case .html(let html): return html.data(using: .utf8) + case .text(let text): return text.data(using: .utf8) } } diff --git a/Sources/ToneAnalyzerV3/ToneAnalyzer.swift b/Sources/ToneAnalyzerV3/ToneAnalyzer.swift index 77aac3110..ced719ce6 100644 --- a/Sources/ToneAnalyzerV3/ToneAnalyzer.swift +++ b/Sources/ToneAnalyzerV3/ToneAnalyzer.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2016, 2020. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + +/** + * IBM OpenAPI SDK Code Generator Version: 99-SNAPSHOT-36b26b63-20201028-122900 + **/ + // swiftlint:disable file_length import Foundation +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif import IBMSwiftSDKCore +public typealias WatsonError = RestError +public typealias WatsonResponse = RestResponse /** The IBM Watson™ Tone Analyzer service uses linguistic analysis to detect emotional and language tones in written text. The service can analyze tone at both the document and sentence levels. You can use the service to understand how @@ -32,8 +42,14 @@ public class ToneAnalyzer { /// The base URL to use when contacting the service. public var serviceURL: String? = "https://api.us-south.tone-analyzer.watson.cloud.ibm.com" + /// Release date of the version of the API you want to use. Specify dates in YYYY-MM-DD format. The current version + /// is `2017-09-21`. + public var version: String + /// Service identifiers - internal let serviceName = "ToneAnalyzer" + public static let defaultServiceName = "tone_analyzer" + // Service info for SDK headers + internal let serviceName = defaultServiceName internal let serviceVersion = "v3" internal let serviceSdkName = "tone_analyzer" @@ -42,41 +58,39 @@ public class ToneAnalyzer { var session = URLSession(configuration: URLSessionConfiguration.default) public let authenticator: Authenticator - let version: String #if os(Linux) /** Create a `ToneAnalyzer` object. - This initializer will retrieve credentials from the environment or a local credentials file. + If an authenticator is not supplied, the initializer will retrieve credentials from the environment or + a local credentials file and construct an appropriate authenticator using these credentials. The credentials file can be downloaded from your service instance on IBM Cloud as ibm-credentials.env. Make sure to add the credentials file to your project so that it can be loaded at runtime. - If credentials are not available in the environment or a local credentials file, initialization will fail. + If an authenticator is not supplied and credentials are not available in the environment or a local + credentials file, initialization will fail by throwing an exception. In that case, try another initializer that directly passes in the credentials. - - parameter version: The release date of the version of the API to use. Specify the date - in "YYYY-MM-DD" format. + - parameter version: Release date of the version of the API you want to use. Specify dates in YYYY-MM-DD format. + The current version is `2017-09-21`. + - parameter authenticator: The Authenticator object used to authenticate requests to the service + - serviceName: String = defaultServiceName */ - public init(version: String) throws { + public init(version: String, authenticator: Authenticator? = nil, serviceName: String = defaultServiceName) throws { self.version = version - - let authenticator = try ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceSdkName) - self.authenticator = authenticator - - if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceSdkName) { + self.authenticator = try authenticator ?? ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceName) + if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceName) { self.serviceURL = serviceURL } - RestRequest.userAgent = Shared.userAgent } - #endif - + #else /** Create a `ToneAnalyzer` object. - - parameter version: The release date of the version of the API to use. Specify the date - in "YYYY-MM-DD" format. + - parameter version: Release date of the version of the API you want to use. Specify dates in YYYY-MM-DD format. + The current version is `2017-09-21`. - parameter authenticator: The Authenticator object used to authenticate requests to the service */ public init(version: String, authenticator: Authenticator) { @@ -84,6 +98,7 @@ public class ToneAnalyzer { self.authenticator = authenticator RestRequest.userAgent = Shared.userAgent } + #endif #if !os(Linux) /** @@ -102,7 +117,7 @@ public class ToneAnalyzer { - parameter data: Raw data returned by the service that may represent an error. - parameter response: the URL response returned by the service. */ - func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> WatsonError { + func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> RestError { let statusCode = response.statusCode var errorMessage: String? @@ -127,7 +142,7 @@ public class ToneAnalyzer { errorMessage = HTTPURLResponse.localizedString(forStatusCode: response.statusCode) } - return WatsonError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) + return RestError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) } /** @@ -152,6 +167,11 @@ public class ToneAnalyzer { - parameter sentences: Indicates whether the service is to return an analysis of each individual sentence in addition to its analysis of the full document. If `true` (the default), the service returns results for each sentence. + - parameter tones: **`2017-09-21`:** Deprecated. The service continues to accept the parameter for + backward-compatibility, but the parameter no longer affects the response. + **`2016-05-19`:** A comma-separated list of tones for which the service is to return its analysis of the input; + the indicated tones apply both to the full document and to individual sentences of the document. You can specify + one or more of the valid values. Omit the parameter to request results for all three tones. - parameter contentLanguage: The language of the input text for the request: English or French. Regional variants are treated as their parent language; for example, `en-US` is interpreted as `en`. The input content must match the specified language. Do not submit content that contains both languages. You can use different languages for @@ -167,22 +187,19 @@ public class ToneAnalyzer { public func tone( toneContent: ToneContent, sentences: Bool? = nil, + tones: [String]? = nil, contentLanguage: String? = nil, acceptLanguage: String? = nil, headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { - // construct body guard let body = toneContent.content else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "tone") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" @@ -193,6 +210,9 @@ public class ToneAnalyzer { if let acceptLanguage = acceptLanguage { headerParameters["Accept-Language"] = acceptLanguage } + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -201,12 +221,16 @@ public class ToneAnalyzer { let queryParameter = URLQueryItem(name: "sentences", value: "\(sentences)") queryParameters.append(queryParameter) } + if let tones = tones { + let queryParameter = URLQueryItem(name: "tones", value: tones.joined(separator: ",")) + queryParameters.append(queryParameter) + } // construct REST request // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -261,18 +285,15 @@ public class ToneAnalyzer { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let toneChatRequest = ToneChatInput( + let toneChatRequest = ToneChatRequest( utterances: utterances) guard let body = try? JSON.encoder.encode(toneChatRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "toneChat") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" @@ -283,6 +304,9 @@ public class ToneAnalyzer { if let acceptLanguage = acceptLanguage { headerParameters["Accept-Language"] = acceptLanguage } + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -292,7 +316,7 @@ public class ToneAnalyzer { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -311,4 +335,11 @@ public class ToneAnalyzer { request.responseObject(completionHandler: completionHandler) } + // Private struct for the toneChat request body + private struct ToneChatRequest: Encodable { + // swiftlint:disable identifier_name + let utterances: [Utterance] + // swiftlint:enable identifier_name + } + } diff --git a/Sources/VisualRecognitionV3/VisualRecognition.swift b/Sources/VisualRecognitionV3/VisualRecognition.swift index ae16b664d..16de67b87 100644 --- a/Sources/VisualRecognitionV3/VisualRecognition.swift +++ b/Sources/VisualRecognitionV3/VisualRecognition.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2016, 2020. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + +/** + * IBM OpenAPI SDK Code Generator Version: 99-SNAPSHOT-36b26b63-20201028-122900 + **/ + // swiftlint:disable file_length import Foundation +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif import IBMSwiftSDKCore +public typealias WatsonError = RestError +public typealias WatsonResponse = RestResponse /** The IBM Watson™ Visual Recognition service uses deep learning algorithms to identify scenes and objects in images that you upload to the service. You can create and train a custom classifier to identify subjects that suit your needs. @@ -27,8 +37,14 @@ public class VisualRecognition { /// The base URL to use when contacting the service. public var serviceURL: String? = "https://api.us-south.visual-recognition.watson.cloud.ibm.com" + /// Release date of the API version you want to use. Specify dates in YYYY-MM-DD format. The current version is + /// `2018-03-19`. + public var version: String + /// Service identifiers - internal let serviceName = "WatsonVisionCombined" + public static let defaultServiceName = "watson_vision_combined" + // Service info for SDK headers + internal let serviceName = defaultServiceName internal let serviceVersion = "v3" internal let serviceSdkName = "visual_recognition" @@ -37,41 +53,39 @@ public class VisualRecognition { var session = URLSession(configuration: URLSessionConfiguration.default) public let authenticator: Authenticator - let version: String #if os(Linux) /** Create a `VisualRecognition` object. - This initializer will retrieve credentials from the environment or a local credentials file. + If an authenticator is not supplied, the initializer will retrieve credentials from the environment or + a local credentials file and construct an appropriate authenticator using these credentials. The credentials file can be downloaded from your service instance on IBM Cloud as ibm-credentials.env. Make sure to add the credentials file to your project so that it can be loaded at runtime. - If credentials are not available in the environment or a local credentials file, initialization will fail. + If an authenticator is not supplied and credentials are not available in the environment or a local + credentials file, initialization will fail by throwing an exception. In that case, try another initializer that directly passes in the credentials. - - parameter version: The release date of the version of the API to use. Specify the date - in "YYYY-MM-DD" format. + - parameter version: Release date of the API version you want to use. Specify dates in YYYY-MM-DD format. The + current version is `2018-03-19`. + - parameter authenticator: The Authenticator object used to authenticate requests to the service + - serviceName: String = defaultServiceName */ - public init(version: String) throws { + public init(version: String, authenticator: Authenticator? = nil, serviceName: String = defaultServiceName) throws { self.version = version - - let authenticator = try ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceSdkName) - self.authenticator = authenticator - - if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceSdkName) { + self.authenticator = try authenticator ?? ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceName) + if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceName) { self.serviceURL = serviceURL } - RestRequest.userAgent = Shared.userAgent } - #endif - + #else /** Create a `VisualRecognition` object. - - parameter version: The release date of the version of the API to use. Specify the date - in "YYYY-MM-DD" format. + - parameter version: Release date of the API version you want to use. Specify dates in YYYY-MM-DD format. The + current version is `2018-03-19`. - parameter authenticator: The Authenticator object used to authenticate requests to the service */ public init(version: String, authenticator: Authenticator) { @@ -79,6 +93,7 @@ public class VisualRecognition { self.authenticator = authenticator RestRequest.userAgent = Shared.userAgent } + #endif #if !os(Linux) /** @@ -97,7 +112,7 @@ public class VisualRecognition { - parameter data: Raw data returned by the service that may represent an error. - parameter response: the URL response returned by the service. */ - func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> WatsonError { + func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> RestError { let statusCode = response.statusCode var errorMessage: String? @@ -114,16 +129,6 @@ public class VisualRecognition { errorMessage = message } else if case let .some(.string(message)) = json["message"] { errorMessage = message - // ErrorAuthentication - } else if case let .some(.string(message)) = json["statusInfo"] { - errorMessage = message - // ErrorInfo - } else if case let .some(.object(errorObj)) = json["error"], // 404 - case let .some(.string(message)) = errorObj["description"] { - errorMessage = message - // ErrorHTML - } else if case let .some(.string(message)) = json["Error"] { // 413 - errorMessage = message } else { errorMessage = HTTPURLResponse.localizedString(forStatusCode: response.statusCode) } @@ -132,7 +137,7 @@ public class VisualRecognition { errorMessage = HTTPURLResponse.localizedString(forStatusCode: response.statusCode) } - return WatsonError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) + return RestError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) } /** @@ -198,27 +203,27 @@ public class VisualRecognition { multipartFormData.append(thresholdData, withName: "threshold") } } - - // HAND EDIT: concat owners into csv data - if let csvOwners = owners?.joined(separator: ",").data(using: .utf8) { - multipartFormData.append(csvOwners, withName: "owners") + if let owners = owners { + for item in owners { + if let itemData = item.data(using: .utf8) { + multipartFormData.append(itemData, withName: "owners") + } + } } - - // HAND EDIT: concat classifier IDs into csv data - if let csvClassifierIDs = classifierIDs?.joined(separator: ",").data(using: .utf8) { - multipartFormData.append(csvClassifierIDs, withName: "classifier_ids") + if let classifierIDs = classifierIDs { + for item in classifierIDs { + if let itemData = item.data(using: .utf8) { + multipartFormData.append(itemData, withName: "classifier_ids") + } + } } - guard let body = try? multipartFormData.toData() else { - completionHandler(nil, WatsonError.serialization(values: "request multipart form data")) + completionHandler(nil, RestError.serialization(values: "request multipart form data")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "classify") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" @@ -226,6 +231,9 @@ public class VisualRecognition { if let acceptLanguage = acceptLanguage { headerParameters["Accept-Language"] = acceptLanguage } + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -235,7 +243,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -299,25 +307,25 @@ public class VisualRecognition { } positiveExamples.forEach { (classname, value) in let partName = "\(classname)_positive_examples" - multipartFormData.append(value, withName: partName, fileName: "\(classname).zip") + multipartFormData.append(value, withName: partName, fileName: classname) } if let negativeExamples = negativeExamples { - multipartFormData.append(negativeExamples, withName: "negative_examples", fileName: negativeExamplesFilename ?? "filename.zip") + multipartFormData.append(negativeExamples, withName: "negative_examples", fileName: negativeExamplesFilename ?? "filename") } guard let body = try? multipartFormData.toData() else { - completionHandler(nil, WatsonError.serialization(values: "request multipart form data")) + completionHandler(nil, RestError.serialization(values: "request multipart form data")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "createClassifier") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = multipartFormData.contentType + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -327,7 +335,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -361,12 +369,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listClassifiers") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -380,7 +388,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -414,12 +422,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getClassifier") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -428,13 +436,13 @@ public class VisualRecognition { // construct REST request let path = "/v3/classifiers/\(classifierID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -498,26 +506,26 @@ public class VisualRecognition { if let positiveExamples = positiveExamples { positiveExamples.forEach { (classname, value) in let partName = "\(classname)_positive_examples" - multipartFormData.append(value, withName: partName, fileName: "\(classname).zip") + multipartFormData.append(value, withName: partName, fileName: classname) } } if let negativeExamples = negativeExamples { - multipartFormData.append(negativeExamples, withName: "negative_examples", fileName: negativeExamplesFilename ?? "filename.zip") + multipartFormData.append(negativeExamples, withName: "negative_examples", fileName: negativeExamplesFilename ?? "filename") } guard let body = try? multipartFormData.toData() else { - completionHandler(nil, WatsonError.serialization(values: "request multipart form data")) + completionHandler(nil, RestError.serialization(values: "request multipart form data")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "updateClassifier") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = multipartFormData.contentType + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -526,13 +534,13 @@ public class VisualRecognition { // construct REST request let path = "/v3/classifiers/\(classifierID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -565,12 +573,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteClassifier") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -579,13 +587,13 @@ public class VisualRecognition { // construct REST request let path = "/v3/classifiers/\(classifierID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -620,12 +628,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getCoreMLModel") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/octet-stream" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -634,13 +642,13 @@ public class VisualRecognition { // construct REST request let path = "/v3/classifiers/\(classifierID)/core_ml_model" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -678,12 +686,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteUserData") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -694,7 +702,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } diff --git a/Sources/VisualRecognitionV4/Models/BaseCollection.swift b/Sources/VisualRecognitionV4/Models/BaseCollection.swift deleted file mode 100644 index dbf9bbc59..000000000 --- a/Sources/VisualRecognitionV4/Models/BaseCollection.swift +++ /dev/null @@ -1,105 +0,0 @@ -/** - * (C) Copyright IBM Corp. 2019. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -import Foundation - -/** - Base details about a collection. - */ -internal struct BaseCollection: Codable, Equatable { - - /** - The identifier of the collection. - */ - public var collectionID: String? - - /** - The name of the collection. The name can contain alphanumeric, underscore, hyphen, and dot characters. It cannot - begin with the reserved prefix `sys-`. - */ - public var name: String? - - /** - The description of the collection. - */ - public var description: String? - - /** - Date and time in Coordinated Universal Time (UTC) that the collection was created. - */ - public var created: Date? - - /** - Date and time in Coordinated Universal Time (UTC) that the collection was most recently updated. - */ - public var updated: Date? - - /** - Number of images in the collection. - */ - public var imageCount: Int? - - /** - Training status information for the collection. - */ - public var trainingStatus: TrainingStatus? - - // Map each property name to the key that shall be used for encoding/decoding. - private enum CodingKeys: String, CodingKey { - case collectionID = "collection_id" - case name = "name" - case description = "description" - case created = "created" - case updated = "updated" - case imageCount = "image_count" - case trainingStatus = "training_status" - } - - /** - Initialize a `BaseCollection` with member variables. - - - parameter collectionID: The identifier of the collection. - - parameter name: The name of the collection. The name can contain alphanumeric, underscore, hyphen, and dot - characters. It cannot begin with the reserved prefix `sys-`. - - parameter description: The description of the collection. - - parameter created: Date and time in Coordinated Universal Time (UTC) that the collection was created. - - parameter updated: Date and time in Coordinated Universal Time (UTC) that the collection was most recently - updated. - - parameter imageCount: Number of images in the collection. - - parameter trainingStatus: Training status information for the collection. - - - returns: An initialized `BaseCollection`. - */ - public init( - collectionID: String? = nil, - name: String? = nil, - description: String? = nil, - created: Date? = nil, - updated: Date? = nil, - imageCount: Int? = nil, - trainingStatus: TrainingStatus? = nil - ) - { - self.collectionID = collectionID - self.name = name - self.description = description - self.created = created - self.updated = updated - self.imageCount = imageCount - self.trainingStatus = trainingStatus - } - -} diff --git a/Sources/VisualRecognitionV4/Models/Collection.swift b/Sources/VisualRecognitionV4/Models/Collection.swift index e051656c4..79c9c2b2b 100644 --- a/Sources/VisualRecognitionV4/Models/Collection.swift +++ b/Sources/VisualRecognitionV4/Models/Collection.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ public struct Collection: Codable, Equatable { /** Training status information for the collection. */ - public var trainingStatus: TrainingStatus + public var trainingStatus: CollectionTrainingStatus // Map each property name to the key that shall be used for encoding/decoding. private enum CodingKeys: String, CodingKey { diff --git a/Sources/VisualRecognitionV4/Models/BaseTrainingDataObjects.swift b/Sources/VisualRecognitionV4/Models/CollectionTrainingStatus.swift similarity index 59% rename from Sources/VisualRecognitionV4/Models/BaseTrainingDataObjects.swift rename to Sources/VisualRecognitionV4/Models/CollectionTrainingStatus.swift index f37b8cdf6..df0ecc78c 100644 --- a/Sources/VisualRecognitionV4/Models/BaseTrainingDataObjects.swift +++ b/Sources/VisualRecognitionV4/Models/CollectionTrainingStatus.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,32 +17,18 @@ import Foundation /** - Container for the training data. + Training status information for the collection. */ -internal struct BaseTrainingDataObjects: Codable, Equatable { +public struct CollectionTrainingStatus: Codable, Equatable { /** - Training data for specific objects. + Training status for the objects in the collection. */ - public var objects: [TrainingDataObject]? + public var objects: ObjectTrainingStatus // Map each property name to the key that shall be used for encoding/decoding. private enum CodingKeys: String, CodingKey { case objects = "objects" } - /** - Initialize a `BaseTrainingDataObjects` with member variables. - - - parameter objects: Training data for specific objects. - - - returns: An initialized `BaseTrainingDataObjects`. - */ - public init( - objects: [TrainingDataObject]? = nil - ) - { - self.objects = objects - } - } diff --git a/Sources/VisualRecognitionV4/Models/ObjectDetail.swift b/Sources/VisualRecognitionV4/Models/ObjectDetail.swift index dc3e9ee58..7819963dd 100644 --- a/Sources/VisualRecognitionV4/Models/ObjectDetail.swift +++ b/Sources/VisualRecognitionV4/Models/ObjectDetail.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ public struct ObjectDetail: Codable, Equatable { /** Defines the location of the bounding box around the object. */ - public var location: Location + public var location: ObjectDetailLocation /** Confidence score for the object in the range of 0 to 1. A higher score indicates greater likelihood that the object diff --git a/Sources/TextToSpeechV1/Models/Text.swift b/Sources/VisualRecognitionV4/Models/ObjectDetailLocation.swift similarity index 56% rename from Sources/TextToSpeechV1/Models/Text.swift rename to Sources/VisualRecognitionV4/Models/ObjectDetailLocation.swift index b719c8663..0abffd9d2 100644 --- a/Sources/TextToSpeechV1/Models/Text.swift +++ b/Sources/VisualRecognitionV4/Models/ObjectDetailLocation.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2018, 2019. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,33 +17,36 @@ import Foundation /** - The text to synthesize. Specify either plain text or a subset of SSML. SSML is an XML-based markup language that - provides text annotation for speech-synthesis applications. Pass a maximum of 5 KB of input text. + Defines the location of the bounding box around the object. */ -internal struct Text: Codable, Equatable { +public struct ObjectDetailLocation: Codable, Equatable { /** - The text to synthesize. + Y-position of top-left pixel of the bounding box. */ - public var text: String - - // Map each property name to the key that shall be used for encoding/decoding. - private enum CodingKeys: String, CodingKey { - case text = "text" - } + public var top: Int /** - Initialize a `Text` with member variables. + X-position of top-left pixel of the bounding box. + */ + public var left: Int - - parameter text: The text to synthesize. + /** + Width in pixels of of the bounding box. + */ + public var width: Int - - returns: An initialized `Text`. + /** + Height in pixels of the bounding box. */ - public init( - text: String - ) - { - self.text = text + public var height: Int + + // Map each property name to the key that shall be used for encoding/decoding. + private enum CodingKeys: String, CodingKey { + case top = "top" + case left = "left" + case width = "width" + case height = "height" } } diff --git a/Sources/VisualRecognitionV4/Models/UpdateObjectMetadata.swift b/Sources/VisualRecognitionV4/Models/UpdateObjectMetadata.swift index e1723b330..1124cc583 100644 --- a/Sources/VisualRecognitionV4/Models/UpdateObjectMetadata.swift +++ b/Sources/VisualRecognitionV4/Models/UpdateObjectMetadata.swift @@ -43,17 +43,14 @@ public struct UpdateObjectMetadata: Codable, Equatable { - parameter object: The updated name of the object. The name can contain alphanumeric, underscore, hyphen, space, and dot characters. It cannot begin with the reserved prefix `sys-`. - - parameter count: Number of bounding boxes in the collection with the updated object name. - returns: An initialized `UpdateObjectMetadata`. */ public init( - object: String, - count: Int? = nil + object: String ) { self.object = object - self.count = count } } diff --git a/Sources/VisualRecognitionV4/VisualRecognition.swift b/Sources/VisualRecognitionV4/VisualRecognition.swift index 400a7ddb9..7d660d8a0 100644 --- a/Sources/VisualRecognitionV4/VisualRecognition.swift +++ b/Sources/VisualRecognitionV4/VisualRecognition.swift @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2019, 2020. + * (C) Copyright IBM Corp. 2020. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + +/** + * IBM OpenAPI SDK Code Generator Version: 99-SNAPSHOT-36b26b63-20201028-122900 + **/ + // swiftlint:disable file_length import Foundation +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif import IBMSwiftSDKCore +public typealias WatsonError = RestError +public typealias WatsonResponse = RestResponse /** Provide images to the IBM Watson™ Visual Recognition service for analysis. The service detects objects based on a set of images with training data. @@ -27,8 +37,14 @@ public class VisualRecognition { /// The base URL to use when contacting the service. public var serviceURL: String? = "https://api.us-south.visual-recognition.watson.cloud.ibm.com" + /// Release date of the API version you want to use. Specify dates in YYYY-MM-DD format. The current version is + /// `2019-02-11`. + public var version: String + /// Service identifiers - internal let serviceName = "WatsonVisionCombined" + public static let defaultServiceName = "watson_vision_combined" + // Service info for SDK headers + internal let serviceName = defaultServiceName internal let serviceVersion = "v4" internal let serviceSdkName = "visual_recognition" @@ -37,41 +53,39 @@ public class VisualRecognition { var session = URLSession(configuration: URLSessionConfiguration.default) public let authenticator: Authenticator - let version: String #if os(Linux) /** Create a `VisualRecognition` object. - This initializer will retrieve credentials from the environment or a local credentials file. + If an authenticator is not supplied, the initializer will retrieve credentials from the environment or + a local credentials file and construct an appropriate authenticator using these credentials. The credentials file can be downloaded from your service instance on IBM Cloud as ibm-credentials.env. Make sure to add the credentials file to your project so that it can be loaded at runtime. - If credentials are not available in the environment or a local credentials file, initialization will fail. + If an authenticator is not supplied and credentials are not available in the environment or a local + credentials file, initialization will fail by throwing an exception. In that case, try another initializer that directly passes in the credentials. - - parameter version: The release date of the version of the API to use. Specify the date - in "YYYY-MM-DD" format. + - parameter version: Release date of the API version you want to use. Specify dates in YYYY-MM-DD format. The + current version is `2019-02-11`. + - parameter authenticator: The Authenticator object used to authenticate requests to the service + - serviceName: String = defaultServiceName */ - public init(version: String) throws { + public init(version: String, authenticator: Authenticator? = nil, serviceName: String = defaultServiceName) throws { self.version = version - - let authenticator = try ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceSdkName) - self.authenticator = authenticator - - if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceSdkName) { + self.authenticator = try authenticator ?? ConfigBasedAuthenticatorFactory.getAuthenticator(credentialPrefix: serviceName) + if let serviceURL = CredentialUtils.getServiceURL(credentialPrefix: serviceName) { self.serviceURL = serviceURL } - RestRequest.userAgent = Shared.userAgent } - #endif - + #else /** Create a `VisualRecognition` object. - - parameter version: The release date of the version of the API to use. Specify the date - in "YYYY-MM-DD" format. + - parameter version: Release date of the API version you want to use. Specify dates in YYYY-MM-DD format. The + current version is `2019-02-11`. - parameter authenticator: The Authenticator object used to authenticate requests to the service */ public init(version: String, authenticator: Authenticator) { @@ -79,6 +93,7 @@ public class VisualRecognition { self.authenticator = authenticator RestRequest.userAgent = Shared.userAgent } + #endif #if !os(Linux) /** @@ -97,7 +112,7 @@ public class VisualRecognition { - parameter data: Raw data returned by the service that may represent an error. - parameter response: the URL response returned by the service. */ - func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> WatsonError { + func errorResponseDecoder(data: Data, response: HTTPURLResponse) -> RestError { let statusCode = response.statusCode var errorMessage: String? @@ -122,7 +137,7 @@ public class VisualRecognition { errorMessage = HTTPURLResponse.localizedString(forStatusCode: response.statusCode) } - return WatsonError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) + return RestError.http(statusCode: statusCode, message: errorMessage, metadata: metadata) } /** @@ -161,17 +176,16 @@ public class VisualRecognition { { // construct body let multipartFormData = MultipartFormData() - - // HAND EDIT: join collectionIDs into CSV string - if let csvCollectionIDsData = collectionIDs.joined(separator: ",").data(using: .utf8) { - multipartFormData.append(csvCollectionIDsData, withName: "collection_ids") + for item in collectionIDs { + if let itemData = item.data(using: .utf8) { + multipartFormData.append(itemData, withName: "collection_ids") + } } - - // HAND EDIT: join features into CSV string - if let csvFeaturesData = features.joined(separator: ",").data(using: .utf8) { - multipartFormData.append(csvFeaturesData, withName: "features") + for item in features { + if let itemData = item.data(using: .utf8) { + multipartFormData.append(itemData, withName: "features") + } } - if let imagesFile = imagesFile { for item in imagesFile { multipartFormData.append(item.data, withName: "images_file", mimeType: item.contentType, fileName: item.filename) @@ -190,19 +204,19 @@ public class VisualRecognition { } } guard let body = try? multipartFormData.toData() else { - completionHandler(nil, WatsonError.serialization(values: "request multipart form data")) + completionHandler(nil, RestError.serialization(values: "request multipart form data")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "analyze") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = multipartFormData.contentType + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -212,7 +226,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -242,33 +256,36 @@ public class VisualRecognition { - parameter name: The name of the collection. The name can contain alphanumeric, underscore, hyphen, and dot characters. It cannot begin with the reserved prefix `sys-`. - parameter description: The description of the collection. + - parameter trainingStatus: Training status information for the collection. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ public func createCollection( name: String? = nil, description: String? = nil, + trainingStatus: TrainingStatus? = nil, headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let createCollectionRequest = BaseCollection( + let createCollectionRequest = CreateCollectionRequest( name: name, - description: description) + description: description, + training_status: trainingStatus) guard let body = try? JSON.encoder.encode(createCollectionRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "createCollection") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -278,7 +295,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -297,6 +314,15 @@ public class VisualRecognition { request.responseObject(completionHandler: completionHandler) } + // Private struct for the createCollection request body + private struct CreateCollectionRequest: Encodable { + // swiftlint:disable identifier_name + let name: String? + let description: String? + let training_status: TrainingStatus? + // swiftlint:enable identifier_name + } + /** List collections. @@ -311,12 +337,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listCollections") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -326,7 +352,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -360,12 +386,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getCollection") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -374,13 +400,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -409,6 +435,7 @@ public class VisualRecognition { - parameter name: The name of the collection. The name can contain alphanumeric, underscore, hyphen, and dot characters. It cannot begin with the reserved prefix `sys-`. - parameter description: The description of the collection. + - parameter trainingStatus: Training status information for the collection. - parameter headers: A dictionary of request headers to be sent with this request. - parameter completionHandler: A function executed when the request completes with a successful result or error */ @@ -416,27 +443,32 @@ public class VisualRecognition { collectionID: String, name: String? = nil, description: String? = nil, + trainingStatus: TrainingStatus? = nil, headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let updateCollectionRequest = BaseCollection( + let updateCollectionRequest = UpdateCollectionRequest( name: name, - description: description) - guard let body = try? JSON.encoder.encodeIfPresent(updateCollectionRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + description: description, + training_status: trainingStatus) + let body: Data? + do { + body = try JSON.encoder.encodeIfPresent(updateCollectionRequest) + } catch { + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "updateCollection") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -445,13 +477,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -470,6 +502,23 @@ public class VisualRecognition { request.responseObject(completionHandler: completionHandler) } + // Private struct for the updateCollection request body + private struct UpdateCollectionRequest: Encodable { + // swiftlint:disable identifier_name + let name: String? + let description: String? + let training_status: TrainingStatus? + init? (name: String? = nil, description: String? = nil, training_status: TrainingStatus? = nil) { + if name == nil && description == nil && training_status == nil { + return nil + } + self.name = name + self.description = description + self.training_status = training_status + } + // swiftlint:enable identifier_name + } + /** Delete a collection. @@ -486,12 +535,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteCollection") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -500,13 +549,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -548,12 +597,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getModelFile") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/octet-stream" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -564,13 +613,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/model" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -642,19 +691,19 @@ public class VisualRecognition { } } guard let body = try? multipartFormData.toData() else { - completionHandler(nil, WatsonError.serialization(values: "request multipart form data")) + completionHandler(nil, RestError.serialization(values: "request multipart form data")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addImages") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = multipartFormData.contentType + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -663,13 +712,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/images" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -704,12 +753,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listImages") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -718,13 +767,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/images" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -760,12 +809,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getImageDetails") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -774,13 +823,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/images/\(imageID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -816,12 +865,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteImage") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -830,13 +879,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/images/\(imageID)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -876,12 +925,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getJpegImage") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "image/jpeg" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -894,13 +943,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/images/\(imageID)/jpeg" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -934,12 +983,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "listObjectMetadata") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -948,13 +997,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/objects" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -992,22 +1041,22 @@ public class VisualRecognition { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let updateObjectMetadataRequest = UpdateObjectMetadata( + let updateObjectMetadataRequest = UpdateObjectMetadataRequest( object: newObject) guard let body = try? JSON.encoder.encode(updateObjectMetadataRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "updateObjectMetadata") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1016,13 +1065,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/objects/\(object)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1041,6 +1090,13 @@ public class VisualRecognition { request.responseObject(completionHandler: completionHandler) } + // Private struct for the updateObjectMetadata request body + private struct UpdateObjectMetadataRequest: Encodable { + // swiftlint:disable identifier_name + let object: String + // swiftlint:enable identifier_name + } + /** Get object metadata. @@ -1059,12 +1115,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getObjectMetadata") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1073,13 +1129,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/objects/\(object)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1116,12 +1172,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteObject") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1130,13 +1186,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/objects/\(object)" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1172,12 +1228,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "train") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1186,13 +1242,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/train" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1233,22 +1289,22 @@ public class VisualRecognition { completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct body - let addImageTrainingDataRequest = BaseTrainingDataObjects( + let addImageTrainingDataRequest = AddImageTrainingDataRequest( objects: objects) guard let body = try? JSON.encoder.encode(addImageTrainingDataRequest) else { - completionHandler(nil, WatsonError.serialization(values: "request body")) + completionHandler(nil, RestError.serialization(values: "request body")) return } // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "addImageTrainingData") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" headerParameters["Content-Type"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1257,13 +1313,13 @@ public class VisualRecognition { // construct REST request let path = "/v4/collections/\(collectionID)/images/\(imageID)/training_data" guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { - completionHandler(nil, WatsonError.urlEncoding(path: path)) + completionHandler(nil, RestError.urlEncoding(path: path)) return } // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1282,6 +1338,13 @@ public class VisualRecognition { request.responseObject(completionHandler: completionHandler) } + // Private struct for the addImageTrainingData request body + private struct AddImageTrainingDataRequest: Encodable { + // swiftlint:disable identifier_name + let objects: [TrainingDataObject]? + // swiftlint:enable identifier_name + } + /** Get training usage. @@ -1297,29 +1360,29 @@ public class VisualRecognition { - parameter completionHandler: A function executed when the request completes with a successful result or error */ public func getTrainingUsage( - startTime: String? = nil, - endTime: String? = nil, + startTime: Date? = nil, + endTime: Date? = nil, headers: [String: String]? = nil, completionHandler: @escaping (WatsonResponse?, WatsonError?) -> Void) { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "getTrainingUsage") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() queryParameters.append(URLQueryItem(name: "version", value: version)) if let startTime = startTime { - let queryParameter = URLQueryItem(name: "start_time", value: startTime) + let queryParameter = URLQueryItem(name: "start_time", value: "\(startTime)") queryParameters.append(queryParameter) } if let endTime = endTime { - let queryParameter = URLQueryItem(name: "end_time", value: endTime) + let queryParameter = URLQueryItem(name: "end_time", value: "\(endTime)") queryParameters.append(queryParameter) } @@ -1327,7 +1390,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return } @@ -1365,12 +1428,12 @@ public class VisualRecognition { { // construct header parameters var headerParameters = defaultHeaders - if let headers = headers { - headerParameters.merge(headers) { (_, new) in new } - } let sdkHeaders = Shared.getSDKHeaders(serviceName: serviceName, serviceVersion: serviceVersion, methodName: "deleteUserData") headerParameters.merge(sdkHeaders) { (_, new) in new } headerParameters["Accept"] = "application/json" + if let headers = headers { + headerParameters.merge(headers) { (_, new) in new } + } // construct query parameters var queryParameters = [URLQueryItem]() @@ -1381,7 +1444,7 @@ public class VisualRecognition { // ensure that serviceURL is set guard let serviceEndpoint = serviceURL else { - completionHandler(nil, WatsonError.noEndpoint) + completionHandler(nil, RestError.noEndpoint) return }