Skip to content

Commit 8067612

Browse files
ehychewing328
authored andcommitted
Handle when response is a file URL. (#6469)
This is the equivalent change in the swift4 module which was made in the swift3 module in this PR: #6274 This updates AlamofireImplementations.mustache to handle when the response is an URL. It also makes changes in the generated sample code for: * default configuration (no promisekit or rxswift) * promisekit * rxswift Also, in order to build, the generated code needed to be updated with the change in CodableHelper which changes dataDecodingStrategy to ".base64" from its previous definition in earlier Xcode 9 betas. *
1 parent d639b38 commit 8067612

File tree

7 files changed

+446
-6
lines changed

7 files changed

+446
-6
lines changed

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

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,56 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
142142
nil
143143
)
144144
})
145+
case is URL.Type:
146+
validatedRequest.responseData(completionHandler: { (dataResponse) in
147+
cleanupRequest()
148+
149+
do {
150+
151+
guard !dataResponse.result.isFailure else {
152+
throw DownloadException.responseFailed
153+
}
154+
155+
guard let data = dataResponse.data else {
156+
throw DownloadException.responseDataMissing
157+
}
158+
159+
guard let request = request.request else {
160+
throw DownloadException.requestMissing
161+
}
162+
163+
let fileManager = FileManager.default
164+
let urlRequest = try request.asURLRequest()
165+
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
166+
let requestURL = try self.getURL(from: urlRequest)
167+
168+
var requestPath = try self.getPath(from: requestURL)
169+
170+
if let headerFileName = self.getFileName(fromContentDisposition: dataResponse.response?.allHeaderFields["Content-Disposition"] as? String) {
171+
requestPath = requestPath.appending("/\(headerFileName)")
172+
}
173+
174+
let filePath = documentsDirectory.appendingPathComponent(requestPath)
175+
let directoryPath = filePath.deletingLastPathComponent().path
176+
177+
try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
178+
try data.write(to: filePath, options: .atomic)
179+
180+
completion(
181+
Response(
182+
response: dataResponse.response!,
183+
body: (filePath as! T)
184+
),
185+
nil
186+
)
187+
188+
} catch let requestParserError as DownloadException {
189+
completion(nil, ErrorResponse.Error(400, dataResponse.data, requestParserError))
190+
} catch let error {
191+
completion(nil, ErrorResponse.Error(400, dataResponse.data, error))
192+
}
193+
return
194+
})
145195
case is Void.Type:
146196
validatedRequest.responseData(completionHandler: { (voidResponse) in
147197
cleanupRequest()
@@ -191,6 +241,66 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
191241
}
192242
return httpHeaders
193243
}
244+
245+
fileprivate func getFileName(fromContentDisposition contentDisposition : String?) -> String? {
246+
247+
guard let contentDisposition = contentDisposition else {
248+
return nil
249+
}
250+
251+
let items = contentDisposition.components(separatedBy: ";")
252+
253+
var filename : String? = nil
254+
255+
for contentItem in items {
256+
257+
let filenameKey = "filename="
258+
guard let range = contentItem.range(of: filenameKey) else {
259+
break
260+
}
261+
262+
filename = contentItem
263+
return filename?
264+
.replacingCharacters(in: range, with:"")
265+
.replacingOccurrences(of: "\"", with: "")
266+
.trimmingCharacters(in: .whitespacesAndNewlines)
267+
}
268+
269+
return filename
270+
271+
}
272+
273+
fileprivate func getPath(from url : URL) throws -> String {
274+
275+
guard var path = NSURLComponents(url: url, resolvingAgainstBaseURL: true)?.path else {
276+
throw DownloadException.requestMissingPath
277+
}
278+
279+
if path.hasPrefix("/") {
280+
path.remove(at: path.startIndex)
281+
}
282+
283+
return path
284+
285+
}
286+
287+
fileprivate func getURL(from urlRequest : URLRequest) throws -> URL {
288+
289+
guard let url = urlRequest.url else {
290+
throw DownloadException.requestMissingURL
291+
}
292+
293+
return url
294+
}
295+
296+
}
297+
298+
fileprivate enum DownloadException : Error {
299+
case responseDataMissing
300+
case responseFailed
301+
case requestMissing
302+
case requestMissingPath
303+
case requestMissingURL
194304
}
195305

