Skip to content

Commit

Permalink
[swift3] Download file fix #6274
Browse files Browse the repository at this point in the history
  • Loading branch information
dwoodel committed Aug 14, 2017
1 parent 23145ed commit 465d6ec
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,56 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
nil
)
})
case is URL.Type:
validatedRequest.responseData(completionHandler: { (dataResponse) in
cleanupRequest()
do {
guard !dataResponse.result.isFailure else {
throw DownloadException.responseFailed
}

guard let data = dataResponse.data else {
throw DownloadException.responseDataMissing
}

guard let request = request.request else {
throw DownloadException.requestMissing
}

let fileManager = FileManager.default
let urlRequest = try request.asURLRequest()
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let requestURL = try self.getURL(from: urlRequest)

var requestPath = try self.getPath(from: requestURL)

if let headerFileName = self.getFileName(fromContentDisposition: dataResponse.response?.allHeaderFields["Content-Disposition"] as? String) {
requestPath = requestPath.appending("/\(headerFileName)")
}

let filePath = documentsDirectory.appendingPathComponent(requestPath)
let directoryPath = filePath.deletingLastPathComponent().path

try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
try data.write(to: filePath, options: .atomic)

completion(
Response(
response: dataResponse.response!,
body: (filePath as! T)
),
nil
)

} catch let requestParserError as DownloadException {
completion(nil, ErrorResponse.HttpError(statusCode: 400, data: dataResponse.data, error: requestParserError))
} catch let error {
completion(nil, ErrorResponse.HttpError(statusCode: 400, data: dataResponse.data, error: error))
}
return
})
default:
validatedRequest.responseJSON(options: .allowFragments) { response in
cleanupRequest()
Expand Down Expand Up @@ -253,4 +303,63 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
}
return httpHeaders
}
fileprivate func getFileName(fromContentDisposition contentDisposition : String?) -> String? {
guard let contentDisposition = contentDisposition else {
return nil
}
let items = contentDisposition.components(separatedBy: ";")
var filename : String? = nil
for contentItem in items {
let filenameKey = "filename="
guard let range = contentItem.range(of: filenameKey) else {
break
}
filename = contentItem
return filename?
.replacingCharacters(in: range, with:"")
.replacingOccurrences(of: "\"", with: "")
.trimmingCharacters(in: .whitespacesAndNewlines)
}
return filename
}
fileprivate func getPath(from url : URL) throws -> String {
guard var path = NSURLComponents(url: url, resolvingAgainstBaseURL: true)?.path else {
throw DownloadException.requestMissingPath
}
if path.hasPrefix("/") {
path.remove(at: path.startIndex)
}
return path
}
fileprivate func getURL(from urlRequest : URLRequest) throws -> URL {
guard let url = urlRequest.url else {
throw DownloadException.requestMissingURL
}
return url
}
}
fileprivate enum DownloadException : Error {
case responseDataMissing
case responseFailed
case requestMissing
case requestMissingPath
case requestMissingURL
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,56 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
nil
)
})
case is URL.Type:
validatedRequest.responseData(completionHandler: { (dataResponse) in
cleanupRequest()

do {

guard !dataResponse.result.isFailure else {
throw DownloadException.responseFailed
}

guard let data = dataResponse.data else {
throw DownloadException.responseDataMissing
}

guard let request = request.request else {
throw DownloadException.requestMissing
}

let fileManager = FileManager.default
let urlRequest = try request.asURLRequest()
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let requestURL = try self.getURL(from: urlRequest)

var requestPath = try self.getPath(from: requestURL)

if let headerFileName = self.getFileName(fromContentDisposition: dataResponse.response?.allHeaderFields["Content-Disposition"] as? String) {
requestPath = requestPath.appending("/\(headerFileName)")
}

let filePath = documentsDirectory.appendingPathComponent(requestPath)
let directoryPath = filePath.deletingLastPathComponent().path

try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
try data.write(to: filePath, options: .atomic)

completion(
Response(
response: dataResponse.response!,
body: (filePath as! T)
),
nil
)

} catch let requestParserError as DownloadException {
completion(nil, ErrorResponse.HttpError(statusCode: 400, data: dataResponse.data, error: requestParserError))
} catch let error {
completion(nil, ErrorResponse.HttpError(statusCode: 400, data: dataResponse.data, error: error))
}
return
})
default:
validatedRequest.responseJSON(options: .allowFragments) { response in
cleanupRequest()
Expand Down Expand Up @@ -253,4 +303,63 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
}
return httpHeaders
}

fileprivate func getFileName(fromContentDisposition contentDisposition : String?) -> String? {

guard let contentDisposition = contentDisposition else {
return nil
}

let items = contentDisposition.components(separatedBy: ";")

var filename : String? = nil

for contentItem in items {

let filenameKey = "filename="
guard let range = contentItem.range(of: filenameKey) else {
break
}

filename = contentItem
return filename?
.replacingCharacters(in: range, with:"")
.replacingOccurrences(of: "\"", with: "")
.trimmingCharacters(in: .whitespacesAndNewlines)
}

return filename

}

fileprivate func getPath(from url : URL) throws -> String {

guard var path = NSURLComponents(url: url, resolvingAgainstBaseURL: true)?.path else {
throw DownloadException.requestMissingPath
}

if path.hasPrefix("/") {
path.remove(at: path.startIndex)
}

return path

}

fileprivate func getURL(from urlRequest : URLRequest) throws -> URL {

guard let url = urlRequest.url else {
throw DownloadException.requestMissingURL
}

return url
}
}

fileprivate enum DownloadException : Error {
case responseDataMissing
case responseFailed
case requestMissing
case requestMissingPath
case requestMissingURL
}

0 comments on commit 465d6ec

Please sign in to comment.