Skip to content

Commit 820417b

Browse files
committed
Implement different date formats
1 parent f30d4b0 commit 820417b

File tree

7 files changed

+125
-17
lines changed

7 files changed

+125
-17
lines changed

modules/swagger-codegen/src/main/resources/swift4/CodableHelper.mustache

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import Foundation
99

1010
public typealias EncodeResult = (data: Data?, error: Error?)
1111

12+
enum DateError: String, Error {
13+
case invalidDate
14+
}
15+
1216
open class CodableHelper {
1317
1418
open static var dateformatter: DateFormatter?
@@ -18,16 +22,39 @@ open class CodableHelper {
1822
var returnedError: Error? = nil
1923
2024
let decoder = JSONDecoder()
25+
2126
if let df = self.dateformatter {
2227
decoder.dateDecodingStrategy = .formatted(df)
2328
} else {
2429
decoder.dataDecodingStrategy = .base64
25-
let formatter = DateFormatter()
26-
formatter.calendar = Calendar(identifier: .iso8601)
27-
formatter.locale = Locale(identifier: "en_US_POSIX")
28-
formatter.timeZone = TimeZone(secondsFromGMT: 0)
29-
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
30-
decoder.dateDecodingStrategy = .formatted(formatter)
30+
decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
31+
let container = try decoder.singleValueContainer()
32+
let dateStr = try container.decode(String.self)
33+
34+
let formatters = [
35+
"yyyy-MM-dd",
36+
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
37+
"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ",
38+
"yyyy-MM-dd'T'HH:mm:ss'Z'",
39+
"yyyy-MM-dd'T'HH:mm:ss.SSS",
40+
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
41+
"yyyy-MM-dd HH:mm:ss"
42+
].map { (format: String) -> DateFormatter in
43+
let formatter = DateFormatter()
44+
formatter.locale = Locale(identifier: "en_US_POSIX")
45+
formatter.dateFormat = format
46+
return formatter
47+
}
48+
49+
for formatter in formatters {
50+
51+
if let date = formatter.date(from: dateStr) {
52+
return date
53+
}
54+
}
55+
56+
throw DateError.invalidDate
57+
})
3158
}
3259

3360
do {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.4.0-SNAPSHOT
1+
2.4.9-SNAPSHOT
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.4.3-SNAPSHOT
1+
2.4.9-SNAPSHOT

samples/client/petstore/swift4/default/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class AlamofireRequestBuilderFactory: RequestBuilderFactory {
2020
// Store manager to retain its reference
2121
private var managerStore: [String: Alamofire.SessionManager] = [:]
2222

23+
// Sync queue to manage safe access to the store manager
24+
private let syncQueue = DispatchQueue(label: "thread-safe-sync-queue", attributes: .concurrent)
25+
2326
open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
2427
required public init(method: String, URLString: String, parameters: [String : Any]?, isBody: Bool, headers: [String : String] = [:]) {
2528
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody, headers: headers)
@@ -58,7 +61,9 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
5861
let managerId:String = UUID().uuidString
5962
// Create a new manager for each request to customize its request header
6063
let manager = createSessionManager()
61-
managerStore[managerId] = manager
64+
syncQueue.async(flags: .barrier) {
65+
managerStore[managerId] = manager
66+
}
6267

6368
let encoding:ParameterEncoding = isBody ? JSONDataEncoding() : URLEncoding()
6469

@@ -112,7 +117,9 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
112117
}
113118

114119
let cleanupRequest = {
115-
_ = managerStore.removeValue(forKey: managerId)
120+
syncQueue.async(flags: .barrier) {
121+
_ = managerStore.removeValue(forKey: managerId)
122+
}
116123
}
117124

118125
let validatedRequest = request.validate()
@@ -314,7 +321,9 @@ open class AlamofireDecodableRequestBuilder<T:Decodable>: AlamofireRequestBuilde
314321
}
315322

316323
let cleanupRequest = {
317-
_ = managerStore.removeValue(forKey: managerId)
324+
syncQueue.async(flags: .barrier) {
325+
_ = managerStore.removeValue(forKey: managerId)
326+
}
318327
}
319328

320329
let validatedRequest = request.validate()

samples/client/petstore/swift4/default/PetstoreClient/Classes/Swaggers/CodableHelper.swift

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import Foundation
99

1010
public typealias EncodeResult = (data: Data?, error: Error?)
1111

