@@ -16,28 +16,33 @@ public struct HttpUtility
1616
1717 private init ( ) { }
1818
19- public func request< T: Decodable > ( requestUrl : URL , method : HUHttpMethods , requestBody : Data ? = nil , resultType: T . Type , completionHandler: @escaping ( Result < T ? , HUNetworkError > ) -> Void )
19+ public func request< T: Decodable > ( huRequest : HURequest , resultType: T . Type , completionHandler: @escaping ( Result < T ? , HUNetworkError > ) -> Void )
2020 {
21- switch method
21+ switch huRequest . method
2222 {
2323 case . get:
24- getData ( requestUrl: requestUrl , resultType: resultType) { completionHandler ( $0) }
24+ getData ( requestUrl: huRequest . url , resultType: resultType) { completionHandler ( $0) }
2525 break
2626
2727 case . post:
28- postData ( requestUrl : requestUrl , requestBody : requestBody! , resultType: T . self ) { completionHandler ( $0) }
28+ postData ( request : huRequest , resultType: resultType ) { completionHandler ( $0) }
2929 break
3030
3131 case . put:
32- putData ( requestUrl: requestUrl , resultType: resultType) { completionHandler ( $0) }
32+ putData ( requestUrl: huRequest . url , resultType: resultType) { completionHandler ( $0) }
3333 break
3434
3535 case . delete:
36- deleteData ( requestUrl: requestUrl , resultType: resultType) { completionHandler ( $0) }
36+ deleteData ( requestUrl: huRequest . url , resultType: resultType) { completionHandler ( $0) }
3737 break
3838 }
3939 }
4040
41+ // MARK: - Multipart
42+ public func requestWithMultiPartFormData< T: Decodable > ( multiPartRequest: HUMultiPartRequest , responseType: T . Type , completionHandler: @escaping ( Result < T ? , HUNetworkError > ) -> Void ) {
43+ postMultiPartFormData ( request: multiPartRequest) { completionHandler ( $0) }
44+ }
45+
4146 // MARK: - Private functions
4247 private func createJsonDecoder( ) -> JSONDecoder
4348 {
@@ -61,9 +66,9 @@ public struct HttpUtility
6166 private func decodeJsonResponse< T: Decodable > ( data: Data , responseType: T . Type ) -> T ?
6267 {
6368 let decoder = createJsonDecoder ( )
64- do {
69+ do {
6570 return try decoder. decode ( responseType, from: data)
66- } catch let error{
71+ } catch let error {
6772 debugPrint ( " deocding error => \( error. localizedDescription) " )
6873 }
6974 return nil
@@ -81,18 +86,64 @@ public struct HttpUtility
8186 }
8287
8388 // MARK: - POST Api
84- private func postData< T: Decodable > ( requestUrl : URL , requestBody : Data , resultType: T . Type , completionHandler: @escaping ( Result < T ? , HUNetworkError > ) -> Void )
89+ private func postData< T: Decodable > ( request : HURequest , resultType: T . Type , completionHandler: @escaping ( Result < T ? , HUNetworkError > ) -> Void )
8590 {
86- var urlRequest = self . createUrlRequest ( requestUrl: requestUrl )
91+ var urlRequest = self . createUrlRequest ( requestUrl: request . url )
8792 urlRequest. httpMethod = HUHttpMethods . post. rawValue
88- urlRequest. httpBody = requestBody
93+ urlRequest. httpBody = request . requestBody
8994 urlRequest. addValue ( " application/json " , forHTTPHeaderField: " content-type " )
9095
9196 performOperation ( requestUrl: urlRequest, responseType: T . self) { ( result) in
9297 completionHandler ( result)
9398 }
9499 }
95100
101+ private func postMultiPartFormData< T: Decodable > ( request: HUMultiPartRequest , completionHandler: @escaping ( Result < T ? , HUNetworkError > ) -> Void )
102+ {
103+ let boundary = " ----------------------------- \( UUID ( ) . uuidString) "
104+ let lineBreak = " \r \n "
105+ var urlRequest = self . createUrlRequest ( requestUrl: request. url)
106+ urlRequest. httpMethod = HUHttpMethods . post. rawValue
107+ urlRequest. addValue ( " multipart/form-data; boundary= \( boundary) " , forHTTPHeaderField: " Content-Type " )
108+
109+ var postBody = Data ( )
110+
111+ let requestDictionary = request. request. convertToDictionary ( )
112+ if ( requestDictionary != nil )
113+ {
114+ requestDictionary? . forEach ( { ( key, value) in
115+ if ( value != nil ) {
116+ let strValue = value. map { String ( describing: $0) }
117+ if ( strValue != nil && strValue? . count != 0 ) {
118+ postBody. append ( " -- \( boundary + lineBreak) " . data ( using: . utf8) !)
119+ postBody. append ( " Content-Disposition: form-data; name= \" \( key) \" \( lineBreak + lineBreak) " . data ( using: . utf8) !)
120+ postBody. append ( " \( strValue! + lineBreak) " . data ( using: . utf8) !)
121+ }
122+ }
123+ } )
124+
125+ // TODO: Next release
126+ // if(huRequest.media != nil) {
127+ // huRequest.media?.forEach({ (media) in
128+ // postBody.append("--\(boundary + lineBreak)" .data(using: .utf8)!)
129+ // postBody.append("Content-Disposition: form-data; name=\"\(media.parameterName)\"; filename=\"\(media.fileName)\" \(lineBreak + lineBreak)" .data(using: .utf8)!)
130+ // postBody.append("Content-Type: \(media.mimeType + lineBreak + lineBreak)" .data(using: .utf8)!)
131+ // postBody.append(media.data)
132+ // postBody.append(lineBreak .data(using: .utf8)!)
133+ // })
134+ // }
135+
136+ postBody. append ( " -- \( boundary) -- \( lineBreak) " . data ( using: . utf8) !)
137+
138+ urlRequest. addValue ( " \( postBody. count) " , forHTTPHeaderField: " Content-Length " )
139+ urlRequest. httpBody = postBody
140+
141+ performOperation ( requestUrl: urlRequest, responseType: T . self) { ( result) in
142+ completionHandler ( result)
143+ }
144+ }
145+ }
146+
96147 // MARK: - PUT Api
97148 private func putData< T: Decodable > ( requestUrl: URL , resultType: T . Type , completionHandler: @escaping ( Result < T ? , HUNetworkError > ) -> Void )
98149 {
@@ -121,21 +172,16 @@ public struct HttpUtility
121172 URLSession . shared. dataTask ( with: requestUrl) { ( data, httpUrlResponse, error) in
122173
123174 let statusCode = ( httpUrlResponse as? HTTPURLResponse ) ? . statusCode
124- if ( error == nil && data != nil && data? . count != 0 )
125- {
175+ if ( error == nil && data != nil && data? . count != 0 ) {
126176 let response = self . decodeJsonResponse ( data: data!, responseType: responseType)
127-
128- if ( response != nil ) {
177+ if ( response != nil ) {
129178 completionHandler ( . success( response) )
130179 } else {
131-
132- let responseJsonString = String ( data: data!, encoding: . utf8)
133- completionHandler ( . failure( HUNetworkError ( reason: " response decoding error = \( String ( describing: responseJsonString) ) " , httpStatusCode: statusCode) ) )
180+ completionHandler ( . failure( HUNetworkError ( withServerResponse: data, forRequestUrl: requestUrl. url!, withHttpBody: requestUrl. httpBody, errorMessage: error. debugDescription, forStatusCode: statusCode!) ) )
134181 }
135182 }
136- else
137- {
138- let networkError = HUNetworkError ( reason: error. debugDescription, httpStatusCode: statusCode)
183+ else {
184+ let networkError = HUNetworkError ( withServerResponse: data, forRequestUrl: requestUrl. url!, withHttpBody: requestUrl. httpBody, errorMessage: error. debugDescription, forStatusCode: statusCode!)
139185 completionHandler ( . failure( networkError) )
140186 }
141187
0 commit comments