Skip to content

Commit ebb1221

Browse files
feat: update to Swift 6 and modernize codebase
- Upgrade swift-tools-version to 6.0 in Package.swift - Update iOS deployment target to v15 - Refactor ApiClient to use async/await - Remove Connection and ConnectionRequest classes - Add @mainactor annotations to relevant methods - Ensure Status struct conforms to Sendable - Update various protocols and methods to use async/await
1 parent c7a2025 commit ebb1221

File tree

11 files changed

+204
-326
lines changed

11 files changed

+204
-326
lines changed

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
// swift-tools-version:5.3
1+
// swift-tools-version:6.0
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
55

66
let package = Package(
77
name: "QueueITLibrary",
88
platforms: [
9-
.iOS(.v11),
9+
.iOS(.v15),
1010
],
1111
products: [
1212
.library(

Sources/QueueITLib/ApiClient.swift

Lines changed: 80 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,13 @@ import Foundation
33
typealias QueueServiceSuccess = (Data) -> Void
44
typealias 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
}

Sources/QueueITLib/Connection.swift

Lines changed: 0 additions & 42 deletions
This file was deleted.

Sources/QueueITLib/ConnectionRequest.swift

Lines changed: 0 additions & 97 deletions
This file was deleted.

0 commit comments

Comments
 (0)