12+
enum DateError: String, Error {
13+
case invalidDate
14+
}
15+
1216
open class CodableHelper {
1317

1418
open static var dateformatter: DateFormatter?
@@ -18,16 +22,39 @@ open class CodableHelper {
1822
var returnedError: Error? = nil
1923

2024
let decoder = JSONDecoder()
25+
2126
if let df = self.dateformatter {
2227
decoder.dateDecodingStrategy = .formatted(df)
2328
} else {
2429
decoder.dataDecodingStrategy = .base64
25-
let formatter = DateFormatter()
26-
formatter.calendar = Calendar(identifier: .iso8601)
27-
formatter.locale = Locale(identifier: "en_US_POSIX")
28-
formatter.timeZone = TimeZone(secondsFromGMT: 0)
29-
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
30-
decoder.dateDecodingStrategy = .formatted(formatter)
30+
decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
31+
let container = try decoder.singleValueContainer()
32+
let dateStr = try container.decode(String.self)
33+
34+
let formatters = [
35+
"yyyy-MM-dd",
36+
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
37+
"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ",
38+
"yyyy-MM-dd'T'HH:mm:ss'Z'",
39+
"yyyy-MM-dd'T'HH:mm:ss.SSS",
40+
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
41+
"yyyy-MM-dd HH:mm:ss"
42+
].map { (format: String) -> DateFormatter in
43+
let formatter = DateFormatter()
44+
formatter.locale = Locale(identifier: "en_US_POSIX")
45+
formatter.dateFormat = format
46+
return formatter
47+
}
48+
49+
for formatter in formatters {
50+
51+
if let date = formatter.date(from: dateStr) {
52+
return date
53+
}
54+
}
55+
56+
throw DateError.invalidDate
57+
})
3158
}
3259

3360
do {

samples/client/petstore/swift4/default/SwaggerClientTests/SwaggerClient.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
54DA06C1D70D78EC0EC72B61 /* Pods_SwaggerClientTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F65B6638217EDDC99D103B16 /* Pods_SwaggerClientTests.framework */; };
11+
68165122233A3AAB001E1C2D /* CodableHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68165121233A3AAB001E1C2D /* CodableHelperTests.swift */; };
1112
6D4EFB951C692C6300B96B06 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4EFB941C692C6300B96B06 /* AppDelegate.swift */; };
1213
6D4EFB971C692C6300B96B06 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4EFB961C692C6300B96B06 /* ViewController.swift */; };
1314
6D4EFB9A1C692C6300B96B06 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D4EFB981C692C6300B96B06 /* Main.storyboard */; };
@@ -31,6 +32,7 @@
3132

3233
/* Begin PBXFileReference section */
3334
289E8A9E9C0BB66AD190C7C6 /* Pods-SwaggerClientTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwaggerClientTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwaggerClientTests/Pods-SwaggerClientTests.debug.xcconfig"; sourceTree = "<group>"; };
35+
68165121233A3AAB001E1C2D /* CodableHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableHelperTests.swift; sourceTree = "<group>"; };
3436
6D4EFB911C692C6300B96B06 /* SwaggerClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwaggerClient.app; sourceTree = BUILT_PRODUCTS_DIR; };
3537
6D4EFB941C692C6300B96B06 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
3638
6D4EFB961C692C6300B96B06 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
@@ -132,6 +134,7 @@
132134
6D4EFBB41C693BE200B96B06 /* PetAPITests.swift */,
133135
6D4EFBB61C693BED00B96B06 /* StoreAPITests.swift */,
134136
6D4EFBB81C693BFC00B96B06 /* UserAPITests.swift */,
137+
68165121233A3AAB001E1C2D /* CodableHelperTests.swift */,
135138
);
136139
path = SwaggerClientTests;
137140
sourceTree = "<group>";
@@ -406,6 +409,7 @@
406409
isa = PBXSourcesBuildPhase;
407410
buildActionMask = 2147483647;
408411
files = (
412+
68165122233A3AAB001E1C2D /* CodableHelperTests.swift in Sources */,
409413
6D4EFBB71C693BED00B96B06 /* StoreAPITests.swift in Sources */,
410414
6D4EFBB91C693BFC00B96B06 /* UserAPITests.swift in Sources */,
411415
6D4EFBB51C693BE200B96B06 /* PetAPITests.swift in Sources */,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// CodableHelperTests.swift
3+
// SwaggerClientTests
4+
//
5+
// Created by Plamen Andreev on 9/24/19.
6+
// Copyright © 2019 Swagger. All rights reserved.
7+
//
8+
9+
import PetstoreClient
10+
import XCTest
11+
12+
class CodableHelperTests: XCTestCase {
13+
func testDecodeMultipeHandlesDateFormats() {
14+
let jsonStrings = [
15+
"{\"date\": \"2019-02-14\"}",
16+
"{\"date\": \"2019-02-14 00:00:00\"}",
17+
"{\"date\": \"2019-02-14T00:00:00\"}",
18+
"{\"date\": \"2019-02-14T00:00:00+0100\"}",
19+
"{\"date\": \"2019-02-14T00:00:00.000+0100\"}",
20+
"{\"date\": \"2019-02-14T00:00:00Z\"}",
21+
"{\"date\": \"2019-02-14T00:00:00.000\"}",
22+
"{\"date\": \"2019-02-14T00:00:00.000Z\"}",
23+
]
24+
25+
for jsonString in jsonStrings {
26+
// Given
27+
let jsonData = jsonString.data(using: .utf8)!
28+
29+
// When
30+
let model = CodableHelper.decode(ModelWithDate.self, from: jsonData)
31+
32+
// Then
33+
XCTAssertNotNil(model.decodableObj)
34+
XCTAssertNil(model.error)
35+
}
36+
}
37+
}
38+
39+
struct ModelWithDate: Codable {
40+
var date: Date
41+
}

0 commit comments

Comments
 (0)