Use CLI option

This commit is contained in:
kubo_takaichi 2015-06-27 21:04:01 +09:00
parent 65af735d6c
commit 91af76cf41
17 changed files with 326 additions and 101 deletions

View File

@ -183,7 +183,7 @@ StaticDocCodegen.java
StaticHtmlGenerator.java StaticHtmlGenerator.java
SwaggerGenerator.java SwaggerGenerator.java
SwaggerYamlGenerator.java SwaggerYamlGenerator.java
SwiftGenerator.java SwiftCodegen.java
TizenClientCodegen.java TizenClientCodegen.java
``` ```

4
bin/swift-petstore.json Normal file
View File

@ -0,0 +1,4 @@
{
"projectName": "PetstoreClient",
"responseAs": "PromiseKit"
}

View File

@ -26,6 +26,6 @@ fi
# if you've executed sbt assembly previously it will use that instead. # if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -o samples/client/petstore/swift" ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -c ./bin/swift-petstore.json -o samples/client/petstore/swift"
java -DsuppressRequired=true -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags java $JAVA_OPTS -jar $executable $ags

View File

@ -11,6 +11,7 @@ import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property; import io.swagger.models.properties.Property;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -19,8 +20,13 @@ import java.io.File;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}");
protected static final String LIBRARY_PROMISE_KIT = "PromiseKit";
protected static final String[] RESPONSE_LIBRARIES = { LIBRARY_PROMISE_KIT };
protected String projectName = "SwaggerClient";
protected boolean unwrapRequired = false;
protected String[] responseAs = new String[0];
protected String sourceFolder = "Classes" + File.separator + "Swaggers"; protected String sourceFolder = "Classes" + File.separator + "Swaggers";
public CodegenType getTag() { public CodegenType getTag() {
@ -35,7 +41,7 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig {
return "Generates a swift client library."; return "Generates a swift client library.";
} }
public SwiftGenerator() { public SwiftCodegen() {
super(); super();
outputFolder = "generated-code" + File.separator + "swift"; outputFolder = "generated-code" + File.separator + "swift";
modelTemplateFiles.put("model.mustache", ".swift"); modelTemplateFiles.put("model.mustache", ".swift");
@ -44,34 +50,6 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig {
apiPackage = File.separator + "APIs"; apiPackage = File.separator + "APIs";
modelPackage = File.separator + "Models"; modelPackage = File.separator + "Models";
// Inject application name
String appName = System.getProperty("appName");
if (appName == null) {
appName = "SwaggerClient";
}
additionalProperties.put("projectName", appName);
// Inject base url override
String basePathOverride = System.getProperty("basePathOverride");
if (basePathOverride != null) {
additionalProperties.put("basePathOverride", basePathOverride);
}
// Make all the variable optional
String suppressRequired = System.getProperty("suppressRequired");
if (suppressRequired != null) {
additionalProperties.put("suppressRequired", suppressRequired);
}
sourceFolder = appName + File.separator + sourceFolder;
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, "AlamofireImplementations.swift"));
supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift"));
supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift"));
supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift"));
languageSpecificPrimitives = new HashSet<String>( languageSpecificPrimitives = new HashSet<String>(
Arrays.asList( Arrays.asList(
"Int", "Int",
@ -125,6 +103,53 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig {
typeMapping.put("file", "NSData"); typeMapping.put("file", "NSData");
importMapping = new HashMap<String, String>(); importMapping = new HashMap<String, String>();
cliOptions.add(new CliOption("projectName", "Project name in Xcode"));
cliOptions.add(new CliOption("responseAs", "Optionally use libraries to manage response. Currently " +
StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available."));
cliOptions.add(new CliOption("unwrapRequired", "Treat 'required' properties in response as non-optional " +
"(which would crash the app if api returns null as opposed to required option specified in json schema"));
}
@Override
public void processOpts() {
super.processOpts();
// Setup project name
if (additionalProperties.containsKey("projectName")) {
projectName = (String) additionalProperties.get("projectName");
} else {
additionalProperties.put("projectName", projectName);
}
sourceFolder = projectName + File.separator + sourceFolder;
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
if (additionalProperties.containsKey("unwrapRequired")) {
unwrapRequired = Boolean.parseBoolean(String.valueOf(additionalProperties.get("unwrapRequired")));
}
additionalProperties.put("unwrapRequired", unwrapRequired);
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
if (additionalProperties.containsKey("responseAs")) {
Object responseAsObject = additionalProperties.get("responseAs");
if (responseAsObject instanceof String) {
responseAs = ((String)responseAsObject).split(",");
} else {
responseAs = (String[]) responseAsObject;
}
}
additionalProperties.put("responseAs", responseAs);
if (ArrayUtils.contains(responseAs, LIBRARY_PROMISE_KIT)) {
additionalProperties.put("usePromiseKit", true);
}
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder,
"AlamofireImplementations.swift"));
supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift"));
supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift"));
supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift"));
} }
@Override @Override

View File

@ -21,7 +21,7 @@ io.swagger.codegen.languages.StaticDocCodegen
io.swagger.codegen.languages.StaticHtmlGenerator io.swagger.codegen.languages.StaticHtmlGenerator
io.swagger.codegen.languages.SwaggerGenerator io.swagger.codegen.languages.SwaggerGenerator
io.swagger.codegen.languages.SwaggerYamlGenerator io.swagger.codegen.languages.SwaggerYamlGenerator
io.swagger.codegen.languages.SwiftGenerator io.swagger.codegen.languages.SwiftCodegen
io.swagger.codegen.languages.TizenClientCodegen io.swagger.codegen.languages.TizenClientCodegen
io.swagger.codegen.languages.TypeScriptAngularClientCodegen io.swagger.codegen.languages.TypeScriptAngularClientCodegen
io.swagger.codegen.languages.TypeScriptNodeClientCodegen io.swagger.codegen.languages.TypeScriptNodeClientCodegen

View File

@ -5,10 +5,9 @@
// //
import Foundation import Foundation
import PromiseKit
class {{projectName}}API { class OneteamAPI {
static let basePath = "{{^basePathOverride}}{{basePath}}{{/basePathOverride}}{{basePathOverride}}" static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/"
static var credential: NSURLCredential? static var credential: NSURLCredential?
static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
} }
@ -44,7 +43,7 @@ class RequestBuilder<T> {
self.isBody = isBody self.isBody = isBody
} }
func execute() -> Promise<Response<T>> { fatalError("Not implemented") } func execute(completion: (response: Response<T>?, erorr: NSError?) -> Void) { }
func addHeader(#name: String, value: String) -> Self { func addHeader(#name: String, value: String) -> Self {
if !value.isEmpty { if !value.isEmpty {
@ -54,7 +53,7 @@ class RequestBuilder<T> {
} }
func addCredential() -> Self { func addCredential() -> Self {
self.credential = {{projectName}}API.credential self.credential = OneteamAPI.credential
return self return self
} }
} }
@ -63,4 +62,3 @@ protocol RequestBuilderFactory {
func getBuilder<T>() -> RequestBuilder<T>.Type func getBuilder<T>() -> RequestBuilder<T>.Type
} }

View File

@ -5,7 +5,6 @@
// //
import Alamofire import Alamofire
import PromiseKit
class AlamofireRequestBuilderFactory: RequestBuilderFactory { class AlamofireRequestBuilderFactory: RequestBuilderFactory {
func getBuilder<T>() -> RequestBuilder<T>.Type { func getBuilder<T>() -> RequestBuilder<T>.Type {
@ -21,7 +20,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody)
} }
override func execute() -> Promise<Response<T>> { override func execute(completion: (response: Response<T>?, erorr: NSError?) -> Void) {
let managerId = NSUUID().UUIDString let managerId = NSUUID().UUIDString
// Create a new manager for each request to customize its request header // Create a new manager for each request to customize its request header
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
@ -35,43 +34,41 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
request.authenticate(usingCredential: credential) request.authenticate(usingCredential: credential)
} }
let defer = Promise<Response<T>>.defer()
request.responseJSON(options: .AllowFragments) { (req, res, json, error) in request.responseJSON(options: .AllowFragments) { (req, res, json, error) in
managerStore.removeValueForKey(managerId) managerStore.removeValueForKey(managerId)
if let error = error { if let error = error {
defer.reject(error) completion(response: nil, erorr: error)
return return
} }
if res!.statusCode >= 400 { if res!.statusCode >= 400 {
//TODO: Add error entity //TODO: Add error entity
let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:]
let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo)
defer.reject(error) completion(response: nil, erorr: error)
return return
} }
if () is T { if () is T {
let response = Response(response: res!, body: () as! T) let response = Response(response: res!, body: () as! T)
defer.fulfill(response) completion(response: response, erorr: nil)
return return
} }
if let json: AnyObject = json { if let json: AnyObject = json {
let body = Decoders.decode(clazz: T.self, source: json) let body = Decoders.decode(clazz: T.self, source: json)
let response = Response(response: res!, body: body) let response = Response(response: res!, body: body)
defer.fulfill(response) completion(response: response, erorr: nil)
return return
} else if "" is T { } else if "" is T {
// swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release // swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release
// https://github.com/swagger-api/swagger-parser/pull/34 // https://github.com/swagger-api/swagger-parser/pull/34
let response = Response(response: res!, body: "" as! T) let response = Response(response: res!, body: "" as! T)
defer.fulfill(response) completion(response: response, erorr: nil)
return return
} }
defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) completion(response: nil, erorr: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
} }
return defer.promise
} }
private func buildHeaders() -> [String: AnyObject] { private func buildHeaders() -> [String: AnyObject] {
@ -83,4 +80,3 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
} }
} }

