Advertisement
Guest User

Untitled

a guest
Jun 20th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 10.81 KB | None | 0 0
  1. //
  2. //  APIResource.swift
  3. //  CEPU
  4. //
  5. //  Created by Elvis Ametov on 24/01/18.
  6. //  Copyright © 2018 CEPU. All rights reserved.
  7. //
  8.  
  9. import Foundation
  10. import Alamofire
  11. import ObjectMapper
  12.  
  13. protocol APIResource {
  14.     var request: APIRequest { get }
  15. }
  16.  
  17. extension APIResource {
  18.     @discardableResult
  19.     func responseData(_ completionHandler: @escaping ResponseHandlerBlock) -> Request? {
  20.         return self.pureRequest(completionHandler: completionHandler)
  21.     }
  22.    
  23.     @discardableResult
  24.     func responseJSON(completionHandler: @escaping (_ json: Any?, _ error: NSError?) -> Void) -> Request? {
  25.         return self.pureRequest(completionHandler: { (data, error) in
  26.             do {
  27.                 guard error == nil else {
  28.                     completionHandler(nil, error)
  29.                     return
  30.                 }
  31.                
  32.                 let JSON = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
  33.                 completionHandler(JSON, nil)
  34.             } catch {
  35.                 completionHandler(nil, error as NSError)
  36.             }
  37.         })
  38.     }
  39.     @discardableResult
  40.     func responseObject<T: Mappable>(_ mappingType: T.Type, keyPath: String? = nil, completionHandler: @escaping (_ object: T?, _ error: NSError?) -> Void) -> Request? {
  41.         return self.responseJSON(completionHandler: { (json, error) in
  42.            
  43.             guard error == nil else {
  44.                 completionHandler(nil, error)
  45.                 return
  46.             }
  47.            
  48.             var json = json as! [String : Any]?// swiftlint:disable:this force_cast
  49.            
  50.             if let keyPath = keyPath {
  51.                 if json != nil {
  52.                     if let js = json {
  53.                         if let js1 = js[keyPath] as? [String: Any] {
  54.                             json = js1
  55.                         } else {
  56.                            
  57.                         }
  58.                     }
  59.                 }
  60.             }
  61.            
  62.             if let parsedObject = Mapper<T>().map(JSON: json!) {
  63.                 completionHandler(parsedObject, nil)
  64.                 return
  65.             }
  66.             print("ObjectMapper failed to serialize response.")
  67.            
  68.             completionHandler(nil, APIError.standard(reason: "ObjectMapper failed to serialize response."))
  69.         })
  70.     }
  71.    
  72.     @discardableResult
  73.     func responseObjectArray<T: Mappable>(_ mappingType: T.Type, keyPath: String? = nil, completionHandler: @escaping (_ objects: [T]?, _ error: NSError?) -> Void) -> Request? {
  74.         return self.responseJSON(completionHandler: { (json, error) -> Void in
  75.            
  76.             guard error == nil else {
  77.                 completionHandler(nil, error)
  78.                 return
  79.             }
  80.            
  81.             var jsonToMap: [[String : Any]]?
  82.            
  83.             if let keyPath = keyPath {
  84. //                jsonToMap = (json as! [String : Any]?)![keyPath] as! [[String : Any]]?
  85.                 if let json = json as? [String: Any] {
  86.                     if let js = json[keyPath] as? [[String: Any]] {
  87.                         jsonToMap = js
  88.                     }
  89.                 }
  90.             } else {
  91.                 jsonToMap = json as! [[String : Any]]?// swiftlint:disable:this force_cast
  92.             }
  93.             if let jsonToMap = jsonToMap {
  94.                 let parsedObject = Mapper<T>(context: nil).mapArray(JSONArray: jsonToMap)
  95.                 if parsedObject.isEmpty {
  96.                     print("Response object array is empty!")
  97.                 }
  98.                 completionHandler(parsedObject, nil)
  99.             } else {
  100.                 completionHandler(nil, APIError.standard(reason: "ObjectMapper failed to serialize response."))
  101.             }
  102.            
  103.         })
  104.     }
  105. }
  106.  
  107. typealias ResponseHandlerBlock = (_ data: Data?, _ error: NSError?) -> Void
  108.  
  109. extension APIResource {
  110.    
  111.     @discardableResult
  112.     fileprivate func pureRequest(completionHandler: @escaping ResponseHandlerBlock) -> Request? {
  113.         var request: DataRequest
  114.         guard NetworkReachabilityManager()!.isReachable else {
  115.             let error = NSError(domain: APIError.domain, code: APIError.connectionErrorCode, userInfo: [NSLocalizedFailureReasonErrorKey: "Connection error"])
  116.             completionHandler(nil, error)
  117.             return nil
  118.         }
  119.         guard !self.request.shouldUpload else {
  120.             if let params = self.request.params {
  121.                 SessionManager.default.upload(multipartFormData: { (formData) in
  122.                     for (index, image) in self.request.images.enumerated() {
  123.                         formData.append(image, withName: "anyNameOfFile", fileName: "image\(index).jpg", mimeType: "image/jpeg")
  124.                     }
  125.                     for (key, value) in params {
  126.                         if let data = "\(value)".data(using: String.Encoding.utf8) {
  127.                             formData.append(data, withName: key)
  128.                         }
  129.                     }
  130.                 }, to: self.request, method: .put, headers: API.additionalHeaders,  encodingCompletion: { (result) in
  131.                     switch result {
  132.                     case .success(let upload, _, _):
  133.                         upload.responseJSON { response in
  134.                             self.serializeResponse(response: response.defaultDataResponse, completionHandler: completionHandler)
  135.                         }
  136.                     case .failure(let encodingError):
  137.                         completionHandler(nil, encodingError as NSError)
  138.                     }
  139.                 })
  140.             }
  141.             return nil
  142.         }
  143.         request = SessionManager.default.request(self.request)
  144.            
  145.         request = request.validate(statusCode: 200...204).validate(contentType: ["application/json"])
  146.         request.response(queue: DispatchQueue.main, completionHandler: { (response) -> Void in
  147.             // logging response
  148.            
  149.             self.serializeResponse(response: response, completionHandler: completionHandler)
  150.         })
  151.        
  152.         return request
  153.     }
  154.    
  155.     private func serializeResponse(response: DefaultDataResponse, completionHandler: @escaping ResponseHandlerBlock) {
  156.         do {
  157.             if let json = try JSONSerialization.jsonObject(with: response.data!, options: .allowFragments) as? [String: AnyObject] {
  158.                 print("Response:\n\(json)\n")
  159.             } else if let json = try JSONSerialization.jsonObject(with: response.data!, options: .allowFragments) as? [AnyObject] {
  160.                 print("Response:\n\(json)\n")
  161.             }
  162.         } catch {
  163.             print(response.error?.localizedDescription ?? "Response error!!!")
  164.         }
  165.        
  166.         let serializedError = Self.errorSerializer(data: response.data, error: response.error as NSError?, response: response.response)
  167.        
  168.         guard serializedError == nil else {
  169.             return completionHandler(nil, serializedError)
  170.         }
  171.        
  172.         completionHandler(response.data, nil)
  173.     }
  174.    
  175.     fileprivate static func errorString(_ json: [String: AnyObject]) -> String? {
  176.         if let error = json["error"] as? [String: Any] {
  177.             if let errorString = error["toUserDisplay"] as? String {
  178.                 return errorString
  179.             } else if let errorString = error["summaryDescription"] as? String {
  180.                 return errorString
  181.             } else {
  182.                 return APIError.unknown.localizedDescription
  183.             }
  184.         }
  185.         if let errorString = json["error"] as? String {
  186.             return errorString
  187.         }
  188.        
  189.         return nil
  190.     }
  191.    
  192.     fileprivate static func errorMessage(_ error: NSError?, response: HTTPURLResponse?, data: Data?) -> NSError? {
  193.         if let response = response {
  194.             if 200...204 ~= response.statusCode || response.statusCode == 404 || response.statusCode == 422 || response.statusCode == 426 {
  195.                 var errorMessage: String?
  196.                 if let data = data, !data.isEmpty {
  197.                     do {
  198.                         guard let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject] else {
  199.                             return nil
  200.                         }
  201.                         errorMessage = self.errorString(json)
  202.                         guard errorMessage != nil else {
  203.                             return nil
  204.                         }
  205.                     } catch {}
  206.                 }
  207.                 return self.extractError(error, response: response, errorMessage: errorMessage)
  208.             }
  209.         }
  210.         return error
  211.     }
  212.    
  213.     fileprivate static func extractError(_ error: NSError?, response: HTTPURLResponse, errorMessage: String?) -> NSError {
  214.         if error != nil {
  215.             if let errorMessage = errorMessage {
  216.                 var userInfo = error!.userInfo
  217.                 userInfo["NSLocalizedFailureReason"] = errorMessage
  218.                 let err = NSError(domain: error!.domain, code: response.statusCode, userInfo: userInfo)
  219.                 return err
  220.             }
  221.             let err = NSError(domain: error!.domain, code: response.statusCode, userInfo: error!.userInfo)
  222.             return err
  223.         } else {
  224.             let userInfo = ["NSLocalizedFailureReason": errorMessage ?? ""]
  225.             let err = NSError(domain: "error.domain", code: response.statusCode, userInfo: userInfo)
  226.             return err
  227.         }
  228.     }
  229.    
  230.     fileprivate static func errorSerializer(data: Data?, error: NSError?, response: HTTPURLResponse?) -> NSError? {
  231.        
  232.         if let error = self.errorMessage(error, response: response, data: data) {
  233.             return error
  234.         }
  235.        
  236.         if let response = response, response.statusCode >= 200 && response.statusCode <= 204 {
  237.             return nil
  238.         }
  239.        
  240.         if let error = error {
  241.             return error
  242.         }
  243.        
  244.         guard let validData = data, !validData.isEmpty else {
  245.             let failureReason = "JSON could not be serialized. Input data was nil or zero length."
  246.             print(failureReason)
  247.             return APIError.standard(reason: failureReason)
  248.         }
  249.        
  250.         do {
  251.             // JSON error parsing
  252.             if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: AnyObject] {
  253.                 if let errorDic = json["error"] as? [String: AnyObject], let errorMessage = errorDic["message"] as? String {
  254.                     print(errorMessage)
  255.                     return APIError.standard(reason: errorMessage)
  256.                 }
  257.             }
  258.         } catch {
  259.             return error as NSError
  260.         }
  261.        
  262.         guard error == nil else {
  263.             return error
  264.         }
  265.        
  266.         return nil
  267.     }
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement