Created
September 30, 2016 20:30
-
-
Save potmo/9752245a3ee7ba05204a4f249b7445c3 to your computer and use it in GitHub Desktop.
generated-endpoint.swift
This file contains 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
/* json to parse | |
{ | |
"required_string": "test", | |
"optional_string": "test", | |
"required_int": 123, | |
"optional_int": 123, | |
"required_bool": true, | |
"optional_bool": true, | |
"required_timestamp": "2016-09-30T17:18:19Z000", | |
"optional_timestamp": "2016-09-30T17:18:19Z000", | |
"required_example_enum": "first", | |
"optional_example_enum": "first", | |
"required_example_class": { | |
"required_string": "test" | |
"optional_int": 123 | |
}, | |
"optional_example_class": { | |
"required_string": "test" | |
"optional_int": 123 | |
}, | |
"required_array": ["a", "b", "c"], | |
"optional_array": ["a", "b", "c"] | |
} | |
*/ | |
/* swagger | |
{ | |
"/some/path/with/{id}/etc": { | |
"get": { | |
"description": "Returns example entity", | |
"produces": [ | |
"application/json" | |
], | |
"parameters": [ | |
{ | |
"name": "id", | |
"in": "path", | |
"description": "ID of the entity", | |
"required": true, | |
"type": "string" | |
} | |
], | |
"responses": { | |
"200": { | |
"description": "An example entiry", | |
"schema": { | |
"type": "array", | |
"items": { | |
"$ref": "#/definitions/pet" | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
*/ | |
import SwiftlyJSON //https://github.com/lingoer/SwiftyJSON | |
import Alamofire //https://github.com/Alamofire/Alamofire | |
/// Example API | |
/// Example API Description | |
/// Version 0.0.1 | |
public struct ExampleAPI { | |
private let sessionManager: SessionManager | |
public init(sessionManager: SessionManager) { | |
self.sessionManager = sessionManager | |
} | |
/// GET https://example.domain.com/some/path/with/{id}/etc | |
public func getExampleEntity(withId id: String, callback: (result: Result<ExampleEntity>) -> Void ) -> Void { | |
// Remember to url encode the id | |
let url = "https://www.example.domain.com/some/path/with/\(id)/etc" | |
let exampleEntity = ... | |
callback(.Success(exampleEntity)) | |
// authentication is added to the session manager instead of here | |
let headers: HTTPHeaders = [ | |
"Accept": "application/json" | |
] | |
// could be added for ?a=1&b=2 | |
let parameters: Parameters = [ | |
"foo": "bar" | |
] | |
// This is another option instead of the inlined in `request` | |
//let url = URL(string: "https://www.example.domain.com")!.appendingPathComponent("/some/path/with/\(id)/etc") | |
//var urlRequest = URLRequest(url: url) | |
//urlRequest.httpMethod = "GET" | |
//urlRequest.httpBody = entity.toJSONString() | |
//urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") | |
//let encodedUrlRequest = try! URLEncoding.queryString.encode(urlRequest, with: parameters) | |
//.request(encodedUrlRequest) | |
self.sessionManager | |
.request(url, headers: headers, parameters: parameters, encoding: URLEncoding.default, method: .get) | |
.validate(statusCode: 200..<300) | |
.validate(contentType: ["application/json"]) | |
.responseJSON { response in | |
switch response.result { | |
case .success(let json): | |
if let entity = ExampleEntry(json) { | |
callback(Result<ExampleEntry>.success(entiry)) | |
} else { | |
callback(Result<ExampleEntry>.failure(BackendError.jsonSerialization(error: "some message")) | |
} | |
case .failure(let error): | |
callback(Result<ExampleEntry>.failure(error)) | |
} | |
} | |
} | |
public struct ExampleEntity: Equatable, CustomStringConvertible { | |
/// A required String | |
public let requiredString: String | |
/// An optional String | |
public let optionalString: String? | |
/// A required Int | |
public let requiredInt: Int | |
/// An optional Int | |
public let optionalInt: Int? | |
/// A required Bool | |
public let requiredBool: Bool | |
/// An optional Bool | |
public let optionalBool: Bool? | |
/// A required Timestamp | |
public let requiredTimestamp: Timestamp | |
/// An optional Timestamp | |
public let optionalTimestamp: Timestamp? | |
/// A required ExampleEnum | |
public let requiredExampleEnum: ExampleEnum | |
/// An optional ExampleEnum | |
public let optionalExampleEnum: ExampleEnum? | |
/// A required ExampleClass | |
public let requiredExampleClass: ExampleClass | |
/// An optional ExampleClass | |
public let optionalExampleClass: ExampleClass? | |
// A required Array<String> | |
public let requiredArray: [String] | |
// An optional Array<String> | |
public let optionalArray: [String]? | |
init?(_ json: JSON?) { | |
guard json = json else { return nil } | |
guard requiredString = json["required_string"].string else { return nil} | |
optionalString = json["optional_string"].string | |
guard requiredInt = json["required_int"].int else { return nil} | |
optionalInt = json["optional_int"].int | |
guard requiredBool = json["required_bool"].bool else { return nil} | |
optionalBool = json["optional_bool"].bool | |
guard requiredTimestamp = Timestamp(json["required_timestamp"]) else { return nil} | |
optionalTimestamp = Timestampe(json["optional_timestamp"]) | |
guard requiredExampleEnum = ExampleEnum(json["required_example_enum"]) else { return nil} | |
optionalExampleEnum = ExampleEnum(json["optional_example_enum"]) | |
guard requiredExampleClass = ExampleClass(json["required_example_class"]) else { return nil} | |
optionalExampleClass = json["optional_example_class"] | |
// Not sure how to do this. If an element is invalid then what? remove the invalid element? | |
// fail the entire Array? | |
// Can is the array typed as [T], [T?], [T]? or [T?]? | |
// Can it be different rules for that? | |
// Also not sure if this closure thingy really compiles | |
guard requiredArray = { | |
return json.map{ (key, value) in | |
return value.string | |
}.filter{ $0 != nil } | |
}() else { | |
return nil | |
} | |
} | |
public func toJSON() -> JSON { | |
var json: JSON = [:] | |
json["required_string"] = requiredString | |
if let optionalString = optionalString { json["optional_string"] = optionalString } | |
json["required_int"] = requiredInt | |
if let optionalInt = optionalInt { json["optional_int"] = optionalInt } | |
json["required_bool"] = requiredBool | |
if let optionalBool = optionalBool { json["optional_bool"] = optionalBool } | |
json["required_timestamp"] = requiredTimestamp.toJSON() | |
if let optionalTimestamp = optionalTimestamp { json["optional_timestamp"] = optionalTimestamp.toJSON() } | |
json["required_example_enum"] = requiredExampleEnum.toJSON() | |
if let optionalExampleEnum = optionalExampleEnum { json["optional_example_enum"] = optionalExampleEnum.toJSON() } | |
json["required_example_class"] = requiredExampleClass.toJSON() | |
if let optionalExampleClass = optionalExampleClass { json["optional_example_class"] = optionalExampleClass.toJSON() } | |
json["required_array"] = requiredArray | |
if let optionalArray = optionalArray { json["optional_array"] = optionalArray } | |
// arrays with compex types or enums would have to array.map{ $0.toJSON() } | |
return json | |
} | |
// Equatable implementation | |
static public func ==(lhs: ExampleEntity, rhs: ExampleEntity) -> Bool { | |
return | |
a.requiredString == b.requiredString && | |
a.optionalString == b.optionalString && | |
a.requiredInt == b.requiredInt && | |
a.optionalInt == b.optionalInt && | |
a.requiredBool == b.requiredBool && | |
a.optionalBool == b.optionalBool && | |
a.requiredTimestamp == b.requiredTimestamp && | |
a.optionalTimestamp == b.optionalTimestamp && | |
a.requiredExampleEnum == b.requiredExampleEnum && | |
a.optionalExampleEnum == b.optionalExampleEnum && | |
a.requiredExampleClass == b.requiredExampleClass && | |
a.optionalExampleClass == b.optionalExampleClass && | |
a.requiredArray == b.requiredArray && | |
a.optionalArray == b.optionalArray | |
} | |
// CustomStringConvertible implementation | |
public var description: String { | |
guard string = toJSON().rawString() else { | |
return "<invalid json>" | |
} | |
return string | |
} | |
/// Some description of the class | |
public enum ExampleEnum: String, Equatable, CustomStringConvertible { | |
// Must be Equatable and CustomStringConvertible. Gets that from string | |
case first = "first" | |
case secon = "second" | |
public init?(_ json: JSON?) { | |
guard json = json else { return nil } | |
guard self = init(rawValue: json.string) else { return nil } | |
} | |
} | |
public struct ExampleClass: Equatable, CustomStringConvertible { | |
// TODO: Must be Equatable. | |
// TODO: Must be CustomStringConvertible. | |
// TODO: Must have toJSON() | |
public let requiredString: String | |
public let optionalInt: Int? | |
public init?(json: JSON?) { | |
guard json = json else { return nil } | |
requiredString = json["required_string"].string | |
guard optionalInt = json["optional_int"].int else { return nil } | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@dbrockman just a first stab in the dark