View File

@ -4,8 +4,8 @@
// https://github.com/swagger-api/swagger-codegen // https://github.com/swagger-api/swagger-codegen
// //
import Alamofire import Alamofire{{#usePromiseKit}}
import PromiseKit import PromiseKit{{/usePromiseKit}}
extension Bool: JSONEncodable { extension Bool: JSONEncodable {
func encodeToJSON() -> AnyObject { return self } func encodeToJSON() -> AnyObject { return self }
@ -63,3 +63,17 @@ extension NSDate: JSONEncodable {
return dateFormatter.stringFromDate(self) return dateFormatter.stringFromDate(self)
} }
} }
{{#usePromiseKit}}extension RequestBuilder {
func execute() -> Promise<Response<T>> {
let deferred = Promise<Response<T>>.defer()
self.execute { (response: Response<T>?, error: NSError?) in
if let response = response {
deferred.fulfill(response)
} else {
deferred.reject(error!)
}
}
return deferred.promise
}
}{{/usePromiseKit}}

View File

@ -121,8 +121,8 @@ class Decoders {
Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in
let sourceDictionary = source as! [NSObject:AnyObject] let sourceDictionary = source as! [NSObject:AnyObject]
var instance = {{classname}}(){{#vars}}{{#isEnum}} var instance = {{classname}}(){{#vars}}{{#isEnum}}
instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}} {{/isEnum}}{{^isEnum}} instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}} {{/isEnum}}{{^isEnum}}
instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}}){{/isEnum}}{{/vars}} instance.{{name}} = Decoders.decode{{^unwrapRequired}}Optional{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}Optional{{/required}}{{/unwrapRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}}){{/isEnum}}{{/vars}}
return instance return instance
}{{/model}} }{{/model}}
{{/models}} {{/models}}

View File

@ -17,17 +17,17 @@ class {{classname}}: JSONEncodable {
} }
{{/isEnum}}{{/vars}} {{/isEnum}}{{/vars}}
{{#vars}}{{#isEnum}}{{#description}}/** {{description}} */ {{#vars}}{{#isEnum}}{{#description}}/** {{description}} */
{{/description}}var {{name}}: {{{datatypeWithEnum}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */
{{/description}}var {{name}}: {{{datatype}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} {{/description}}var {{name}}: {{{datatype}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}
{{/vars}} {{/vars}}
// MARK: JSONEncodable // MARK: JSONEncodable
func encodeToJSON() -> AnyObject { func encodeToJSON() -> AnyObject {
var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}}
nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}}
nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}}
nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}}
nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isContainer}}{{/vars}}
let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:]
return dictionary return dictionary
} }

View File

@ -1,2 +0,0 @@
github "Alamofire/Alamofire" >= 1.2
github "mxcl/PromiseKit"

View File

@ -5,10 +5,9 @@
// //
import Foundation import Foundation
import PromiseKit
class PetstoreClientAPI { class OneteamAPI {
static let basePath = "http://petstore.swagger.io/v2" static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/"
static var credential: NSURLCredential? static var credential: NSURLCredential?
static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
} }
@ -44,7 +43,7 @@ class RequestBuilder<T> {
self.isBody = isBody self.isBody = isBody
} }
func execute() -> Promise<Response<T>> { fatalError("Not implemented") } func execute(completion: (response: Response<T>?, erorr: NSError?) -> Void) { }
func addHeader(#name: String, value: String) -> Self { func addHeader(#name: String, value: String) -> Self {
if !value.isEmpty { if !value.isEmpty {
@ -54,7 +53,7 @@ class RequestBuilder<T> {
} }
func addCredential() -> Self { func addCredential() -> Self {
self.credential = PetstoreClientAPI.credential self.credential = OneteamAPI.credential
return self return self
} }
} }
@ -63,4 +62,3 @@ protocol RequestBuilderFactory {
func getBuilder<T>() -> RequestBuilder<T>.Type func getBuilder<T>() -> RequestBuilder<T>.Type
} }

View File

@ -71,8 +71,44 @@ extension PetstoreClientAPI {
- OAuth: - OAuth:
- type: oauth2 - type: oauth2
- name: petstore_auth - name: petstore_auth
- examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=<Pet>\n <id>123456</id>\n <Category>\n <id>123456</id>\n <name>string</name>\n </Category>\n <name>doggie</name>\n <photoUrls>string</photoUrls>\n <Tag>\n <id>123456</id>\n <name>string</name>\n </Tag>\n <status>string</status>\n</Pet>, contentType=application/xml}] - examples: [{example=[ {
- examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=<Pet>\n <id>123456</id>\n <Category>\n <id>123456</id>\n <name>string</name>\n </Category>\n <name>doggie</name>\n <photoUrls>string</photoUrls>\n <Tag>\n <id>123456</id>\n <name>string</name>\n </Tag>\n <status>string</status>\n</Pet>, contentType=application/xml}] "tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
} ], contentType=application/json}, {example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>string</photoUrls>
<status>string</status>
</Pet>, contentType=application/xml}]
- examples: [{example=[ {
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
} ], contentType=application/json}, {example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>string</photoUrls>
<status>string</status>
</Pet>, contentType=application/xml}]
:param: status (query) Status values that need to be considered for filter :param: status (query) Status values that need to be considered for filter
@ -101,8 +137,44 @@ extension PetstoreClientAPI {
- OAuth: - OAuth:
- type: oauth2 - type: oauth2
- name: petstore_auth - name: petstore_auth
- examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=<Pet>\n <id>123456</id>\n <Category>\n <id>123456</id>\n <name>string</name>\n </Category>\n <name>doggie</name>\n <photoUrls>string</photoUrls>\n <Tag>\n <id>123456</id>\n <name>string</name>\n </Tag>\n <status>string</status>\n</Pet>, contentType=application/xml}] - examples: [{example=[ {
- examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=<Pet>\n <id>123456</id>\n <Category>\n <id>123456</id>\n <name>string</name>\n </Category>\n <name>doggie</name>\n <photoUrls>string</photoUrls>\n <Tag>\n <id>123456</id>\n <name>string</name>\n </Tag>\n <status>string</status>\n</Pet>, contentType=application/xml}] "tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
} ], contentType=application/json}, {example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>string</photoUrls>
<status>string</status>
</Pet>, contentType=application/xml}]
- examples: [{example=[ {
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
} ], contentType=application/json}, {example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>string</photoUrls>
<status>string</status>
</Pet>, contentType=application/xml}]
:param: tags (query) Tags to filter by :param: tags (query) Tags to filter by
@ -134,14 +206,50 @@ extension PetstoreClientAPI {
- OAuth: - OAuth:
- type: oauth2 - type: oauth2
- name: petstore_auth - name: petstore_auth
- examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=<Pet>\n <id>123456</id>\n <Category>\n <id>123456</id>\n <name>string</name>\n </Category>\n <name>doggie</name>\n <photoUrls>string</photoUrls>\n <Tag>\n <id>123456</id>\n <name>string</name>\n </Tag>\n <status>string</status>\n</Pet>, contentType=application/xml}] - examples: [{example={
- examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=<Pet>\n <id>123456</id>\n <Category>\n <id>123456</id>\n <name>string</name>\n </Category>\n <name>doggie</name>\n <photoUrls>string</photoUrls>\n <Tag>\n <id>123456</id>\n <name>string</name>\n </Tag>\n <status>string</status>\n</Pet>, contentType=application/xml}] "tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
}, contentType=application/json}, {example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>string</photoUrls>
<status>string</status>
</Pet>, contentType=application/xml}]
- examples: [{example={
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
}, contentType=application/json}, {example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>string</photoUrls>
<status>string</status>
</Pet>, contentType=application/xml}]
:param: petId (path) ID of pet that needs to be fetched :param: petId (path) ID of pet that needs to be fetched
:returns: Promise<Response<Pet>> :returns: Promise<Response<Pet>>
*/ */
func getPetById(#petId: Int?) -> RequestBuilder<Pet> { func getPetById(#petId: Int) -> RequestBuilder<Pet> {
var path = "/pet/{petId}" var path = "/pet/{petId}"
path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path
@ -170,7 +278,7 @@ extension PetstoreClientAPI {
:returns: Promise<Response<Void>> :returns: Promise<Response<Void>>
*/ */
func updatePetWithForm(#petId: String?, name: String?, status: String?) -> RequestBuilder<Void> { func updatePetWithForm(#petId: String, name: String?, status: String?) -> RequestBuilder<Void> {
var path = "/pet/{petId}" var path = "/pet/{petId}"
path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path
@ -197,7 +305,7 @@ extension PetstoreClientAPI {
:returns: Promise<Response<Void>> :returns: Promise<Response<Void>>
*/ */
func deletePet(#petId: Int?) -> RequestBuilder<Void> { func deletePet(#petId: Int) -> RequestBuilder<Void> {
var path = "/pet/{petId}" var path = "/pet/{petId}"
path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path
@ -226,7 +334,7 @@ extension PetstoreClientAPI {
:returns: Promise<Response<Void>> :returns: Promise<Response<Void>>
*/ */
func uploadFile(#petId: Int?, additionalMetadata: String?, file: NSData?) -> RequestBuilder<Void> { func uploadFile(#petId: Int, additionalMetadata: String?, file: NSData?) -> RequestBuilder<Void> {
var path = "/pet/{petId}/uploadImage" var path = "/pet/{petId}/uploadImage"
path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path

View File

@ -21,8 +21,12 @@ extension PetstoreClientAPI {
- API Key: - API Key:
- type: apiKey api_key - type: apiKey api_key
- name: api_key - name: api_key
- examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] - examples: [{example={
- examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] "key" : 123
}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@3e, contentType=application/xml}]
- examples: [{example={
"key" : 123
}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@3e, contentType=application/xml}]
:returns: Promise<Response<[String:Int]>> :returns: Promise<Response<[String:Int]>>
*/ */
@ -44,8 +48,36 @@ extension PetstoreClientAPI {
- POST /store/order - POST /store/order
- -
- examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=<Order>\n <id>123456</id>\n <petId>123456</petId>\n <quantity>0</quantity>\n <shipDate>2015-05-27T13:22:21.817Z</shipDate>\n <status>string</status>\n <complete>true</complete>\n</Order>, contentType=application/xml}] - examples: [{example={
- examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=<Order>\n <id>123456</id>\n <petId>123456</petId>\n <quantity>0</quantity>\n <shipDate>2015-05-27T13:22:21.817Z</shipDate>\n <status>string</status>\n <complete>true</complete>\n</Order>, contentType=application/xml}] "id" : 123456789,
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2015-06-27T13:41:28.102+0000"
}, contentType=application/json}, {example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2015-06-27T22:41:28.105Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
- examples: [{example={
"id" : 123456789,
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2015-06-27T13:41:28.102+0000"
}, contentType=application/json}, {example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2015-06-27T22:41:28.105Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
:param: body (body) order placed for purchasing the pet :param: body (body) order placed for purchasing the pet
@ -68,14 +100,42 @@ extension PetstoreClientAPI {
- GET /store/order/{orderId} - GET /store/order/{orderId}
- For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
- examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=<Order>\n <id>123456</id>\n <petId>123456</petId>\n <quantity>0</quantity>\n <shipDate>2015-05-27T13:22:21.818Z</shipDate>\n <status>string</status>\n <complete>true</complete>\n</Order>, contentType=application/xml}] - examples: [{example={
- examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=<Order>\n <id>123456</id>\n <petId>123456</petId>\n <quantity>0</quantity>\n <shipDate>2015-05-27T13:22:21.818Z</shipDate>\n <status>string</status>\n <complete>true</complete>\n</Order>, contentType=application/xml}] "id" : 123456789,
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2015-06-27T13:41:28.106+0000"
}, contentType=application/json}, {example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2015-06-27T22:41:28.106Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
- examples: [{example={
"id" : 123456789,
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2015-06-27T13:41:28.106+0000"
}, contentType=application/json}, {example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2015-06-27T22:41:28.106Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
:param: orderId (path) ID of pet that needs to be fetched :param: orderId (path) ID of pet that needs to be fetched
:returns: Promise<Response<Order>> :returns: Promise<Response<Order>>
*/ */
func getOrderById(#orderId: String?) -> RequestBuilder<Order> { func getOrderById(#orderId: String) -> RequestBuilder<Order> {
var path = "/store/order/{orderId}" var path = "/store/order/{orderId}"
path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path
@ -99,7 +159,7 @@ extension PetstoreClientAPI {
:returns: Promise<Response<Void>> :returns: Promise<Response<Void>>
*/ */
func deleteOrder(#orderId: String?) -> RequestBuilder<Void> { func deleteOrder(#orderId: String) -> RequestBuilder<Void> {
var path = "/store/order/{orderId}" var path = "/store/order/{orderId}"
path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path

View File

@ -134,14 +134,22 @@ extension PetstoreClientAPI {
- GET /user/{username} - GET /user/{username}
- -
- examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=<User>\n <id>123456</id>\n <username>string</username>\n <firstName>string</firstName>\n <lastName>string</lastName>\n <email>string</email>\n <password>string</password>\n <phone>string</phone>\n <userStatus>0</userStatus>\n</User>, contentType=application/xml}] - examples: [{example={
- examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=<User>\n <id>123456</id>\n <username>string</username>\n <firstName>string</firstName>\n <lastName>string</lastName>\n <email>string</email>\n <password>string</password>\n <phone>string</phone>\n <userStatus>0</userStatus>\n</User>, contentType=application/xml}] "id" : 1,
"username" : "johnp",
"firstName" : "John",
"lastName" : "Public",
"email" : "johnp@swagger.io",
"password" : "-secret-",
"phone" : "0123456789",
"userStatus" : 0
}, contentType=application/json}]
:param: username (path) The name that needs to be fetched. Use user1 for testing. :param: username (path) The name that needs to be fetched. Use user1 for testing.
:returns: Promise<Response<User>> :returns: Promise<Response<User>>
*/ */
func getUserByName(#username: String?) -> RequestBuilder<User> { func getUserByName(#username: String) -> RequestBuilder<User> {
var path = "/user/{username}" var path = "/user/{username}"
path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path
@ -166,7 +174,7 @@ extension PetstoreClientAPI {
:returns: Promise<Response<Void>> :returns: Promise<Response<Void>>
*/ */
func updateUser(#username: String?, body: User?) -> RequestBuilder<Void> { func updateUser(#username: String, body: User?) -> RequestBuilder<Void> {
var path = "/user/{username}" var path = "/user/{username}"
path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path
@ -189,7 +197,7 @@ extension PetstoreClientAPI {
:returns: Promise<Response<Void>> :returns: Promise<Response<Void>>
*/ */
func deleteUser(#username: String?) -> RequestBuilder<Void> { func deleteUser(#username: String) -> RequestBuilder<Void> {
var path = "/user/{username}" var path = "/user/{username}"
path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil)
let url = PetstoreClientAPI.basePath + path let url = PetstoreClientAPI.basePath + path

View File

@ -5,7 +5,6 @@
// //
import Alamofire import Alamofire
import PromiseKit
class AlamofireRequestBuilderFactory: RequestBuilderFactory { class AlamofireRequestBuilderFactory: RequestBuilderFactory {
func getBuilder<T>() -> RequestBuilder<T>.Type { func getBuilder<T>() -> RequestBuilder<T>.Type {
@ -21,7 +20,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody)
} }
override func execute() -> Promise<Response<T>> { override func execute(completion: (response: Response<T>?, erorr: NSError?) -> Void) {
let managerId = NSUUID().UUIDString let managerId = NSUUID().UUIDString
// Create a new manager for each request to customize its request header // Create a new manager for each request to customize its request header
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
@ -35,37 +34,41 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
request.authenticate(usingCredential: credential) request.authenticate(usingCredential: credential)
} }
let defer = Promise<Response<T>>.defer()
request.responseJSON(options: .AllowFragments) { (req, res, json, error) in request.responseJSON(options: .AllowFragments) { (req, res, json, error) in
managerStore.removeValueForKey(managerId) managerStore.removeValueForKey(managerId)
if let error = error { if let error = error {
defer.reject(error) completion(response: nil, erorr: error)
return return
} }
if res!.statusCode >= 400 { if res!.statusCode >= 400 {
//TODO: Add error entity //TODO: Add error entity
let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:]
let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo)
defer.reject(error) completion(response: nil, erorr: error)
return return
} }
if () is T { if () is T {
let response = Response(response: res!, body: () as! T) let response = Response(response: res!, body: () as! T)
defer.fulfill(response) completion(response: response, erorr: nil)
return return
} }
if let json: AnyObject = json { if let json: AnyObject = json {
let body = Decoders.decode(clazz: T.self, source: json) let body = Decoders.decode(clazz: T.self, source: json)
let response = Response(response: res!, body: body) let response = Response(response: res!, body: body)
defer.fulfill(response) completion(response: response, erorr: nil)
return
} else if "" is T {
// swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release
// https://github.com/swagger-api/swagger-parser/pull/34
let response = Response(response: res!, body: "" as! T)
completion(response: response, erorr: nil)
return return
} }
defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) completion(response: nil, erorr: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
} }
return defer.promise
} }
private func buildHeaders() -> [String: AnyObject] { private func buildHeaders() -> [String: AnyObject] {
@ -77,4 +80,3 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
} }
} }

View File

@ -63,3 +63,17 @@ extension NSDate: JSONEncodable {
return dateFormatter.stringFromDate(self) return dateFormatter.stringFromDate(self)
} }
} }
extension RequestBuilder {
func execute() -> Promise<Response<T>> {
let deferred = Promise<Response<T>>.defer()
self.execute { (response: Response<T>?, error: NSError?) in
if let response = response {
deferred.fulfill(response)
} else {
deferred.reject(error!)
}
}
return deferred.promise
}
}