196306
public enum AlamofireDecodableRequestBuilderError: Error {

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

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,56 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
142142
nil
143143
)
144144
})
145+
case is URL.Type:
146+
validatedRequest.responseData(completionHandler: { (dataResponse) in
147+
cleanupRequest()
148+
149+
do {
150+
151+
guard !dataResponse.result.isFailure else {
152+
throw DownloadException.responseFailed
153+
}
154+
155+
guard let data = dataResponse.data else {
156+
throw DownloadException.responseDataMissing
157+
}
158+
159+
guard let request = request.request else {
160+
throw DownloadException.requestMissing
161+
}
162+
163+
let fileManager = FileManager.default
164+
let urlRequest = try request.asURLRequest()
165+
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
166+
let requestURL = try self.getURL(from: urlRequest)
167+
168+
var requestPath = try self.getPath(from: requestURL)
169+
170+
if let headerFileName = self.getFileName(fromContentDisposition: dataResponse.response?.allHeaderFields["Content-Disposition"] as? String) {
171+
requestPath = requestPath.appending("/\(headerFileName)")
172+
}
173+
174+
let filePath = documentsDirectory.appendingPathComponent(requestPath)
175+
let directoryPath = filePath.deletingLastPathComponent().path
176+
177+
try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
178+
try data.write(to: filePath, options: .atomic)
179+
180+
completion(
181+
Response(
182+
response: dataResponse.response!,
183+
body: (filePath as! T)
184+
),
185+
nil
186+
)
187+
188+
} catch let requestParserError as DownloadException {
189+
completion(nil, ErrorResponse.Error(400, dataResponse.data, requestParserError))
190+
} catch let error {
191+
completion(nil, ErrorResponse.Error(400, dataResponse.data, error))
192+
}
193+
return
194+
})
145195
case is Void.Type:
146196
validatedRequest.responseData(completionHandler: { (voidResponse) in
147197
cleanupRequest()
@@ -191,6 +241,66 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
191241
}
192242
return httpHeaders
193243
}
244+
245+
fileprivate func getFileName(fromContentDisposition contentDisposition : String?) -> String? {
246+
247+
guard let contentDisposition = contentDisposition else {
248+
return nil
249+
}
250+
251+
let items = contentDisposition.components(separatedBy: ";")
252+
253+
var filename : String? = nil
254+
255+
for contentItem in items {
256+
257+
let filenameKey = "filename="
258+
guard let range = contentItem.range(of: filenameKey) else {
259+
break
260+
}
261+
262+
filename = contentItem
263+
return filename?
264+
.replacingCharacters(in: range, with:"")
265+
.replacingOccurrences(of: "\"", with: "")
266+
.trimmingCharacters(in: .whitespacesAndNewlines)
267+
}
268+
269+
return filename
270+
271+
}
272+
273+
fileprivate func getPath(from url : URL) throws -> String {
274+
275+
guard var path = NSURLComponents(url: url, resolvingAgainstBaseURL: true)?.path else {
276+
throw DownloadException.requestMissingPath
277+
}
278+
279+
if path.hasPrefix("/") {
280+
path.remove(at: path.startIndex)
281+
}
282+
283+
return path
284+
285+
}
286+
287+
fileprivate func getURL(from urlRequest : URLRequest) throws -> URL {
288+
289+
guard let url = urlRequest.url else {
290+
throw DownloadException.requestMissingURL
291+
}
292+
293+
return url
294+
}
295+
296+
}
297+
298+
fileprivate enum DownloadException : Error {
299+
case responseDataMissing
300+
case responseFailed
301+
case requestMissing
302+
case requestMissingPath
303+
case requestMissingURL
194304
}
195305

