Skip to content

Instantly share code, notes, and snippets.

@macbaszii
Last active August 17, 2016 11:13
Show Gist options
  • Save macbaszii/82769972f2b992237b086bc659314f4d to your computer and use it in GitHub Desktop.
Save macbaszii/82769972f2b992237b086bc659314f4d to your computer and use it in GitHub Desktop.
import Foundation
import Alamofire
import ObjectMapper
let DefaultErrorMessage = "ObjectMapper failed to serialize response."
enum ExampleErrorCode: Int {
case DataSerializationError = -6004
case EndpointError = 404
}
extension Request {
static func ObjectMapperSerializer<T: Mappable, E: APIError>(keyPath: String?, mapToObject object: T? = nil, typeOfError errorType: E.Type) -> ResponseSerializer<T, NSError> {
return ResponseSerializer { request, response, data, error in
guard error == nil else {
return .Failure(error!)
}
guard let _ = data else {
let failureReason = "Data could not be serialized. Input data was nil."
let error = newError(.DataSerializationError, failureReason: failureReason)
return .Failure(error)
}
guard let response = response else {
return .Failure(defaultError())
}
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let result = JSONResponseSerializer.serializeResponse(request, response, data, error)
let JSONToMap: AnyObject?
if let keyPath = keyPath where keyPath.isEmpty == false {
JSONToMap = result.value?.valueForKeyPath(keyPath)
} else {
JSONToMap = result.value
}
switch response.statusCode {
case 204:
if let emptyContentObject = Mapper<T>().map([:]) {
return .Success(emptyContentObject)
}
case 200..<400:
break
default:
if let errorParsed = Mapper<E>().map(JSONToMap) {
let failureReason = errorParsed.message
let error = newError(.EndpointError, failureReason:
failureReason ?? DefaultErrorMessage)
return .Failure(error)
}
}
if let object = object {
Mapper<T>().map(JSONToMap, toObject: object)
return .Success(object)
} else if let parsedObject = Mapper<T>().map(JSONToMap){
return .Success(parsedObject)
}
return .Failure(defaultError())
}
}
func responseObject<T: Mappable, E: APIError>(queue queue: dispatch_queue_t? = nil, keyPath: String? = nil, mapToObject object: T? = nil, typeOfError errorType: E.Type, completionHandler: Response<T, NSError> -> Void) -> Self {
return response(queue: queue, responseSerializer: Request.ObjectMapperSerializer(keyPath, mapToObject: object, typeOfError: errorType), completionHandler: completionHandler)
}
static func ObjectMapperArraySerializer<T: Mappable, E: APIError>(keyPath: String?, mapToObject object: [T]? = nil, typeOfError errorType: E.Type) -> ResponseSerializer<[T], NSError> {
return ResponseSerializer { request, response, data, error in
guard error == nil else {
return .Failure(error!)
}
guard let _ = data else {
let failureReason = "Data could not be serialized. Input data was nil."
let error = newError(.DataSerializationError, failureReason: failureReason)
return .Failure(error)
}
guard let response = response else {
return .Failure(defaultError())
}
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let result = JSONResponseSerializer.serializeResponse(request, response, data, error)
let JSONToMap: AnyObject?
if let keyPath = keyPath where keyPath.isEmpty == false {
JSONToMap = result.value?.valueForKeyPath(keyPath)
} else {
JSONToMap = result.value
}
switch response.statusCode {
case 200..<400:
break
default:
if let errorParsed = Mapper<E>().map(JSONToMap) {
let failureReason = errorParsed.message
let error = newError(.EndpointError, failureReason: failureReason ?? DefaultErrorMessage)
return .Failure(error)
}
}
if let parsedObject = Mapper<T>().mapArray(JSONToMap){
return .Success(parsedObject)
}
return .Failure(defaultError())
}
}
func responseArray<T: Mappable, E: APIError>(queue queue: dispatch_queue_t? = nil, keyPath: String? = nil, mapToObject object: [T]? = nil, typeOfError errorType: E.Type, completionHandler: Response<[T], NSError> -> Void) -> Self {
return response(queue: queue, responseSerializer: Request.ObjectMapperArraySerializer(keyPath, mapToObject: object, typeOfError: errorType), completionHandler: completionHandler)
}
// MARK: - Internal Methods
static func newError(code: ExampleErrorCode, failureReason: String) -> NSError {
let errorDomain = "com.examplekit.error"
let userInfo = [NSLocalizedFailureReasonErrorKey: failureReason]
let returnError = NSError(domain: errorDomain, code: code.rawValue, userInfo: userInfo)
return returnError
}
static func defaultError() -> NSError {
let failureReason = DefaultErrorMessage
let error = newError(.DataSerializationError, failureReason: failureReason)
return error
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment