Skip to content

Commit ca03211

Browse files
authored
[Swift] shorter readme (#19884)
* [Swift] shorter readme * [Swift] update docs * [Swift] update docs * [Swift] format codegen * [Swift] try to make CI pass
1 parent 65b1859 commit ca03211

File tree

33 files changed

+215
-3077
lines changed

33 files changed

+215
-3077
lines changed

docs/faq-generators.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,8 @@ Here is a working sample that put's together all of this.
477477

478478
### How do I migrate from the Swift 5 generator to the swift 6 generator?
479479

480+
- Change the generator to the new `swift6` generator, e.g. `openapi-generator generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g swift6 -o /tmp/test/`
481+
- Check the `swift6` [URLSession](https://github.com/OpenAPITools/openapi-generator/tree/master/samples/client/petstore/swift6/urlsessionLibrary) and [Alamofire](https://github.com/OpenAPITools/openapi-generator/tree/master/samples/client/petstore/swift6/alamofireLibrary) samples.
480482
- The infrastructure files have been moved to a new directory called `Infrastructure`. Please delete the old ones.
481483
- The `AnyCodable` dependency has been removed and replaced with a new enum called `JSONValue`, allowing you to use this generator without external dependencies.
482484
- The `Combine` response is now deferred by default, meaning the request will only start when you begin listening to it. To restore the previous behavior, set the `combineDeferred` flag to `false`.

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift5ClientCodegen.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,6 @@ private static CodegenModel reconcileProperties(CodegenModel codegenModel,
366366
codegenModel.vars = codegenProperties;
367367
}
368368

369-
370369
return codegenModel;
371370
}
372371

@@ -847,7 +846,6 @@ public String toOperationId(String operationId) {
847846
operationId = camelize(sanitizeName("call_" + operationId), LOWERCASE_FIRST_LETTER);
848847
}
849848

850-
851849
return operationId;
852850
}
853851

@@ -1306,9 +1304,11 @@ public void postProcess() {
13061304
System.out.println("# swift5 generator is contributed by Bruno Coelho (https://github.com/4brunu). #");
13071305
System.out.println("# Please support his work directly via https://paypal.com/paypalme/4brunu \uD83D\uDE4F #");
13081306
System.out.println("# #");
1309-
System.out.println("# There is a new `swift6` generator, that is currently in beta. #");
1307+
System.out.println("# There is a new swift6 generator, that is currently in beta. #");
13101308
System.out.println("# Try it and give us your feedback. #");
13111309
System.out.println("# https://openapi-generator.tech/docs/generators/swift6 #");
1310+
System.out.println("# #");
1311+
System.out.println("# If you need help migrating from the swift5 to the swift6 generator, check the following url.#");
13121312
System.out.println("# https://openapi-generator.tech/docs/faq-generators/#how-do-i-migrate-from-the-swift-5-generator-to-the-swift-6-generator");
13131313
System.out.println("################################################################################");
13141314
}

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift6ClientCodegen.java

Lines changed: 66 additions & 109 deletions
Large diffs are not rendered by default.

modules/openapi-generator/src/main/resources/swift5/README.mustache

Lines changed: 7 additions & 237 deletions
Original file line numberDiff line numberDiff line change
@@ -78,250 +78,20 @@ Class | Method | HTTP request | Description
7878

7979
{{/authMethods}}
8080

81-
{{#useURLSession}}
82-
### How do I implement bearer token authentication with URLSession on the Swift 5 API client?
83-
84-
First you subclass RequestBuilderFactory
85-
```
86-
class BearerRequestBuilderFactory: RequestBuilderFactory {
87-
func getNonDecodableBuilder<T>() -> RequestBuilder<T>.Type {
88-
BearerRequestBuilder<T>.self
89-
}
90-
91-
func getBuilder<T: Decodable>() -> RequestBuilder<T>.Type {
92-
BearerDecodableRequestBuilder<T>.self
93-
}
94-
}
95-
```
96-
97-
Then you subclass URLSessionRequestBuilder and URLSessionDecodableRequestBuilder
98-
```
99-
class BearerRequestBuilder<T>: URLSessionRequestBuilder<T> {
100-
@discardableResult
101-
override func execute(_ apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, _ completion: @escaping (Result<Response<T>, ErrorResponse>) -> Void) -> RequestTask {
102-
103-
// Before making the request, we can validate if we have a bearer token to be able to make a request
104-
BearerTokenHandler.refreshTokenIfDoesntExist {
105-
106-
// Here we make the request
107-
super.execute(apiResponseQueue) { result in
108-
109-
switch result {
110-
case .success:
111-
// If we got a successful response, we send the response to the completion block
112-
completion(result)
113-
114-
case let .failure(error):
115-
116-
// If we got a failure response, we will analyse the error to see what we should do with it
117-
if case let ErrorResponse.error(_, data, response, error) = error {
118-
119-
// If the error is an ErrorResponse.error() we will analyse it to see if it's a 401, and if it's a 401, we will refresh the token and retry the request
120-
BearerTokenHandler.refreshTokenIfUnauthorizedRequestResponse(
121-
data: data,
122-
response: response,
123-
error: error
124-
) { wasTokenRefreshed in
125-
126-
if wasTokenRefreshed {
127-
// If the token was refreshed, it's because it was a 401 error, so we refreshed the token, and we are going to retry the request by calling self.execute()
128-
self.execute(apiResponseQueue, completion)
129-
} else {
130-
// If the token was not refreshed, it's because it was not a 401 error, so we send the response to the completion block
131-
completion(result)
132-
}
133-
}
134-
} else {
135-
// If it's an unknown error, we send the response to the completion block
136-
completion(result)
137-
}
138-
139-
}
140-
}
141-
}
142-
143-
return requestTask
144-
}
145-
}
146-
147-
class BearerDecodableRequestBuilder<T: Decodable>: URLSessionDecodableRequestBuilder<T> {
148-
@discardableResult
149-
override func execute(_ apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, _ completion: @escaping (Result<Response<T>, ErrorResponse>) -> Void) -> RequestTask {
150-
// Before making the request, we can validate if we have a bearer token to be able to make a request
151-
BearerTokenHandler.refreshTokenIfDoesntExist {
152-
153-
// Here we make the request
154-
super.execute(apiResponseQueue) { result in
155-
156-
switch result {
157-
case .success:
158-
// If we got a successful response, we send the response to the completion block
159-
completion(result)
160-
161-
case let .failure(error):
162-
163-
// If we got a failure response, we will analyse the error to see what we should do with it
164-
if case let ErrorResponse.error(_, data, response, error) = error {
165-
166-
// If the error is an ErrorResponse.error() we will analyse it to see if it's a 401, and if it's a 401, we will refresh the token and retry the request
167-
BearerTokenHandler.refreshTokenIfUnauthorizedRequestResponse(
168-
data: data,
169-
response: response,
170-
error: error
171-
) { wasTokenRefreshed in
172-
173-
if wasTokenRefreshed {
174-
// If the token was refreshed, it's because it was a 401 error, so we refreshed the token, and we are going to retry the request by calling self.execute()
175-
self.execute(apiResponseQueue, completion)
176-
} else {
177-
// If the token was not refreshed, it's because it was not a 401 error, so we send the response to the completion block
178-
completion(result)
179-
}
180-
}
181-
} else {
182-
// If it's an unknown error, we send the response to the completion block
183-
completion(result)
184-
}
185-
186-
}
187-
}
188-
}
189-
190-
return requestTask
191-
}
192-
}
193-
194-
class BearerTokenHandler {
195-
private static var bearerToken: String? = nil
196-
197-
static func refreshTokenIfDoesntExist(completionHandler: @escaping () -> Void) {
198-
if bearerToken != nil {
199-
completionHandler()
200-
} else {
201-
startRefreshingToken {
202-
completionHandler()
203-
}
204-
}
205-
}
206-
207-
static func refreshTokenIfUnauthorizedRequestResponse(data: Data?, response: URLResponse?, error: Error?, completionHandler: @escaping (Bool) -> Void) {
208-
if let response = response as? HTTPURLResponse, response.statusCode == 401 {
209-
startRefreshingToken {
210-
completionHandler(true)
211-
}
212-
} else {
213-
completionHandler(false)
214-
}
215-
}
216-
217-
private static func startRefreshingToken(completionHandler: @escaping () -> Void) {
218-
// Get a bearer token
219-
let dummyBearerToken = "..."
220-
221-
bearerToken = dummyBearerToken
222-
PetstoreClientAPI.customHeaders["Authorization"] = "Bearer \(dummyBearerToken)"
223-
224-
completionHandler()
225-
}
226-
}
227-
```
228-
229-
Then you assign the `BearerRequestBuilderFactory` to the property `requestBuilderFactory`.
81+
# How do I migrate from the Swift 5 generator to the swift 6 generator?
23082

231-
`PetstoreClientAPI.requestBuilderFactory = BearerRequestBuilderFactory()`
83+
https://openapi-generator.tech/docs/faq-generators#how-do-i-migrate-from-the-swift-5-generator-to-the-swift-6-generator
84+
{{#useURLSession}}
23285

233-
The name `PetstoreClientAPI.requestBuilderFactory` will change depending on your project name.
86+
### How do I implement bearer token authentication with URLSession on the Swift 5 API client?
23487

235-
Here is a working sample that put's together all of this.
236-
[AppDelegate.swift](https://github.com/OpenAPITools/openapi-generator/blob/master/samples/client/petstore/swift5/urlsessionLibrary/SwaggerClientTests/SwaggerClient/AppDelegate.swift)
237-
[BearerDecodableRequestBuilder.swift](https://github.com/OpenAPITools/openapi-generator/blob/master/samples/client/petstore/swift5/urlsessionLibrary/SwaggerClientTests/SwaggerClient/BearerDecodableRequestBuilder.swift)
88+
https://openapi-generator.tech/docs/faq-generators#how-do-i-implement-bearer-token-authentication-with-urlsession-on-the-swift-5-api-client
23889
{{/useURLSession}}
23990
{{#useAlamofire}}
240-
### How do I implement bearer token authentication with Alamofire on the Swift 5 API client?
241-
242-
First you subclass RequestBuilderFactory
243-
```
244-
class BearerRequestBuilderFactory: RequestBuilderFactory {
245-
func getNonDecodableBuilder<T>() -> RequestBuilder<T>.Type {
246-
BearerRequestBuilder<T>.self
247-
}
248-
249-
func getBuilder<T: Decodable>() -> RequestBuilder<T>.Type {
250-
BearerDecodableRequestBuilder<T>.self
251-
}
252-
}
253-
```
254-
255-
Then you subclass AlamofireRequestBuilder and AlamofireDecodableRequestBuilder
256-
```
257-
class BearerRequestBuilder<T>: AlamofireRequestBuilder<T> {
258-
override func createSessionManager() -> SessionManager {
259-
let sessionManager = super.createSessionManager()
260-
261-
let bearerTokenHandler = BearerTokenHandler()
262-
sessionManager.adapter = bearerTokenHandler
263-
sessionManager.retrier = bearerTokenHandler
264-
265-
return sessionManager
266-
}
267-
}
26891

269-
class BearerDecodableRequestBuilder<T: Decodable>: AlamofireDecodableRequestBuilder<T> {
270-
override func createSessionManager() -> SessionManager {
271-
let sessionManager = super.createSessionManager()
272-
273-
let bearerTokenHandler = BearerTokenHandler()
274-
sessionManager.adapter = bearerTokenHandler
275-
sessionManager.retrier = bearerTokenHandler
276-
277-
return sessionManager
278-
}
279-
}
280-
281-
class BearerTokenHandler: RequestAdapter, RequestRetrier {
282-
private static var bearerToken: String? = nil
283-
284-
func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
285-
if let bearerToken = Self.bearerToken {
286-
var urlRequest = urlRequest
287-
urlRequest.setValue("Bearer \(bearerToken)", forHTTPHeaderField: "Authorization")
288-
return urlRequest
289-
}
290-
291-
return urlRequest
292-
}
293-
294-
func should(_: SessionManager, retry request: Request, with _: Error, completion: @escaping RequestRetryCompletion) {
295-
if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {
296-
Self.startRefreshingToken { isTokenRefreshed in
297-
completion(isTokenRefreshed, 0.0)
298-
}
299-
} else {
300-
completion(false, 0.0)
301-
}
302-
}
303-
304-
private static func startRefreshingToken(completionHandler: @escaping (Bool) -> Void) {
305-
// Get a bearer token
306-
let dummyBearerToken = "..."
307-
308-
bearerToken = dummyBearerToken
309-
PetstoreClientAPI.customHeaders["Authorization"] = "Bearer \(dummyBearerToken)"
310-
311-
completionHandler(true)
312-
}
313-
}
314-
```
315-
316-
Then you assign the `BearerRequestBuilderFactory` to the property `requestBuilderFactory`.
317-
318-
`PetstoreClientAPI.requestBuilderFactory = BearerRequestBuilderFactory()`
319-
320-
The name `PetstoreClientAPI.requestBuilderFactory` will change depending on your project name.
92+
### How do I implement bearer token authentication with Alamofire on the Swift 5 API client?
32193

322-
Here is a working sample that put's together all of this.
323-
[AppDelegate.swift](https://github.com/OpenAPITools/openapi-generator/blob/master/samples/client/petstore/swift5/alamofireLibrary/SwaggerClientTests/SwaggerClient/AppDelegate.swift)
324-
[BearerTokenHandler.swift](https://github.com/OpenAPITools/openapi-generator/blob/master/samples/client/petstore/swift5/alamofireLibrary/SwaggerClientTests/SwaggerClient/BearerDecodableRequestBuilder.swift)
94+
https://openapi-generator.tech/docs/faq-generators#how-do-i-implement-bearer-token-authentication-with-alamofire-on-the-swift-5-api-client
32595
{{/useAlamofire}}
32696

32797
## Author

0 commit comments

Comments
 (0)