196306
public enum AlamofireDecodableRequestBuilderError: Error {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ open class CodableHelper {
1616
var returnedError: Error? = nil
1717

1818
let decoder = JSONDecoder()
19-
decoder.dataDecodingStrategy = .base64Decode
19+
decoder.dataDecodingStrategy = .base64
2020
if #available(iOS 10.0, *) {
2121
decoder.dateDecodingStrategy = .iso8601
2222
}
@@ -38,7 +38,7 @@ open class CodableHelper {
3838
if prettyPrint {
3939
encoder.outputFormatting = .prettyPrinted
4040
}
41-
encoder.dataEncodingStrategy = .base64Encode
41+
encoder.dataEncodingStrategy = .base64
4242
if #available(iOS 10.0, *) {
4343
encoder.dateEncodingStrategy = .iso8601
4444
}

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

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,56 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
142142
nil
143143
)
144144
})
145+
case is URL.Type:
146+
validatedRequest.responseData(completionHandler: { (dataResponse) in
147+
cleanupRequest()
148+
149+
do {
150+
151+
guard !dataResponse.result.isFailure else {
152+
throw DownloadException.responseFailed
153+
}
154+
155+
guard let data = dataResponse.data else {
156+
throw DownloadException.responseDataMissing
157+
}
158+
159+
guard let request = request.request else {
160+
throw DownloadException.requestMissing
161+
}
162+
163+
let fileManager = FileManager.default
164+
let urlRequest = try request.asURLRequest()
165+
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
166+
let requestURL = try self.getURL(from: urlRequest)
167+
168+
var requestPath = try self.getPath(from: requestURL)
169+
170+
if let headerFileName = self.getFileName(fromContentDisposition: dataResponse.response?.allHeaderFields["Content-Disposition"] as? String) {
171+
requestPath = requestPath.appending("/\(headerFileName)")
172+
}
173+
174+
let filePath = documentsDirectory.appendingPathComponent(requestPath)
175+
let directoryPath = filePath.deletingLastPathComponent().path
176+
177+
try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
178+
try data.write(to: filePath, options: .atomic)
179+
180+
completion(
181+
Response(
182+
response: dataResponse.response!,
183+
body: (filePath as! T)
184+
),
185+
nil
186+
)
187+
188+
} catch let requestParserError as DownloadException {
189+
completion(nil, ErrorResponse.Error(400, dataResponse.data, requestParserError))
190+
} catch let error {
191+
completion(nil, ErrorResponse.Error(400, dataResponse.data, error))
192+
}
193+
return
194+
})
145195
case is Void.Type:
146196
validatedRequest.responseData(completionHandler: { (voidResponse) in
147197
cleanupRequest()
@@ -191,6 +241,66 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
191241
}
192242
return httpHeaders
193243
}
244+
245+
fileprivate func getFileName(fromContentDisposition contentDisposition : String?) -> String? {
246+
247+
guard let contentDisposition = contentDisposition else {
248+
return nil
249+
}
250+
251+
let items = contentDisposition.components(separatedBy: ";")
252+
253+
var filename : String? = nil
254+
255+
for contentItem in items {
256+
257+
let filenameKey = "filename="
258+
guard let range = contentItem.range(of: filenameKey) else {
259+
break
260+
}
261+
262+
filename = contentItem
263+
return filename?
264+
.replacingCharacters(in: range, with:"")
265+
.replacingOccurrences(of: "\"", with: "")
266+
.trimmingCharacters(in: .whitespacesAndNewlines)
267+
}
268+
269+
return filename
270+
271+
}
272+
273+
fileprivate func getPath(from url : URL) throws -> String {
274+
275+
guard var path = NSURLComponents(url: url, resolvingAgainstBaseURL: true)?.path else {
276+
throw DownloadException.requestMissingPath
277+
}
278+
279+
if path.hasPrefix("/") {
280+
path.remove(at: path.startIndex)
281+
}
282+
283+
return path
284+
285+
}
286+
287+
fileprivate func getURL(from urlRequest : URLRequest) throws -> URL {
288+
289+
guard let url = urlRequest.url else {
290+
throw DownloadException.requestMissingURL
291+
}
292+
293+
return url
294+
}
295+
296+
}
297+
298+
fileprivate enum DownloadException : Error {
299+
case responseDataMissing
300+
case responseFailed
301+
case requestMissing
302+
case requestMissingPath
303+
case requestMissingURL
194304
}
195305

196306
public enum AlamofireDecodableRequestBuilderError: Error {

0 commit comments

Comments
 (0)