Skip to content

Commit 465d6ec

Browse files
committed
[swift3] Download file fix #6274
1 parent 23145ed commit 465d6ec

File tree

2 files changed

+218
-0
lines changed

2 files changed

+218
-0
lines changed

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

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,56 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
207207
nil
208208
)
209209
})
210+
case is URL.Type:
211+
validatedRequest.responseData(completionHandler: { (dataResponse) in
212+
cleanupRequest()
213+
214+
do {
215+
216+
guard !dataResponse.result.isFailure else {
217+
throw DownloadException.responseFailed
218+
}
219+
220+
guard let data = dataResponse.data else {
221+
throw DownloadException.responseDataMissing
222+
}
223+
224+
guard let request = request.request else {
225+
throw DownloadException.requestMissing
226+
}
227+
228+
let fileManager = FileManager.default
229+
let urlRequest = try request.asURLRequest()
230+
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
231+
let requestURL = try self.getURL(from: urlRequest)
232+
233+
var requestPath = try self.getPath(from: requestURL)
234+
235+
if let headerFileName = self.getFileName(fromContentDisposition: dataResponse.response?.allHeaderFields["Content-Disposition"] as? String) {
236+
requestPath = requestPath.appending("/\(headerFileName)")
237+
}
238+
239+
let filePath = documentsDirectory.appendingPathComponent(requestPath)
240+
let directoryPath = filePath.deletingLastPathComponent().path
241+
242+
try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
243+
try data.write(to: filePath, options: .atomic)
244+
245+
completion(
246+
Response(
247+
response: dataResponse.response!,
248+
body: (filePath as! T)
249+
),
250+
nil
251+
)
252+
253+
} catch let requestParserError as DownloadException {
254+
completion(nil, ErrorResponse.HttpError(statusCode: 400, data: dataResponse.data, error: requestParserError))
255+
} catch let error {
256+
completion(nil, ErrorResponse.HttpError(statusCode: 400, data: dataResponse.data, error: error))
257+
}
258+
return
259+
})
210260
default:
211261
validatedRequest.responseJSON(options: .allowFragments) { response in
212262
cleanupRequest()
@@ -253,4 +303,63 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
253303
}
254304
return httpHeaders
255305
}
306+
307+
fileprivate func getFileName(fromContentDisposition contentDisposition : String?) -> String? {
308+
309+
guard let contentDisposition = contentDisposition else {
310+
return nil
311+
}
312+
313+
let items = contentDisposition.components(separatedBy: ";")
314+
315+
var filename : String? = nil
316+
317+
for contentItem in items {
318+
319+
let filenameKey = "filename="
320+
guard let range = contentItem.range(of: filenameKey) else {
321+
break
322+
}
323+
324+
filename = contentItem
325+
return filename?
326+
.replacingCharacters(in: range, with:"")
327+
.replacingOccurrences(of: "\"", with: "")
328+
.trimmingCharacters(in: .whitespacesAndNewlines)
329+
}
330+
331+
return filename
332+
333+
}
334+
335+
fileprivate func getPath(from url : URL) throws -> String {
336+
337+
guard var path = NSURLComponents(url: url, resolvingAgainstBaseURL: true)?.path else {
338+
throw DownloadException.requestMissingPath
339+
}
340+
341+
if path.hasPrefix("/") {
342+
path.remove(at: path.startIndex)
343+
}
344+
345+
return path
346+
347+
}
348+
349+
fileprivate func getURL(from urlRequest : URLRequest) throws -> URL {
350+
351+
guard let url = urlRequest.url else {
352+
throw DownloadException.requestMissingURL
353+
}
354+
355+
return url
356+
}
256357
}
358+
359+
fileprivate enum DownloadException : Error {
360+
case responseDataMissing
361+
case responseFailed
362+
case requestMissing
363+
case requestMissingPath
364+
case requestMissingURL
365+
}

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

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,56 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
207207
nil
208208
)
209209
})
210+
case is URL.Type:
211+
validatedRequest.responseData(completionHandler: { (dataResponse) in
212+
cleanupRequest()
213+
214+
do {
215+
216+
guard !dataResponse.result.isFailure else {
217+
throw DownloadException.responseFailed
218+
}
219+
220+
guard let data = dataResponse.data else {
221+
throw DownloadException.responseDataMissing
222+
}
223+
224+
guard let request = request.request else {
225+
throw DownloadException.requestMissing
226+
}
227+
228+
let fileManager = FileManager.default
229+
let urlRequest = try request.asURLRequest()
230+
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
231+
let requestURL = try self.getURL(from: urlRequest)
232+
233+
var requestPath = try self.getPath(from: requestURL)
234+
235+
if let headerFileName = self.getFileName(fromContentDisposition: dataResponse.response?.allHeaderFields["Content-Disposition"] as? String) {
236+
requestPath = requestPath.appending("/\(headerFileName)")
237+
}
238+
239+
let filePath = documentsDirectory.appendingPathComponent(requestPath)
240+
let directoryPath = filePath.deletingLastPathComponent().path
241+
242+
try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
243+
try data.write(to: filePath, options: .atomic)
244+
245+
completion(
246+
Response(
247+
response: dataResponse.response!,
248+
body: (filePath as! T)
249+
),
250+
nil
251+
)
252+
253+
} catch let requestParserError as DownloadException {
254+
completion(nil, ErrorResponse.HttpError(statusCode: 400, data: dataResponse.data, error: requestParserError))
255+
} catch let error {
256+
completion(nil, ErrorResponse.HttpError(statusCode: 400, data: dataResponse.data, error: error))
257+
}
258+
return
259+
})
210260
default:
211261
validatedRequest.responseJSON(options: .allowFragments) { response in
212262
cleanupRequest()
@@ -253,4 +303,63 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
253303
}
254304
return httpHeaders
255305
}
306+
307+
fileprivate func getFileName(fromContentDisposition contentDisposition : String?) -> String? {
308+
309+
guard let contentDisposition = contentDisposition else {
310+
return nil
311+
}
312+
313+
let items = contentDisposition.components(separatedBy: ";")
314+
315+
var filename : String? = nil
316+
317+
for contentItem in items {
318+
319+
let filenameKey = "filename="
320+
guard let range = contentItem.range(of: filenameKey) else {
321+
break
322+
}
323+
324+
filename = contentItem
325+
return filename?
326+
.replacingCharacters(in: range, with:"")
327+
.replacingOccurrences(of: "\"", with: "")
328+
.trimmingCharacters(in: .whitespacesAndNewlines)
329+
}
330+
331+
return filename
332+
333+
}
334+
335+
fileprivate func getPath(from url : URL) throws -> String {
336+
337+
guard var path = NSURLComponents(url: url, resolvingAgainstBaseURL: true)?.path else {
338+
throw DownloadException.requestMissingPath
339+
}
340+
341+
if path.hasPrefix("/") {
342+
path.remove(at: path.startIndex)
343+
}
344+
345+
return path
346+
347+
}
348+
349+
fileprivate func getURL(from urlRequest : URLRequest) throws -> URL {
350+
351+
guard let url = urlRequest.url else {
352+
throw DownloadException.requestMissingURL
353+
}
354+
355+
return url
356+
}
256357
}
358+
359+
fileprivate enum DownloadException : Error {
360+
case responseDataMissing
361+
case responseFailed
362+
case requestMissing
363+
case requestMissingPath
364+
case requestMissingURL
365+
}

0 commit comments

Comments
 (0)