@@ -3,20 +3,13 @@ import Foundation
33typealias QueueServiceSuccess = ( Data ) -> Void
44typealias QueueServiceFailure = ( Error , String ) -> Void
55
6- class ApiClient {
6+ @MainActor
7+ final class ApiClient {
78 static let API_ROOT = " https://%@.queue-it.net/api/mobileapp/queue "
89 static let TESTING_API_ROOT = " https://%@.test.queue-it.net/api/mobileapp/queue "
9- private static var testingIsEnabled = false
10- private static var sharedInstance : ApiClient ?
10+ private var testingIsEnabled = false
1111
12- static func getInstance( ) -> ApiClient {
13- if sharedInstance == nil {
14- sharedInstance = Connection ( )
15- }
16- return sharedInstance!
17- }
18-
19- static func setTesting( _ enabled: Bool ) {
12+ func setTesting( _ enabled: Bool ) {
2013 testingIsEnabled = enabled
2114 }
2215
@@ -29,10 +22,8 @@ class ApiClient {
2922 layoutName: String ? ,
3023 language: String ? ,
3124 enqueueToken: String ? ,
32- enqueueKey: String ? ,
33- success: @escaping ( Status ? ) -> Void ,
34- failure: @escaping QueueServiceFailure
35- ) {
25+ enqueueKey: String ?
26+ ) async throws -> Status ? {
3627 var bodyDict : [ String : Any ] = [
3728 " userId " : userId,
3829 " userAgent " : userAgent,
@@ -55,68 +46,102 @@ class ApiClient {
5546 bodyDict [ " enqueueKey " ] = enqueueKey
5647 }
5748
58- let apiRoot = ApiClient . testingIsEnabled ? ApiClient . TESTING_API_ROOT : ApiClient . API_ROOT
49+ let apiRoot = testingIsEnabled ? ApiClient . TESTING_API_ROOT : ApiClient . API_ROOT
5950 var urlAsString = String ( format: apiRoot, customerId)
6051 urlAsString += " / \( customerId) "
6152 urlAsString += " / \( eventOrAliasId) "
6253 urlAsString += " /enqueue "
6354
64- submitPOSTPath (
65- path: urlAsString,
66- body: bodyDict,
67- success: { data in
68- do {
69- if let userDict = try JSONSerialization . jsonObject (
70- with: data,
71- options: [ ]
72- ) as? [ String : Any ] {
73- let Status = Status ( dictionary: userDict)
74- success ( Status)
75- } else {
76- success ( nil )
77- }
78- } catch {
79- success ( nil )
80- }
81- } ,
82- failure: failure
83- )
55+ let data = try await submitPOSTPath ( path: urlAsString, body: bodyDict)
56+ do {
57+ if let userDict = try JSONSerialization . jsonObject (
58+ with: data,
59+ options: [ ]
60+ ) as? [ String : Any ] {
61+ return Status ( dictionary: userDict)
62+ } else {
63+ return nil
64+ }
65+ } catch {
66+ return nil
67+ }
8468 }
69+ }
8570
71+ private extension ApiClient {
8672 func submitPOSTPath(
8773 path: String ,
88- body bodyDict: [ String : Any ] ,
89- success: @escaping QueueServiceSuccess ,
90- failure: @escaping QueueServiceFailure
91- ) {
74+ body bodyDict: [ String : Any ]
75+ ) async throws -> Data {
9276 guard let url = URL ( string: path) else {
9377 let error = NSError (
9478 domain: " ApiClient " ,
9579 code: - 1 ,
9680 userInfo: [ NSLocalizedDescriptionKey: " Invalid URL " ]
9781 )
98- failure ( error, " Invalid URL " )
99- return
82+ throw error
10083 }
10184
102- submitRequest (
85+ return try await submitRequest (
10386 with: url,
10487 method: " POST " ,
105- body: bodyDict,
106- expectedStatus: 200 ,
107- success: success,
108- failure: failure
88+ body: bodyDict
10989 )
11090 }
11191
11292 func submitRequest(
113- with _: URL ,
114- method _: String ,
115- body _: [ String : Any ] ,
116- expectedStatus _: Int ,
117- success _: @escaping QueueServiceSuccess ,
118- failure _: @escaping QueueServiceFailure
119- ) {
120- return
93+ with url: URL ,
94+ method httpMethod: String ,
95+ body bodyDict: [ String : Any ]
96+ ) async throws -> Data {
97+ var request = URLRequest ( url: url)
98+ request. httpMethod = httpMethod
99+
100+ do {
101+ let jsonData = try JSONSerialization . data ( withJSONObject: bodyDict, options: [ ] )
102+ request. httpBody = jsonData
103+ } catch {
104+ throw error
105+ }
106+
107+ request. addValue ( " application/json " , forHTTPHeaderField: " Accept " )
108+ request. addValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
109+
110+ return try await initiateRequest ( request: request)
121111 }
112+
113+ func initiateRequest( request: URLRequest ) async throws -> Data {
114+ let ( data, response) = try await URLSession . shared. data ( for: request)
115+
116+ guard let response = response as? HTTPURLResponse else {
117+ throw ApiClientError . nilResponse
118+ }
119+
120+ let actualStatusCode = response. statusCode
121+ if actualStatusCode == 200 {
122+ return data
123+ } else {
124+ var message = " Unexpected response code: \( actualStatusCode) "
125+ if actualStatusCode >= 400 , actualStatusCode < 500 {
126+ if let decodedMessage = String ( data: data, encoding: . ascii) {
127+ message = decodedMessage
128+ }
129+ } else if let json = try ? JSONSerialization . jsonObject ( with: data, options: [ ] ) ,
130+ let jsonDict = json as? [ String : Any ] ,
131+ let errorMessage = jsonDict [ " error " ] as? String
132+ {
133+ message = errorMessage
134+ }
135+
136+ throw NSError (
137+ domain: " QueueService " ,
138+ code: actualStatusCode,
139+ userInfo: [ NSLocalizedDescriptionKey: message]
140+ )
141+ }
142+ }
143+ }
144+
145+ enum ApiClientError : Error {
146+ case nilResponse
122147}
0 commit comments