sdk/communication/AzureCommunicationChat/Source/Generated/ChatThread.swift (1,600 lines of code) (raw):

// -------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for // license information. // // Code generated by Microsoft (R) AutoRest Code Generator. // Changes may cause incorrect behavior and will be lost if the code is // regenerated. // -------------------------------------------------------------------------- import AzureCore import Foundation // swiftlint:disable superfluous_disable_command // swiftlint:disable file_length // swiftlint:disable cyclomatic_complexity // swiftlint:disable function_body_length // swiftlint:disable type_body_length internal final class ChatThread { internal let client: ChatClientInternal init(client: ChatClientInternal) { self.client = client } /// Gets chat message read receipts for a thread. /// - Parameters: /// - chatThreadId : Thread id to get the chat message read receipts for. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func listChatReadReceipts( chatThreadId: String, withOptions options: ListChatReadReceiptsOptions? = nil, completionHandler: @escaping HTTPResultHandler<PagedCollection<ChatMessageReadReceiptInternal>> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.query, "maxPageSize", options?.maxPageSize, .encode), (.query, "skip", options?.skip, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Accept", "application/json", .encode) ) // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/readReceipts" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 200 ].contains(statusCode) { do { let decoder = JSONDecoder() let codingKeys = PagedCodingKeys( items: "value", continuationToken: "nextLink" ) let paged = try PagedCollection<ChatMessageReadReceiptInternal>( client: self.client, request: request, context: context, data: data, codingKeys: codingKeys, decoder: decoder ) dispatchQueue.async { completionHandler(.success(paged), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Sends a read receipt event to a thread, on behalf of a user. /// - Parameters: /// - chatReadReceipt : Read receipt details. /// - chatThreadId : Thread id to send the read receipt event to. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func send( chatReadReceipt: SendReadReceiptRequest, chatThreadId: String, withOptions options: SendChatReadReceiptOptions? = nil, completionHandler: @escaping HTTPResultHandler<Void> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Content-Type", "application/json", .encode), (.header, "Accept", "application/json", .encode) ) // Construct request guard let requestBody = try? JSONEncoder().encode(chatReadReceipt) else { client.options.logger.error("Failed to encode request body as json.") return } let urlTemplate = "/chat/threads/{chatThreadId}/readReceipts" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 200 ].contains(statusCode) { dispatchQueue.async { completionHandler( .success(()), httpResponse ) } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Sends a message to a thread. /// - Parameters: /// - chatMessage : Details of the message to send. /// - chatThreadId : The thread id to send the message to. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func send( chatMessage: SendChatMessageRequest, chatThreadId: String, withOptions options: SendChatMessageOptions? = nil, completionHandler: @escaping HTTPResultHandler<SendChatMessageResult> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Content-Type", "application/json", .encode), (.header, "Accept", "application/json", .encode) ) // Construct request guard let requestBody = try? JSONEncoder().encode(chatMessage) else { client.options.logger.error("Failed to encode request body as json.") return } let urlTemplate = "/chat/threads/{chatThreadId}/messages" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [201, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 201 ].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(SendChatMessageResult.self, from: data) dispatchQueue.async { completionHandler(.success(decoded), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Gets a list of messages from a thread. /// - Parameters: /// - chatThreadId : The thread id of the message. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func listChatMessages( chatThreadId: String, withOptions options: ListChatMessagesOptions? = nil, completionHandler: @escaping HTTPResultHandler<PagedCollection<ChatMessageInternal>> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.query, "maxPageSize", options?.maxPageSize, .encode), (.query, "startTime", options?.startTime, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Accept", "application/json", .encode) ) // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/messages" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 200 ].contains(statusCode) { do { let decoder = JSONDecoder() let codingKeys = PagedCodingKeys( items: "value", continuationToken: "nextLink" ) let paged = try PagedCollection<ChatMessageInternal>( client: self.client, request: request, context: context, data: data, codingKeys: codingKeys, decoder: decoder ) dispatchQueue.async { completionHandler(.success(paged), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Gets a message by id. /// - Parameters: /// - chatThreadId : The thread id to which the message was sent. /// - chatMessageId : The message id. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func getChatMessage( chatThreadId: String, chatMessageId: String, withOptions options: GetChatMessageOptions? = nil, completionHandler: @escaping HTTPResultHandler<ChatMessageInternal> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.path, "chatMessageId", chatMessageId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Accept", "application/json", .encode) ) // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/messages/{chatMessageId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 200 ].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(ChatMessageInternal.self, from: data) dispatchQueue.async { completionHandler(.success(decoded), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Updates a message. /// - Parameters: /// - chatMessage : Details of the request to update the message. /// - chatThreadId : The thread id to which the message was sent. /// - chatMessageId : The message id. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func update( chatMessage: UpdateChatMessageRequest, chatThreadId: String, chatMessageId: String, withOptions options: UpdateChatMessageOptions? = nil, completionHandler: @escaping HTTPResultHandler<Void> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.path, "chatMessageId", chatMessageId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Content-Type", "application/merge-patch+json", .encode), (.header, "Accept", "application/json", .encode) ) // Construct request guard let requestBody = try? JSONEncoder().encode(chatMessage) else { client.options.logger.error("Failed to encode request body as json.") return } let urlTemplate = "/chat/threads/{chatThreadId}/messages/{chatMessageId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest( method: .patch, url: requestUrl, headers: params.headers, data: requestBody ) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [204, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 204 ].contains(statusCode) { dispatchQueue.async { completionHandler( .success(()), httpResponse ) } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Deletes a message. /// - Parameters: /// - chatThreadId : The thread id to which the message was sent. /// - chatMessageId : The message id. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func deleteChatMessage( chatThreadId: String, chatMessageId: String, withOptions options: DeleteChatMessageOptions? = nil, completionHandler: @escaping HTTPResultHandler<Void> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.path, "chatMessageId", chatMessageId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Accept", "application/json", .encode) ) // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/messages/{chatMessageId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .delete, url: requestUrl, headers: params.headers) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [204, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 204 ].contains(statusCode) { dispatchQueue.async { completionHandler( .success(()), httpResponse ) } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Gets the participants of a thread. /// - Parameters: /// - chatThreadId : Thread id to get participants for. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func listChatParticipants( chatThreadId: String, withOptions options: ListChatParticipantsOptions? = nil, completionHandler: @escaping HTTPResultHandler<PagedCollection<ChatParticipantInternal>> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.query, "maxPageSize", options?.maxPageSize, .encode), (.query, "skip", options?.skip, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Accept", "application/json", .encode) ) // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/participants" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 200 ].contains(statusCode) { do { let decoder = JSONDecoder() let codingKeys = PagedCodingKeys( items: "value", continuationToken: "nextLink" ) let paged = try PagedCollection<ChatParticipantInternal>( client: self.client, request: request, context: context, data: data, codingKeys: codingKeys, decoder: decoder ) dispatchQueue.async { completionHandler(.success(paged), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Remove a participant from a thread. /// - Parameters: /// - chatParticipant : Id of the thread participant to remove from the thread. /// - chatThreadId : Thread id to remove the participant from. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func remove( chatParticipant: CommunicationIdentifierModelInternal, chatThreadId: String, withOptions options: RemoveChatParticipantOptions? = nil, completionHandler: @escaping HTTPResultHandler<Void> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Content-Type", "application/json", .encode), (.header, "Accept", "application/json", .encode) ) // Construct request guard let requestBody = try? JSONEncoder().encode(chatParticipant) else { client.options.logger.error("Failed to encode request body as json.") return } let urlTemplate = "/chat/threads/{chatThreadId}/participants/:remove" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [204, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 204 ].contains(statusCode) { dispatchQueue.async { completionHandler( .success(()), httpResponse ) } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Adds thread participants to a thread. If participants already exist, no change occurs. /// - Parameters: /// - chatParticipants : Thread participants to be added to the thread. /// - chatThreadId : Id of the thread to add participants to. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func add( chatParticipants: AddChatParticipantsRequestInternal, chatThreadId: String, withOptions options: AddChatParticipantsOptions? = nil, completionHandler: @escaping HTTPResultHandler<AddChatParticipantsResult> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Content-Type", "application/json", .encode), (.header, "Accept", "application/json", .encode) ) // Construct request guard let requestBody = try? JSONEncoder().encode(chatParticipants) else { client.options.logger.error("Failed to encode request body as json.") return } let urlTemplate = "/chat/threads/{chatThreadId}/participants/:add" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [201, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 201 ].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(AddChatParticipantsResult.self, from: data) dispatchQueue.async { completionHandler(.success(decoded), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Updates a thread's properties. /// - Parameters: /// - chatThreadProperties : Request payload for updating a chat thread. /// - chatThreadId : The id of the thread to update. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func update( chatThreadProperties: UpdateChatThreadRequestInternal, chatThreadId: String, withOptions options: UpdateChatThreadPropertiesOptions? = nil, completionHandler: @escaping HTTPResultHandler<Void> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Content-Type", "application/merge-patch+json", .encode), (.header, "Accept", "application/json", .encode) ) // Construct request guard let requestBody = try? JSONEncoder().encode(chatThreadProperties) else { client.options.logger.error("Failed to encode request body as json.") return } let urlTemplate = "/chat/threads/{chatThreadId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest( method: .patch, url: requestUrl, headers: params.headers, data: requestBody ) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [204, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 204 ].contains(statusCode) { dispatchQueue.async { completionHandler( .success(()), httpResponse ) } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Gets a chat thread's properties. /// - Parameters: /// - chatThreadId : Id of the thread. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func getChatThreadProperties( chatThreadId: String, withOptions options: GetChatThreadPropertiesOptions? = nil, completionHandler: @escaping HTTPResultHandler<ChatThreadPropertiesInternal> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Accept", "application/json", .encode) ) // Construct request let urlTemplate = "/chat/threads/{chatThreadId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 200 ].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(ChatThreadPropertiesInternal.self, from: data) dispatchQueue.async { completionHandler(.success(decoded), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } /// Posts a typing event to a thread, on behalf of a user. /// - Parameters: /// - typingNotification : Details of the typing notification request. /// - chatThreadId : Id of the thread. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. internal func send( typingNotification: SendTypingNotificationRequest?, chatThreadId: String, withOptions options: SendTypingNotificationOptions? = nil, completionHandler: @escaping HTTPResultHandler<Void> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Content-Type", "application/json", .encode), (.header, "Accept", "application/json", .encode) ) // Construct request var requestBody: Data? if typingNotification != nil { guard let encodedRequestBody = try? JSONEncoder().encode(typingNotification) else { client.options.logger.error("Failed to encode request body as json.") return } requestBody = encodedRequestBody } let urlTemplate = "/chat/threads/{chatThreadId}/typing" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) else { client.options.logger.error("Failed to construct HTTP request.") return } // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) client.request(request, context: context) { result, httpResponse in guard let data = httpResponse?.data else { let noDataError = AzureError.client("Response data expected but not found.") dispatchQueue.async { completionHandler(.failure(noDataError), httpResponse) } return } switch result { case .success: guard let statusCode = httpResponse?.statusCode else { let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") dispatchQueue.async { completionHandler(.failure(noStatusCodeError), httpResponse) } return } if [ 200 ].contains(statusCode) { dispatchQueue.async { completionHandler( .success(()), httpResponse ) } } if [401].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [403].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [429].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } if [503].contains(statusCode) { do { let decoder = JSONDecoder() let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } } catch { dispatchQueue.async { completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) } } } case let .failure(error): dispatchQueue.async { completionHandler(.failure(error), httpResponse) } } } } }