Created
August 28, 2016 23:16
-
-
Save matsuda/97b2ee5ab764289669637bca7243e015 to your computer and use it in GitHub Desktop.
Alamofire + Himotoki
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
public struct Configuration { | |
public static var baseURL: NSURL { | |
return NSURL(string: "\(scheme)://\(host)\(scriptName)")! | |
} | |
private static var scheme: String { | |
return useSSL ? "https" : "http" | |
} | |
private static var useSSL: Bool { | |
#if DEBUG | |
return false | |
#else | |
return true | |
#endif | |
} | |
private static var scriptName: String { | |
return "/api" | |
} | |
public static var host: String { | |
return "example.com" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Alamofire | |
public enum Error: ErrorType { | |
case Network(error: NSError) | |
case JSONSerialization(error: NSError) | |
case ObjectDecode(error: ErrorType) | |
case ResponseInvalid(status: Status) | |
// case ObjectSerialization(reason: String) | |
} | |
extension Error { | |
public func isCanceled() -> Bool { | |
if case .Network(let nsError) = self where nsError.isCanceled() { | |
return true | |
} | |
return false | |
} | |
} | |
/// | |
/// MARK: - NSError | |
/// | |
extension NSError { | |
public func isCanceled() -> Bool { | |
return domain == NSURLErrorDomain | |
&& code == NSURLErrorCancelled | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Alamofire | |
import Himotoki | |
/// | |
/// MARK: - RequestType | |
/// | |
public protocol RequestType { | |
//public protocol RequestType: URLRequestConvertible { | |
associatedtype Response: Decodable | |
var baseURL: NSURL { get } | |
var path: String { get } | |
var method: Alamofire.Method { get } | |
var headers: [String: String]? { get } | |
} | |
extension RequestType { | |
public var baseURL: NSURL { | |
return Configuration.baseURL | |
} | |
public var headers: [String: String]? { | |
return nil | |
} | |
public var method: Alamofire.Method { | |
return .POST | |
} | |
/* | |
var URLRequest: NSMutableURLRequest { | |
let URL = path.isEmpty ? baseURL : baseURL.URLByAppendingPathComponent(path) | |
let mutableURLRequest = NSMutableURLRequest(URL: URL) | |
mutableURLRequest.HTTPMethod = method.rawValue | |
if let headers = headers { | |
for (headerField, headerValue) in headers { | |
mutableURLRequest.setValue(headerValue, forHTTPHeaderField: headerField) | |
} | |
} | |
return mutableURLRequest | |
} | |
*/ | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Himotoki | |
/// | |
/// MARK: - Status | |
/// | |
public struct Status: Decodable { | |
/// MARK: - StatusCode | |
public enum StatusCode: String, Decodable { | |
case success = "00" | |
case failure = "10" | |
} | |
public let status: String | |
public let messages: [String]? | |
public static func decode(e: Extractor) throws -> Status { | |
return try Status(status: e <| "status", messages: e <||? "messages") | |
} | |
var isSuccess: Bool { | |
return StatusCode(rawValue: status) == .success | |
} | |
} | |
/// | |
/// MARK: - ResponseType | |
/// | |
public protocol ResponseType { | |
var status: Status { get } | |
} | |
public extension ResponseType { | |
} | |
/// | |
/// MARK: - Response | |
/// | |
public struct Response<Result: Decodable>: Decodable, ResponseType { | |
public let status: Status | |
public let results: Result? | |
public static func decode(e: Extractor) throws -> Response<Result> { | |
let status = try Status.decode(e) | |
if !status.isSuccess { | |
return Response(status: status, results: nil) | |
} | |
if let results = e.rawValue["results"] as? [String: AnyObject] where results.isEmpty { | |
return Response(status: status, results: nil) | |
} | |
return try Response(status: status, results: e <|? "results") | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Alamofire | |
import Himotoki | |
public extension Request { | |
public static func DecodableResponseSerializer<T: Decodable>() | |
-> ResponseSerializer<T, Error> | |
{ | |
return ResponseSerializer<T, Error> { request, response, data, error in | |
guard error == nil else { return .Failure(.Network(error: error!)) } | |
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments) | |
let result = JSONResponseSerializer.serializeResponse(request, response, data, error) | |
switch result { | |
case .Success(let value): | |
do { | |
return .Success(try decodeValue(value)) | |
} catch { | |
return .Failure(.ObjectDecode(error: error)) | |
// return .Failure(.ObjectSerialization(reason: "JSON could not be serialized into response object: \(value)")) | |
} | |
case .Failure(let error): | |
return .Failure(.JSONSerialization(error: error)) | |
} | |
} | |
} | |
func responseObject<T: Decodable>( | |
completionHandler: Alamofire.Response<T, Error> -> Void) | |
-> Self | |
{ | |
return response(responseSerializer: Request.DecodableResponseSerializer(), completionHandler: completionHandler) | |
} | |
public static func ObjectResponseSerializer<T: ResponseType where T: Decodable>() | |
-> ResponseSerializer<T, Error> | |
{ | |
return ResponseSerializer<T, Error> { request, response, data, error in | |
let Serializer: ResponseSerializer<T, Error> = Request.DecodableResponseSerializer() | |
let result = Serializer.serializeResponse(request, response, data, error) | |
switch result { | |
case .Success(let value): | |
if value.status.isSuccess { | |
return result | |
} else { | |
return .Failure(.ResponseInvalid(status: value.status)) | |
} | |
case .Failure: | |
return result | |
} | |
} | |
} | |
public func responseObject<T: ResponseType where T: Decodable>( | |
completionHandler: Alamofire.Response<T, Error> -> Void) | |
-> Self | |
{ | |
return response(responseSerializer: Request.ObjectResponseSerializer(), completionHandler: completionHandler) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Alamofire | |
/// | |
/// MARK: - Session | |
/// | |
public class Session { | |
public static let sharedSession = Session() | |
public let manager = Manager() | |
public func sendRequest<T: RequestType where T.Response: ResponseType>( | |
request: T, | |
parameters: [String: AnyObject]?, | |
completionHandler: Alamofire.Response<T.Response, Error> -> Void | |
) -> Request | |
{ | |
let URL = request.baseURL.URLByAppendingPathComponent(request.path) | |
return manager | |
.request( | |
request.method, | |
URL, | |
parameters: ParameterBuilder.toJSON(parameters), | |
headers: request.headers | |
) | |
.validate() | |
.responseObject(completionHandler) | |
} | |
public class func sendRequest<T: RequestType where T.Response: ResponseType>( | |
request: T, | |
parameters: [String: AnyObject]?, | |
completionHandler: Alamofire.Response<T.Response, Error> -> Void | |
) -> Request | |
{ | |
return sharedSession.sendRequest(request, | |
parameters: parameters, | |
completionHandler: completionHandler) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment