diff --git a/README.md b/README.md index f2c44ebf718..2fb525528a3 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,7 @@ StaticDocCodegen.java StaticHtmlGenerator.java SwaggerGenerator.java SwaggerYamlGenerator.java -SwiftGenerator.java +SwiftCodegen.java TizenClientCodegen.java ``` diff --git a/bin/swift-petstore.json b/bin/swift-petstore.json new file mode 100644 index 00000000000..700fdeff061 --- /dev/null +++ b/bin/swift-petstore.json @@ -0,0 +1,4 @@ +{ + "projectName": "PetstoreClient", + "responseAs": "PromiseKit" +} \ No newline at end of file diff --git a/bin/swift-petstore.sh b/bin/swift-petstore.sh index 4436ed8774d..96433e5b72d 100755 --- a/bin/swift-petstore.sh +++ b/bin/swift-petstore.sh @@ -26,6 +26,6 @@ fi # 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" -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 diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java similarity index 78% rename from modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java rename to modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java index 96f0666df52..5d4f5f341a7 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java @@ -11,6 +11,7 @@ import io.swagger.models.parameters.Parameter; import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.Property; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import javax.annotation.Nullable; @@ -19,8 +20,13 @@ import java.io.File; import java.util.regex.Matcher; 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_]+\\}"); + 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"; public CodegenType getTag() { @@ -35,7 +41,7 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { return "Generates a swift client library."; } - public SwiftGenerator() { + public SwiftCodegen() { super(); outputFolder = "generated-code" + File.separator + "swift"; modelTemplateFiles.put("model.mustache", ".swift"); @@ -44,34 +50,6 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { apiPackage = File.separator + "APIs"; 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( Arrays.asList( "Int", @@ -125,6 +103,53 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { typeMapping.put("file", "NSData"); importMapping = new HashMap(); + + 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 diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 7360129285e..29c7ed0f729 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -21,7 +21,7 @@ io.swagger.codegen.languages.StaticDocCodegen io.swagger.codegen.languages.StaticHtmlGenerator io.swagger.codegen.languages.SwaggerGenerator io.swagger.codegen.languages.SwaggerYamlGenerator -io.swagger.codegen.languages.SwiftGenerator +io.swagger.codegen.languages.SwiftCodegen io.swagger.codegen.languages.TizenClientCodegen io.swagger.codegen.languages.TypeScriptAngularClientCodegen io.swagger.codegen.languages.TypeScriptNodeClientCodegen diff --git a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache index d9fcb84c125..e473915cf24 100644 --- a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache @@ -5,10 +5,9 @@ // import Foundation -import PromiseKit -class {{projectName}}API { - static let basePath = "{{^basePathOverride}}{{basePath}}{{/basePathOverride}}{{basePathOverride}}" +class OneteamAPI { + static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/" static var credential: NSURLCredential? static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() } @@ -44,7 +43,7 @@ class RequestBuilder { self.isBody = isBody } - func execute() -> Promise> { fatalError("Not implemented") } + func execute(completion: (response: Response?, erorr: NSError?) -> Void) { } func addHeader(#name: String, value: String) -> Self { if !value.isEmpty { @@ -54,7 +53,7 @@ class RequestBuilder { } func addCredential() -> Self { - self.credential = {{projectName}}API.credential + self.credential = OneteamAPI.credential return self } } @@ -63,4 +62,3 @@ protocol RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type } - diff --git a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache index edc7a51a169..61e2bf2886d 100644 --- a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache @@ -5,7 +5,6 @@ // import Alamofire -import PromiseKit class AlamofireRequestBuilderFactory: RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type { @@ -21,7 +20,7 @@ class AlamofireRequestBuilder: RequestBuilder { super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) } - override func execute() -> Promise> { + override func execute(completion: (response: Response?, erorr: NSError?) -> Void) { let managerId = NSUUID().UUIDString // Create a new manager for each request to customize its request header let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() @@ -35,43 +34,41 @@ class AlamofireRequestBuilder: RequestBuilder { request.authenticate(usingCredential: credential) } - let defer = Promise>.defer() request.responseJSON(options: .AllowFragments) { (req, res, json, error) in managerStore.removeValueForKey(managerId) if let error = error { - defer.reject(error) + completion(response: nil, erorr: error) return } if res!.statusCode >= 400 { //TODO: Add error entity let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) - defer.reject(error) + completion(response: nil, erorr: error) return } if () is T { let response = Response(response: res!, body: () as! T) - defer.fulfill(response) + completion(response: response, erorr: nil) return } if let json: AnyObject = json { let body = Decoders.decode(clazz: T.self, source: json) 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) - defer.fulfill(response) + completion(response: response, erorr: nil) 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] { @@ -83,4 +80,3 @@ class AlamofireRequestBuilder: RequestBuilder { } } - diff --git a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache index a06ebae7026..801e90514ff 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache @@ -4,8 +4,8 @@ // https://github.com/swagger-api/swagger-codegen // -import Alamofire -import PromiseKit +import Alamofire{{#usePromiseKit}} +import PromiseKit{{/usePromiseKit}} extension Bool: JSONEncodable { func encodeToJSON() -> AnyObject { return self } @@ -63,3 +63,17 @@ extension NSDate: JSONEncodable { return dateFormatter.stringFromDate(self) } } + +{{#usePromiseKit}}extension RequestBuilder { + func execute() -> Promise> { + let deferred = Promise>.defer() + self.execute { (response: Response?, error: NSError?) in + if let response = response { + deferred.fulfill(response) + } else { + deferred.reject(error!) + } + } + return deferred.promise + } +}{{/usePromiseKit}} diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index b2f72e483ad..f832cdab9a4 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -121,8 +121,8 @@ class Decoders { Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in let sourceDictionary = source as! [NSObject:AnyObject] var instance = {{classname}}(){{#vars}}{{#isEnum}} - instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}} {{/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}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}} {{/isEnum}}{{^isEnum}} + 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 }{{/model}} {{/models}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index 2302a6f44a5..bcd4702fb3b 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -17,17 +17,17 @@ class {{classname}}: JSONEncodable { } {{/isEnum}}{{/vars}} {{#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}}: {{{datatype}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} + {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ + {{/description}}var {{name}}: {{{datatype}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} {{/vars}} // MARK: JSONEncodable func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#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}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.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}}.rawValue{{/isEnum}}{{^isPrimitiveType}} + nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } diff --git a/samples/client/petstore/swift/PetstoreClient/Cartfile b/samples/client/petstore/swift/PetstoreClient/Cartfile deleted file mode 100644 index 245a690a74b..00000000000 --- a/samples/client/petstore/swift/PetstoreClient/Cartfile +++ /dev/null @@ -1,2 +0,0 @@ -github "Alamofire/Alamofire" >= 1.2 -github "mxcl/PromiseKit" \ No newline at end of file diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift index 75138ff689a..e473915cf24 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift @@ -5,10 +5,9 @@ // import Foundation -import PromiseKit -class PetstoreClientAPI { - static let basePath = "http://petstore.swagger.io/v2" +class OneteamAPI { + static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/" static var credential: NSURLCredential? static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() } @@ -44,7 +43,7 @@ class RequestBuilder { self.isBody = isBody } - func execute() -> Promise> { fatalError("Not implemented") } + func execute(completion: (response: Response?, erorr: NSError?) -> Void) { } func addHeader(#name: String, value: String) -> Self { if !value.isEmpty { @@ -54,7 +53,7 @@ class RequestBuilder { } func addCredential() -> Self { - self.credential = PetstoreClientAPI.credential + self.credential = OneteamAPI.credential return self } } @@ -63,4 +62,3 @@ protocol RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type } - diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift index b136a04f8d2..5202240bbc9 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -71,8 +71,44 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - 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=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - 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=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, 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= + 123456 + doggie + string + string +, 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= + 123456 + doggie + string + string +, contentType=application/xml}] :param: status (query) Status values that need to be considered for filter @@ -101,8 +137,44 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - 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=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - 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=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, 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= + 123456 + doggie + string + string +, 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= + 123456 + doggie + string + string +, contentType=application/xml}] :param: tags (query) Tags to filter by @@ -134,14 +206,50 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - 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=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - 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=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, 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= + 123456 + doggie + string + string +, 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= + 123456 + doggie + string + string +, contentType=application/xml}] :param: petId (path) ID of pet that needs to be fetched :returns: Promise> */ - func getPetById(#petId: Int?) -> RequestBuilder { + func getPetById(#petId: Int) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -170,7 +278,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updatePetWithForm(#petId: String?, name: String?, status: String?) -> RequestBuilder { + func updatePetWithForm(#petId: String, name: String?, status: String?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -197,7 +305,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deletePet(#petId: Int?) -> RequestBuilder { + func deletePet(#petId: Int) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -226,7 +334,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func uploadFile(#petId: Int?, additionalMetadata: String?, file: NSData?) -> RequestBuilder { + func uploadFile(#petId: Int, additionalMetadata: String?, file: NSData?) -> RequestBuilder { var path = "/pet/{petId}/uploadImage" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift index ed0c5a87889..ad122129939 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -21,8 +21,12 @@ extension PetstoreClientAPI { - API Key: - type: apiKey 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={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] + - examples: [{example={ + "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> */ @@ -44,8 +48,36 @@ extension PetstoreClientAPI { - 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=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] - - 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=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, 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= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.105Z + string + true +, 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= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.105Z + string + true +, contentType=application/xml}] :param: body (body) order placed for purchasing the pet @@ -68,14 +100,42 @@ extension PetstoreClientAPI { - GET /store/order/{orderId} - 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=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] - - 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=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, 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= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.106Z + string + true +, 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= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.106Z + string + true +, contentType=application/xml}] :param: orderId (path) ID of pet that needs to be fetched :returns: Promise> */ - func getOrderById(#orderId: String?) -> RequestBuilder { + func getOrderById(#orderId: String) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -99,7 +159,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteOrder(#orderId: String?) -> RequestBuilder { + func deleteOrder(#orderId: String) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift index 812d823459d..9c283396214 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift @@ -134,14 +134,22 @@ extension PetstoreClientAPI { - 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=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] - - 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=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] + - examples: [{example={ + "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. :returns: Promise> */ - func getUserByName(#username: String?) -> RequestBuilder { + func getUserByName(#username: String) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -166,7 +174,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updateUser(#username: String?, body: User?) -> RequestBuilder { + func updateUser(#username: String, body: User?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -189,7 +197,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteUser(#username: String?) -> RequestBuilder { + func deleteUser(#username: String) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift index 37edceea13c..61e2bf2886d 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift @@ -5,7 +5,6 @@ // import Alamofire -import PromiseKit class AlamofireRequestBuilderFactory: RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type { @@ -21,7 +20,7 @@ class AlamofireRequestBuilder: RequestBuilder { super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) } - override func execute() -> Promise> { + override func execute(completion: (response: Response?, erorr: NSError?) -> Void) { let managerId = NSUUID().UUIDString // Create a new manager for each request to customize its request header let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() @@ -35,37 +34,41 @@ class AlamofireRequestBuilder: RequestBuilder { request.authenticate(usingCredential: credential) } - let defer = Promise>.defer() request.responseJSON(options: .AllowFragments) { (req, res, json, error) in managerStore.removeValueForKey(managerId) if let error = error { - defer.reject(error) + completion(response: nil, erorr: error) return } if res!.statusCode >= 400 { //TODO: Add error entity let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) - defer.reject(error) + completion(response: nil, erorr: error) return } if () is T { let response = Response(response: res!, body: () as! T) - defer.fulfill(response) + completion(response: response, erorr: nil) return } if let json: AnyObject = json { let body = Decoders.decode(clazz: T.self, source: json) 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 } - 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] { @@ -77,4 +80,3 @@ class AlamofireRequestBuilder: RequestBuilder { } } - diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift index a06ebae7026..80af4351f04 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift @@ -63,3 +63,17 @@ extension NSDate: JSONEncodable { return dateFormatter.stringFromDate(self) } } + +extension RequestBuilder { + func execute() -> Promise> { + let deferred = Promise>.defer() + self.execute { (response: Response?, error: NSError?) in + if let response = response { + deferred.fulfill(response) + } else { + deferred.reject(error!) + } + } + return deferred.promise + } +}